merge: 合并sa 1.1.2

This commit is contained in:
xlsea 2024-05-30 09:26:51 +08:00
parent eb0ed778b1
commit 3e6d241cd6
22 changed files with 1244 additions and 1215 deletions

View File

@ -65,44 +65,44 @@
"nprogress": "0.2.0",
"pinia": "2.1.7",
"ts-md5": "1.3.1",
"vue": "3.4.26",
"vue": "3.4.27",
"vue-codemirror6": "^1.3.0",
"vue-draggable-plus": "0.4.0",
"vue-draggable-plus": "0.4.1",
"vue-i18n": "9.13.1",
"vue-router": "4.3.2"
},
"devDependencies": {
"@elegant-router/vue": "0.3.6",
"@iconify/json": "2.2.207",
"@elegant-router/vue": "0.3.7",
"@iconify/json": "2.2.211",
"@sa/scripts": "workspace:*",
"@sa/uno-preset": "workspace:*",
"@soybeanjs/eslint-config": "1.3.4",
"@soybeanjs/eslint-config": "1.3.5",
"@types/lodash-es": "4.17.12",
"@types/node": "20.12.10",
"@types/node": "20.12.12",
"@types/nprogress": "0.2.3",
"@unocss/eslint-config": "0.59.4",
"@unocss/preset-icons": "0.59.4",
"@unocss/preset-uno": "0.59.4",
"@unocss/transformer-directives": "0.59.4",
"@unocss/transformer-variant-group": "0.59.4",
"@unocss/vite": "0.59.4",
"@unocss/eslint-config": "0.60.2",
"@unocss/preset-icons": "0.60.2",
"@unocss/preset-uno": "0.60.2",
"@unocss/transformer-directives": "0.60.2",
"@unocss/transformer-variant-group": "0.60.2",
"@unocss/vite": "0.60.2",
"@vitejs/plugin-vue": "5.0.4",
"@vitejs/plugin-vue-jsx": "3.1.0",
"eslint": "9.2.0",
"eslint-plugin-vue": "9.25.0",
"eslint": "9.3.0",
"eslint-plugin-vue": "9.26.0",
"lint-staged": "15.2.2",
"sass": "1.76.0",
"sass": "1.77.2",
"simple-git-hooks": "2.11.1",
"tsx": "4.9.3",
"tsx": "4.10.5",
"typescript": "5.4.5",
"unplugin-icons": "0.19.0",
"unplugin-vue-components": "0.27.0",
"vite": "5.2.11",
"vite-plugin-progress": "0.0.7",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-devtools": "7.1.3",
"vite-plugin-vue-devtools": "7.2.0",
"vue-eslint-parser": "9.4.2",
"vue-tsc": "2.0.16"
"vue-tsc": "2.0.19"
},
"simple-git-hooks": {
"commit-msg": "pnpm sa git-commit-verify",

View File

@ -1,6 +1,6 @@
{
"name": "@sa/axios",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},
@ -12,7 +12,7 @@
"dependencies": {
"@sa/utils": "workspace:*",
"axios": "1.6.8",
"axios-retry": "4.1.0",
"axios-retry": "4.2.0",
"qs": "6.12.1"
},
"devDependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "@sa/color",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/hooks",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/materials",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

View File

@ -36,7 +36,7 @@ defineSlots<Slots>();
<template>
<div
class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-12px whitespace-nowrap border-1px rounded-4px border-solid px-12px py-4px"
class=":soy: relative inline-flex cursor-pointer items-center justify-center gap-12px whitespace-nowrap border-(1px solid) rounded-4px px-12px py-4px"
:class="[
style['button-tab'],
{ [style['button-tab_dark']]: darkMode },

View File

@ -1,6 +1,6 @@
{
"name": "@sa/fetch",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/scripts",
"version": "1.1.0",
"version": "1.1.2",
"bin": {
"sa": "./bin.ts"
},
@ -19,9 +19,9 @@
"cac": "6.7.14",
"consola": "3.2.3",
"enquirer": "2.4.1",
"execa": "8.0.1",
"execa": "9.1.0",
"kolorist": "1.8.0",
"npm-check-updates": "16.14.20",
"rimraf": "5.0.5"
"rimraf": "5.0.7"
}
}

View File

@ -3,5 +3,5 @@ import type { Options } from 'execa';
export async function execCommand(cmd: string, args: string[], options?: Options) {
const { execa } = await import('execa');
const res = await execa(cmd, args, options);
return res?.stdout?.trim() || '';
return (res?.stdout as string)?.trim() || '';
}

View File

@ -1,6 +1,6 @@
{
"name": "@sa/uno-preset",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

View File

@ -1,6 +1,6 @@
{
"name": "@sa/utils",
"version": "1.1.0",
"version": "1.1.2",
"exports": {
".": "./src/index.ts"
},

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@ import { computed } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { useThemeStore } from '@/store/modules/theme';
import { useRouteStore } from '@/store/modules/route';
import { useTabStore } from '@/store/modules/tab';
defineOptions({
name: 'GlobalContent'
@ -20,6 +21,7 @@ withDefaults(defineProps<Props>(), {
const appStore = useAppStore();
const themeStore = useThemeStore();
const routeStore = useRouteStore();
const tabStore = useTabStore();
const transitionName = computed(() => (themeStore.page.animate ? themeStore.page.animateMode : ''));
</script>
@ -36,7 +38,7 @@ const transitionName = computed(() => (themeStore.page.animate ? themeStore.page
<component
:is="Component"
v-if="appStore.reloadFlag"
:key="route.path"
:key="tabStore.getTabIdByRoute(route)"
:class="{ 'p-16px': showPadding }"
class="flex-grow bg-layout transition-300"
/>

View File

@ -52,7 +52,7 @@ const href = (url: string) => {
</script>
<template>
<DarkModeContainer class="h-full flex-y-center shadow-header">
<DarkModeContainer class="h-full flex-y-center px-12px shadow-header">
<GlobalLogo v-if="showLogo" class="h-full" :style="{ width: themeStore.sider.width + 'px' }" />
<HorizontalMenu v-if="showMenu" mode="horizontal" :menus="headerMenus" class="px-12px" />
<div v-else class="h-full flex-y-center flex-1-hidden">

View File

@ -68,7 +68,7 @@ function handleClickMixMenu(menu: App.Global.Menu) {
<component :is="icon" :class="[isMini ? 'text-icon-small' : 'text-icon-large']" />
<p
class="w-full ellipsis-text text-center text-12px transition-height-300"
:class="[isMini ? 'h-0 pt-0' : 'h-24px pt-4px']"
:class="[isMini ? 'h-0 pt-0' : 'h-20px pt-4px']"
>
{{ label }}
</p>

View File

@ -55,8 +55,8 @@ function handleResetActiveMenu() {
:inverted="siderInverted"
:style="{ width: showDrawer ? themeStore.sider.mixChildMenuWidth + 'px' : '0px' }"
>
<header class="flex-y-center justify-between" :style="{ height: themeStore.header.height + 'px' }">
<h2 class="pl-8px text-16px text-primary font-bold">{{ $t('system.title') }}</h2>
<header class="flex-y-center justify-between px-12px" :style="{ height: themeStore.header.height + 'px' }">
<h2 class="text-16px text-primary font-bold">{{ $t('system.title') }}</h2>
<PinToggler
:pin="appStore.mixSiderFixed"
:class="{ 'text-white:88 !hover:text-white': siderInverted }"

View File

@ -73,10 +73,8 @@ function getActivePathIndex() {
}
/** key enter */
function handleEnter(e: Event | undefined) {
function handleEnter() {
if (resultOptions.value?.length === 0 || activePath.value === '') return;
e?.preventDefault();
handleClose();
router.push(activePath.value);
}
@ -114,7 +112,7 @@ registerShortcut();
<div class="mt-20px">
<NEmpty v-if="resultOptions.length === 0" :description="$t('common.noData')" />
<SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter="handleEnter" />
<SearchResult v-else v-model:path="activePath" :options="resultOptions" @enter.prevent="handleEnter" />
</div>
<template #footer>
<SearchFooter v-if="!isMobile" />

View File

@ -141,6 +141,10 @@ function init() {
tabStore.initTabStore(route);
}
function removeFocus() {
(document.activeElement as HTMLElement)?.blur();
}
// watch
watch(
() => route.fullPath,
@ -162,7 +166,11 @@ init();
<template>
<DarkModeContainer class="size-full flex-y-center px-16px shadow-tab">
<div ref="bsWrapper" class="h-full flex-1-hidden">
<BetterScroll ref="bsScroll" :options="{ scrollX: true, scrollY: false, click: appStore.isMobile }">
<BetterScroll
ref="bsScroll"
:options="{ scrollX: true, scrollY: false, click: appStore.isMobile }"
@click="removeFocus"
>
<div
ref="tabRef"
class="h-full flex pr-18px"

View File

@ -42,7 +42,13 @@ function transformElegantRouteToVueRoute(
}
function getLayoutName(component: string) {
return component.replace(LAYOUT_PREFIX, '');
const layout = component.replace(LAYOUT_PREFIX, '');
if(!layouts[layout]) {
throw new Error(`Layout component "${layout}" not found`);
}
return layout;
}
function isView(component: string) {
@ -50,7 +56,13 @@ function transformElegantRouteToVueRoute(
}
function getViewName(component: string) {
return component.replace(VIEW_PREFIX, '');
const view = component.replace(VIEW_PREFIX, '');
if(!views[view]) {
throw new Error(`View component "${view}" not found`);
}
return view;
}
function isFirstLevelRoute(item: ElegantConstRoute) {
@ -81,39 +93,45 @@ function transformElegantRouteToVueRoute(
const vueRoute = { name, path, ...rest } as RouteRecordRaw;
if (component) {
if (isSingleLevelRoute(route)) {
const { layout, view } = getSingleLevelRouteComponent(component);
const singleLevelRoute: RouteRecordRaw = {
path,
component: layouts[layout],
children: [
{
name,
path: '',
component: views[view],
...rest
} as RouteRecordRaw
]
};
return [singleLevelRoute];
try {
if (component) {
if (isSingleLevelRoute(route)) {
const { layout, view } = getSingleLevelRouteComponent(component);
const singleLevelRoute: RouteRecordRaw = {
path,
component: layouts[layout],
children: [
{
name,
path: '',
component: views[view],
...rest
} as RouteRecordRaw
]
};
return [singleLevelRoute];
}
if (isLayout(component)) {
const layoutName = getLayoutName(component);
vueRoute.component = layouts[layoutName];
}
if (isView(component)) {
const viewName = getViewName(component);
vueRoute.component = views[viewName];
}
}
if (isLayout(component)) {
const layoutName = getLayoutName(component);
vueRoute.component = layouts[layoutName];
}
if (isView(component)) {
const viewName = getViewName(component);
vueRoute.component = views[viewName];
}
} catch (error: any) {
console.error(`Error transforming route "${route.name}": ${error.toString()}`);
return [];
}
// add redirect to child
if (children?.length && !vueRoute.redirect) {

View File

@ -179,15 +179,18 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
async function initConstantRoute() {
if (isInitConstantRoute.value) return;
if (authRouteMode.value === 'static') {
const staticRoute = createStaticRoutes();
const staticRoute = createStaticRoutes();
if (authRouteMode.value === 'static') {
addConstantRoutes(staticRoute.constantRoutes);
} else {
const { data, error } = await fetchGetConstantRoutes();
if (!error) {
addConstantRoutes(data);
} else {
// if fetch constant routes failed, use static constant routes
addConstantRoutes(staticRoute.constantRoutes);
}
}
@ -240,6 +243,9 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
handleUpdateRootRouteRedirect(home);
setIsInitAuthRoute(true);
} else {
// if fetch user routes failed, reset store
authStore.resetStore();
}
}

View File

@ -1,8 +1,8 @@
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
import { defineStore } from 'pinia';
import { useEventListener } from '@vueuse/core';
import type { RouteKey } from '@elegant-router/types';
import { router } from '@/router';
import { SetupStoreId } from '@/enum';
import { useRouterPush } from '@/hooks/common/router';
import { localStg } from '@/utils/storage';
@ -17,13 +17,13 @@ import {
getDefaultHomeTab,
getFixedTabIds,
getTabByRoute,
getTabIdByRoute,
isTabInTabs,
updateTabByI18nKey,
updateTabsByI18nKey
} from './shared';
export const useTabStore = defineStore(SetupStoreId.Tab, () => {
const router = useRouter();
const routeStore = useRouteStore();
const themeStore = useThemeStore();
const { routerPush } = useRouterPush(false);
@ -289,6 +289,7 @@ export const useTabStore = defineStore(SetupStoreId.Tab, () => {
setTabLabel,
resetTabLabel,
isTabRetain,
updateTabsByLocale
updateTabsByLocale,
getTabIdByRoute
};
});

View File

@ -359,13 +359,13 @@ watch(
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.keepAlive')" path="keepAlive">
<NRadioGroup v-model:value="model.keepAlive">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.constant')" path="constant">
<NRadioGroup v-model:value="model.constant">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>
@ -374,7 +374,6 @@ watch(
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.hideInMenu')" path="hideInMenu">
<NRadioGroup v-model:value="model.hideInMenu">
<!-- eslint-disable-next-line vue/prefer-true-attribute-shorthand -->
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
@ -394,7 +393,7 @@ watch(
</NFormItemGi>
<NFormItemGi span="24 m:12" :label="$t('page.manage.menu.multiTab')" path="multiTab">
<NRadioGroup v-model:value="model.multiTab">
<NRadio value :label="$t('common.yesOrNo.yes')" />
<NRadio :value="true" :label="$t('common.yesOrNo.yes')" />
<NRadio :value="false" :label="$t('common.yesOrNo.no')" />
</NRadioGroup>
</NFormItemGi>