@pubinfo/core 2.0.0-rc.2 → 2.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AppSetting-D2RJrc9O.js → AppSetting-3wJKvibc.js} +19 -19
- package/dist/{HCheckList.vue_vue_type_script_setup_true_lang-DusVz35O.js → HCheckList.vue_vue_type_script_setup_true_lang-17EywJvs.js} +1 -1
- package/dist/{HToggle-DMcVgMVY.js → HToggle-B-ZjSh6S.js} +1 -1
- package/dist/{PreferencesContent-Dtd9rtew.js → PreferencesContent-xT4paU7N.js} +52 -52
- package/dist/{SettingBreadcrumb-QSCSviKM.js → SettingBreadcrumb-CYnO51Ek.js} +5 -5
- package/dist/{SettingCopyright-Dr5P6yfq.js → SettingCopyright-FOW5ObHK.js} +2 -2
- package/dist/{SettingEnableTransition-DGiHEbCI.js → SettingEnableTransition-Q5cvubmF.js} +12 -12
- package/dist/{SettingHome-CEPcBlds.js → SettingHome-Df7-AlWB.js} +8 -8
- package/dist/{SettingMenu-BJdjnRA6.js → SettingMenu-BNAJ3el9.js} +14 -14
- package/dist/{SettingMode-BnuCHoEY.js → SettingMode-LzlRsBL9.js} +3 -3
- package/dist/{SettingNavSearch-CiU4BmlU.js → SettingNavSearch-BA08vYuw.js} +6 -6
- package/dist/{SettingOther-DTHjVlFe.js → SettingOther-BE8dDCYD.js} +11 -11
- package/dist/{SettingPage-D75_Nf05.js → SettingPage-D061yXCv.js} +2 -2
- package/dist/{SettingTabbar-D48dzvgA.js → SettingTabbar-COwdPPKy.js} +13 -13
- package/dist/{SettingThemes-D-8vTs5n.js → SettingThemes-BHaYERNp.js} +12 -12
- package/dist/{SettingToolbar-DjIjm9V-.js → SettingToolbar-fSuzu6ND.js} +10 -10
- package/dist/{SettingTopbar-Cg30OTH3.js → SettingTopbar-D7GgP0KB.js} +6 -6
- package/dist/{SettingWidthMode-BKV_7kb8.js → SettingWidthMode-CNjzChe1.js} +11 -11
- package/dist/{TopThinMode-JFYsp_lJ.js → TopThinMode-B-28sBJD.js} +3 -3
- package/dist/built-in/layout-component/Layout.vue.d.ts +1 -0
- package/dist/built-in/layout-component/components/Tools/Fullscreen.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/PageReload.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/SearchBar.vue.d.ts +2 -0
- package/dist/built-in/layout-component/components/Tools/index.vue.d.ts +47 -1
- package/dist/built-in/layout-component/components/Tools/interface.d.ts +26 -0
- package/dist/built-in/layout-component/components/ui/HDropdownMenu.vue.d.ts +2 -7
- package/dist/built-in/layout-component/composables/useHotkey.d.ts +1 -5
- package/dist/built-in/layout-component/composables/useMainPage.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useMenu.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useTabbar.d.ts +1 -1
- package/dist/built-in/layout-component/composables/useTitle.d.ts +2 -1
- package/dist/built-in/layout-component/composables/useWatermark.d.ts +3 -1
- package/dist/built-in/layout-component/index.d.ts +9 -6
- package/dist/built-in/layout-component/utils/index.d.ts +0 -1
- package/dist/{colors-CODcBxrF.js → colors-BIQSd520.js} +1 -1
- package/dist/{index-Jd3PYkpj.js → index-Beb7_0-E.js} +11384 -11329
- package/dist/{index-BAoB7aoj.js → index-CPRiufg0.js} +1 -1
- package/dist/{index-DmcblkoZ.js → index-DNdH93AP.js} +13 -13
- package/dist/{index-DQn1WFMa.js → index-DYMBkmAp.js} +2 -2
- package/dist/{index-BVLkBCRY.js → index-Dlf6GQBd.js} +6418 -6439
- package/dist/{index-DvJr0paY.js → index-IscoZG-Y.js} +2 -2
- package/dist/{index-BROqFYXS.js → index-WubcSL0v.js} +1 -1
- package/dist/{index-RT-QBzm0.js → index-YSjb6X1D.js} +10 -12
- package/dist/{index-D4_xmL_A.js → index-wxEEuQXu.js} +17 -17
- package/dist/index.d.ts +4 -2
- package/dist/index.js +53 -55
- package/dist/{pick-BLJM77QN.js → pick-D_XPbQHB.js} +1 -1
- package/dist/style.css +1 -1
- package/package.json +9 -9
- package/src/built-in/layout-component/Layout.vue +11 -22
- package/src/built-in/layout-component/components/Header/TopMode/index.vue +1 -1
- package/src/built-in/layout-component/components/Sidebar/MainSidebar.vue +1 -1
- package/src/built-in/layout-component/components/Sidebar/index.vue +1 -1
- package/src/built-in/layout-component/components/Tools/DarkModeToggle.vue +108 -0
- package/src/built-in/layout-component/components/Tools/Fullscreen.vue +24 -0
- package/src/built-in/layout-component/components/Tools/PageReload.vue +22 -0
- package/src/built-in/layout-component/components/Tools/SearchBar.vue +44 -0
- package/src/built-in/layout-component/components/Tools/{Search.vue → SearchPanel.vue} +1 -1
- package/src/built-in/layout-component/components/Tools/index.vue +63 -131
- package/src/built-in/layout-component/components/Tools/interface.ts +27 -0
- package/src/built-in/layout-component/components/Topbar/Tabbar/MoreAction.vue +2 -2
- package/src/built-in/layout-component/components/Topbar/Tabbar/index.vue +2 -2
- package/src/built-in/layout-component/components/ui/HDropdownMenu.vue +19 -26
- package/src/built-in/layout-component/composables/useGetComputedStyle.ts +2 -3
- package/src/built-in/layout-component/composables/useHotkey.ts +6 -10
- package/src/built-in/layout-component/composables/useMainPage.ts +5 -6
- package/src/built-in/layout-component/composables/useMenu.ts +3 -5
- package/src/built-in/layout-component/composables/useTabbar.ts +3 -5
- package/src/built-in/layout-component/composables/useTitle.ts +2 -3
- package/src/built-in/layout-component/composables/useWatermark.ts +25 -12
- package/src/built-in/layout-component/index.ts +21 -12
- package/src/built-in/layout-component/provider.ts +6 -2
- package/src/built-in/layout-component/utils/index.ts +0 -1
- package/src/built-in/settings/router.ts +5 -1
- package/src/features/stores/utils/routerHelper.ts +3 -0
- package/src/index.ts +7 -9
- package/dist/built-in/layout-component/utils/eventBus.d.ts +0 -5
- package/src/built-in/layout-component/components/Tools/DayNightSwitch.vue +0 -70
- package/src/built-in/layout-component/utils/eventBus.ts +0 -8
- /package/dist/built-in/layout-component/components/Tools/{DayNightSwitch.vue.d.ts → DarkModeToggle.vue.d.ts} +0 -0
- /package/dist/built-in/layout-component/components/Tools/{Search.vue.d.ts → SearchPanel.vue.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubinfo/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-rc.
|
|
4
|
+
"version": "2.0.0-rc.3",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
"vue": "^3.5.17",
|
|
25
25
|
"vue-i18n": "^10.0.7",
|
|
26
26
|
"vue-router": "^4.5.1",
|
|
27
|
-
"@pubinfo/config": "2.0.0-rc.
|
|
28
|
-
"@pubinfo/vite": "2.0.0-rc.
|
|
27
|
+
"@pubinfo/config": "2.0.0-rc.3",
|
|
28
|
+
"@pubinfo/vite": "2.0.0-rc.3"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@alova/adapter-axios": "^2.0.16",
|
|
32
32
|
"@ant-design/icons-vue": "^7.0.1",
|
|
33
33
|
"@headlessui/vue": "^1.7.23",
|
|
34
34
|
"@imengyu/vue3-context-menu": "^1.5.1",
|
|
35
|
-
"@pubinfo/pro-components": "^1.7.
|
|
35
|
+
"@pubinfo/pro-components": "^1.7.3",
|
|
36
36
|
"@unocss/reset": "^66.4.2",
|
|
37
37
|
"@vueuse/core": "^13.7.0",
|
|
38
38
|
"@vueuse/integrations": "^13.5.0",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@iconify/json": "^2.2.354",
|
|
62
62
|
"@iconify/vue": "^5.0.0",
|
|
63
|
-
"@pubinfo/openapi": "^0.
|
|
64
|
-
"@pubinfo/preset-openapi": "^0.
|
|
63
|
+
"@pubinfo/openapi": "^0.9.0",
|
|
64
|
+
"@pubinfo/preset-openapi": "^0.9.0",
|
|
65
65
|
"@types/lodash-es": "^4.17.12",
|
|
66
66
|
"@types/md5": "^2.3.5",
|
|
67
67
|
"@types/nprogress": "^0.2.3",
|
|
@@ -82,11 +82,11 @@
|
|
|
82
82
|
"vue": "^3.5.17",
|
|
83
83
|
"vue-i18n": "^10.0.7",
|
|
84
84
|
"vue-router": "^4.5.1",
|
|
85
|
-
"@pubinfo/config": "2.0.0-rc.
|
|
86
|
-
"@pubinfo/vite": "2.0.0-rc.
|
|
85
|
+
"@pubinfo/config": "2.0.0-rc.3",
|
|
86
|
+
"@pubinfo/vite": "2.0.0-rc.3"
|
|
87
87
|
},
|
|
88
88
|
"scripts": {
|
|
89
|
-
"dev": "vite build -w -m watch
|
|
89
|
+
"dev": "vite build -w -m watch",
|
|
90
90
|
"build": "vite build",
|
|
91
91
|
"openapi": "pnpx @pubinfo/openapi generate"
|
|
92
92
|
}
|
|
@@ -4,30 +4,23 @@ import BackTop from './components/BackTop/index.vue';
|
|
|
4
4
|
import LayoutContent from './components/Content/index.vue';
|
|
5
5
|
import Copyright from './components/Copyright/index.vue';
|
|
6
6
|
import LayoutHeader from './components/Header/index.vue';
|
|
7
|
-
|
|
8
7
|
import SettingBar from './components/SettingBar/index.vue';
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
import Topbar from './components/Topbar/index.vue';
|
|
8
|
+
import LayoutSidebar from './components/Sidebar/index.vue';
|
|
9
|
+
import LayoutTopbar from './components/Topbar/index.vue';
|
|
10
|
+
|
|
13
11
|
import { useContext } from './composables/useContext';
|
|
14
12
|
import { useGetSidebarActualWidth } from './composables/useGetComputedStyle';
|
|
15
13
|
import { useHotkey } from './composables/useHotkey';
|
|
16
|
-
import useWatermark from './composables/useWatermark';
|
|
14
|
+
import { useWatermark } from './composables/useWatermark';
|
|
17
15
|
|
|
18
16
|
defineOptions({
|
|
19
17
|
name: 'Layout',
|
|
20
18
|
});
|
|
21
19
|
|
|
22
20
|
const routeInfo = useRoute();
|
|
23
|
-
const { settingsStore
|
|
21
|
+
const { settingsStore } = useContext();
|
|
24
22
|
const { mainSidebarActualWidth, subSidebarActualWidth } = useGetSidebarActualWidth();
|
|
25
|
-
|
|
26
|
-
useHotkey({
|
|
27
|
-
settingsStore,
|
|
28
|
-
menuStore,
|
|
29
|
-
});
|
|
30
|
-
|
|
23
|
+
useHotkey();
|
|
31
24
|
useWatermark();
|
|
32
25
|
|
|
33
26
|
watch(() => settingsStore.settings.menu.subMenuCollapse, (val) => {
|
|
@@ -68,13 +61,9 @@ watch(() => routeInfo.path, () => {
|
|
|
68
61
|
class="sidebar-container"
|
|
69
62
|
:class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }"
|
|
70
63
|
>
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
</slot> -->
|
|
75
|
-
|
|
76
|
-
<MainSidebar />
|
|
77
|
-
<SubSidebar />
|
|
64
|
+
<slot name="sidebar">
|
|
65
|
+
<LayoutSidebar />
|
|
66
|
+
</slot>
|
|
78
67
|
</div>
|
|
79
68
|
|
|
80
69
|
<div
|
|
@@ -85,7 +74,7 @@ watch(() => routeInfo.path, () => {
|
|
|
85
74
|
|
|
86
75
|
<div class="main-container" :style="{ 'padding-bottom': routeInfo.meta.paddingBottom }">
|
|
87
76
|
<slot name="topbar">
|
|
88
|
-
<
|
|
77
|
+
<LayoutTopbar />
|
|
89
78
|
</slot>
|
|
90
79
|
|
|
91
80
|
<div class="main">
|
|
@@ -213,7 +202,7 @@ watch(() => routeInfo.path, () => {
|
|
|
213
202
|
--at-apply: visible op-100;
|
|
214
203
|
}
|
|
215
204
|
|
|
216
|
-
.wrapper .main-sidebar-container:not(.main-sidebar-leave-active) + .sub-sidebar-container {
|
|
205
|
+
.wrapper ::v-deep(.main-sidebar-container:not(.main-sidebar-leave-active) + .sub-sidebar-container) {
|
|
217
206
|
--at-apply: left-[--g-main-sidebar-width];
|
|
218
207
|
}
|
|
219
208
|
|
|
@@ -4,7 +4,7 @@ import { useElementSize } from '@vueuse/core';
|
|
|
4
4
|
import SolarWidget5BoldDuotone from '~icons/solar/widget-5-bold-duotone';
|
|
5
5
|
import { PubinfoIcon } from '@/features/components';
|
|
6
6
|
import { useContext } from '../../../composables/useContext';
|
|
7
|
-
import useMenu from '../../../composables/useMenu';
|
|
7
|
+
import { useMenu } from '../../../composables/useMenu';
|
|
8
8
|
import More from './More.vue';
|
|
9
9
|
import NotCursor from './NotCursor.vue';
|
|
10
10
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { PubinfoIcon } from '@/features/components';
|
|
3
3
|
import { useContext } from '../../composables/useContext';
|
|
4
|
-
import useMenu from '../../composables/useMenu';
|
|
4
|
+
import { useMenu } from '../../composables/useMenu';
|
|
5
5
|
import Logo from '../Logo/index.vue';
|
|
6
6
|
import Menu from '../Menu/index.vue';
|
|
7
7
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useContext } from '../../composables/useContext';
|
|
3
|
+
import useViewTransition from '../../composables/useViewTransition';
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'DarkModeToggle',
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const { settingsStore } = useContext();
|
|
10
|
+
|
|
11
|
+
function toggleColorScheme(event: MouseEvent) {
|
|
12
|
+
const { startViewTransition } = useViewTransition(async () => {
|
|
13
|
+
const colorScheme = settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark';
|
|
14
|
+
settingsStore.setColorScheme(colorScheme);
|
|
15
|
+
await settingsStore.setPreferencesSetting({
|
|
16
|
+
app: {
|
|
17
|
+
colorScheme,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
nextTick(() => {
|
|
23
|
+
startViewTransition()?.ready.then(() => {
|
|
24
|
+
const x = event.clientX;
|
|
25
|
+
const y = event.clientY;
|
|
26
|
+
const endRadius = Math.hypot(
|
|
27
|
+
Math.max(x, innerWidth - x),
|
|
28
|
+
Math.max(y, innerHeight - y),
|
|
29
|
+
);
|
|
30
|
+
const clipPath = [
|
|
31
|
+
`circle(0px at ${x}px ${y}px)`,
|
|
32
|
+
`circle(${endRadius}px at ${x}px ${y}px)`,
|
|
33
|
+
];
|
|
34
|
+
document.documentElement.animate(
|
|
35
|
+
{
|
|
36
|
+
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
duration: 300,
|
|
40
|
+
easing: 'ease-out',
|
|
41
|
+
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template>
|
|
50
|
+
<div
|
|
51
|
+
v-if="settingsStore.settings.toolbar.enableColorScheme"
|
|
52
|
+
class="inline-flex items-center justify-center cursor-pointer"
|
|
53
|
+
@click="toggleColorScheme"
|
|
54
|
+
>
|
|
55
|
+
<div
|
|
56
|
+
class="animate-icon"
|
|
57
|
+
:class="{
|
|
58
|
+
'animate-icon-day': settingsStore.settings.app.colorScheme !== 'dark',
|
|
59
|
+
}"
|
|
60
|
+
/>
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<style scoped>
|
|
65
|
+
.animate-icon {
|
|
66
|
+
--at-apply: relative size-[20px] rounded-1/2 inline-block align-middle;
|
|
67
|
+
box-shadow: inset 6px -6px 0 0 #fff; /* 比例缩小 */
|
|
68
|
+
transition: box-shadow 0.5s ease 0s, transform 0.4s ease 0.1s;
|
|
69
|
+
transform: scale(1) rotate(-2deg);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.animate-icon::before {
|
|
73
|
+
--at-apply: absolute size-[20px] content-empty rounded-[inherit] left-0 top-0 block;
|
|
74
|
+
transition: background 0.3s ease;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.animate-icon::after {
|
|
78
|
+
--at-apply: absolute top-1/2 left-1/2 size-1 -ml-0.5 -mt-0.5 rounded-[50%] content-empty block;
|
|
79
|
+
box-shadow:
|
|
80
|
+
0 -12px 0 #ffce6e,
|
|
81
|
+
0 12px 0 #ffce6e,
|
|
82
|
+
12px 0 0 #ffce6e,
|
|
83
|
+
-12px 0 0 #ffce6e,
|
|
84
|
+
8px 8px 0 #ffce6e,
|
|
85
|
+
-8px 8px 0 #ffce6e,
|
|
86
|
+
8px -8px 0 #ffce6e,
|
|
87
|
+
-8px -8px 0 #ffce6e;
|
|
88
|
+
transition: all 0.3s ease;
|
|
89
|
+
transform: scale(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.animate-icon-day {
|
|
93
|
+
--at-apply: size-5;
|
|
94
|
+
box-shadow: inset 10px -10px 0 0 #fff; /* 缩小后的太阳核心 */
|
|
95
|
+
transition: transform 0.3s ease 0.1s, box-shadow 0.2s ease 0s;
|
|
96
|
+
transform: scale(0.5) rotate(0deg);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.animate-icon-day::before {
|
|
100
|
+
background: #ffce6e;
|
|
101
|
+
transition: background 0.3s ease 0.1s;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.animate-icon-day::after {
|
|
105
|
+
transition: transform 0.5s ease 0.15s;
|
|
106
|
+
transform: scale(1.2);
|
|
107
|
+
}
|
|
108
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useFullscreen } from '@vueuse/core';
|
|
3
|
+
import FluentFullScreenMaximize16Filled from '~icons/fluent/full-screen-maximize-16-filled';
|
|
4
|
+
import FluentFullScreenMinimize16Filled from '~icons/fluent/full-screen-minimize-16-filled';
|
|
5
|
+
import { useContext } from '../../composables/useContext';
|
|
6
|
+
|
|
7
|
+
defineOptions({
|
|
8
|
+
name: 'Fullscreen',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const { isFullscreen, toggle } = useFullscreen();
|
|
12
|
+
const { settingsStore } = useContext();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<div
|
|
17
|
+
v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.enableFullscreen"
|
|
18
|
+
class="size-5 cursor-pointer"
|
|
19
|
+
@click="toggle"
|
|
20
|
+
>
|
|
21
|
+
<FluentFullScreenMinimize16Filled v-if="isFullscreen" text="16px" />
|
|
22
|
+
<FluentFullScreenMaximize16Filled v-else text="16px" />
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import FluentArrowSync16Filled from '~icons/fluent/arrow-sync-16-filled';
|
|
3
|
+
import { useContext } from '../../composables/useContext';
|
|
4
|
+
import { useMainPage } from '../../composables/useMainPage';
|
|
5
|
+
|
|
6
|
+
defineOptions({
|
|
7
|
+
name: 'PageReload',
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const { settingsStore } = useContext();
|
|
11
|
+
const mainPage = useMainPage();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<div
|
|
16
|
+
v-if="settingsStore.settings.toolbar.enablePageReload"
|
|
17
|
+
class="size-5 cursor-pointer"
|
|
18
|
+
@click="mainPage.reload()"
|
|
19
|
+
>
|
|
20
|
+
<FluentArrowSync16Filled text="16px" />
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useI18n } from 'vue-i18n';
|
|
3
|
+
import IconamoonSearch from '~icons/iconamoon/search';
|
|
4
|
+
import { useContext } from '../../composables/useContext';
|
|
5
|
+
import { useGlobalSearch } from '../../composables/useGlobalSearch';
|
|
6
|
+
|
|
7
|
+
defineOptions({
|
|
8
|
+
name: 'SearchBar',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const { settingsStore } = useContext();
|
|
12
|
+
const { toggle: toggleSearch } = useGlobalSearch();
|
|
13
|
+
const { t } = useI18n();
|
|
14
|
+
|
|
15
|
+
const searchComponentsClass = computed(() => {
|
|
16
|
+
const componentsClass = {
|
|
17
|
+
'side': 'ring-1 ',
|
|
18
|
+
'head': 'bg-[var(--g-header-menu-active-bg)]',
|
|
19
|
+
'single': ' ring-1',
|
|
20
|
+
'only-side': 'ring-1',
|
|
21
|
+
'only-head': ' bg-[var(--g-header-menu-active-bg)]',
|
|
22
|
+
};
|
|
23
|
+
const menuMode = settingsStore.settings.menu.menuMode;
|
|
24
|
+
return componentsClass[menuMode];
|
|
25
|
+
});
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<span
|
|
30
|
+
v-if="settingsStore.settings.navSearch.enable"
|
|
31
|
+
class="group inline-flex cursor-pointer items-center gap-1 rounded-2 px-2 py-1.5 hover:ring-1 ring-inset transition ring-stone-3 dark:ring-stone-7"
|
|
32
|
+
:class="searchComponentsClass"
|
|
33
|
+
@click="toggleSearch('menu')"
|
|
34
|
+
>
|
|
35
|
+
<IconamoonSearch text="14px" />
|
|
36
|
+
<span class="text-sm transition ">{{ t('app.search.text') }}</span>
|
|
37
|
+
<HKbd
|
|
38
|
+
v-if="settingsStore.settings.navSearch.enableHotkeys"
|
|
39
|
+
class="ml-2"
|
|
40
|
+
>
|
|
41
|
+
{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S
|
|
42
|
+
</HKbd>
|
|
43
|
+
</span>
|
|
44
|
+
</template>
|
|
@@ -1,130 +1,108 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { DropdownMenuRender } from './interface';
|
|
3
3
|
import { useI18n } from 'vue-i18n';
|
|
4
4
|
import CarbonUserAvatarFilledAlt from '~icons/carbon/user-avatar-filled-alt';
|
|
5
|
-
import FluentArrowSync16Filled from '~icons/fluent/arrow-sync-16-filled';
|
|
6
|
-
import FluentFullScreenMaximize16Filled from '~icons/fluent/full-screen-maximize-16-filled';
|
|
7
|
-
import FluentFullScreenMinimize16Filled from '~icons/fluent/full-screen-minimize-16-filled';
|
|
8
|
-
import IconamoonSearch from '~icons/iconamoon/search';
|
|
9
5
|
import MaterialSymbolsExpandMoreRounded from '~icons/material-symbols/expand-more-rounded';
|
|
10
|
-
import PhLineVerticalThin from '~icons/ph/line-vertical-thin';
|
|
11
6
|
|
|
7
|
+
import PhLineVerticalThin from '~icons/ph/line-vertical-thin';
|
|
12
8
|
import { useContext } from '../../composables/useContext';
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import useViewTransition from '../../composables/useViewTransition';
|
|
16
|
-
import DayNightSwitch from './DayNightSwitch.vue';
|
|
9
|
+
import DarkModeToggle from './DarkModeToggle.vue';
|
|
10
|
+
import Fullscreen from './Fullscreen.vue';
|
|
17
11
|
import HotkeysIntro from './HotkeysIntro.vue';
|
|
12
|
+
import PageReload from './PageReload.vue';
|
|
18
13
|
import Preferences from './Preferences/index.vue';
|
|
19
|
-
import
|
|
14
|
+
import SearchBar from './SearchBar.vue';
|
|
15
|
+
import SearchPanel from './SearchPanel.vue';
|
|
20
16
|
|
|
21
17
|
defineOptions({
|
|
22
18
|
name: 'Tools',
|
|
23
19
|
});
|
|
24
20
|
|
|
21
|
+
const props = withDefaults(
|
|
22
|
+
defineProps<{
|
|
23
|
+
// 用户菜单渲染函数
|
|
24
|
+
dropdownMenuRender?: DropdownMenuRender
|
|
25
|
+
}>(),
|
|
26
|
+
{
|
|
27
|
+
dropdownMenuRender: (({ Home, Preferences, Hotkeys, Org, Profile, Password, Logout, Divider }) => {
|
|
28
|
+
return [Home, Preferences, Divider, Hotkeys, Divider, Org, Profile, Password, Logout];
|
|
29
|
+
}) as DropdownMenuRender,
|
|
30
|
+
},
|
|
31
|
+
);
|
|
32
|
+
|
|
25
33
|
const router = useRouter();
|
|
26
34
|
const { settingsStore, userStore, generateI18nTitle } = useContext();
|
|
27
35
|
|
|
28
36
|
const { t } = useI18n();
|
|
29
37
|
|
|
30
|
-
const mainPage = useMainPage();
|
|
31
|
-
const { isFullscreen, toggle } = useFullscreen();
|
|
32
|
-
|
|
33
|
-
const { toggle: toggleSearch } = useGlobalSearch();
|
|
34
|
-
|
|
35
38
|
const hotkeysIntroRef = ref();
|
|
36
39
|
const preferencesRef = ref();
|
|
37
40
|
|
|
38
|
-
const userMenu = computed(() =>
|
|
39
|
-
|
|
40
|
-
{
|
|
41
|
+
const userMenu = computed(() => {
|
|
42
|
+
return {
|
|
43
|
+
Home: {
|
|
44
|
+
key: 'home',
|
|
41
45
|
label: generateI18nTitle('route.home', settingsStore.settings.home.title),
|
|
42
46
|
icon: 'i-ant-design:home-twotone',
|
|
43
|
-
|
|
47
|
+
onClick: () => router.push({ name: 'Home' }),
|
|
44
48
|
hide: !settingsStore.settings.home.enable,
|
|
45
49
|
},
|
|
46
|
-
{
|
|
50
|
+
Preferences: {
|
|
51
|
+
key: 'preferences',
|
|
47
52
|
label: t('app.preferences'),
|
|
48
53
|
icon: 'i-iconamoon-star-duotone',
|
|
49
|
-
|
|
54
|
+
onClick: () => preferencesRef.value?.open?.(),
|
|
50
55
|
hide: !settingsStore.settings.app.enableUserPreferences,
|
|
51
56
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{
|
|
57
|
+
Hotkeys: {
|
|
58
|
+
key: 'hotkeys',
|
|
55
59
|
label: t('app.hotkeys'),
|
|
56
60
|
icon: 'i-iconamoon-lightning-2-duotone',
|
|
57
|
-
|
|
61
|
+
onClick: () => hotkeysIntroRef.value?.open?.(),
|
|
58
62
|
hide: settingsStore.mode !== 'pc',
|
|
59
63
|
},
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
{
|
|
64
|
+
Org: {
|
|
65
|
+
key: 'org',
|
|
63
66
|
label: t('app.changeOrg'),
|
|
64
67
|
icon: 'i-iconamoon-synchronize-duotone',
|
|
65
|
-
|
|
68
|
+
onClick: () => router.push({
|
|
66
69
|
name: 'ChangeOrganization',
|
|
67
70
|
params: { orgId: userStore.user.orgId },
|
|
68
71
|
}),
|
|
69
72
|
hide: userStore.user.orgList.length <= 1,
|
|
70
73
|
},
|
|
71
|
-
{
|
|
74
|
+
Profile: {
|
|
75
|
+
key: 'profile',
|
|
72
76
|
label: t('route.personal.profile'),
|
|
73
77
|
icon: 'i-iconamoon-profile-duotone',
|
|
74
|
-
|
|
78
|
+
onClick: () => router.push({ name: 'Profile' }),
|
|
75
79
|
},
|
|
76
|
-
{
|
|
80
|
+
Password: {
|
|
81
|
+
key: 'password',
|
|
77
82
|
label: t('app.changePassword'),
|
|
78
83
|
icon: 'i-iconamoon-lock-duotone',
|
|
79
|
-
|
|
84
|
+
onClick: () => router.push({
|
|
80
85
|
name: 'ChangePassword',
|
|
81
86
|
params: {
|
|
82
87
|
changePassWordToken: userStore.user.token,
|
|
83
88
|
},
|
|
84
89
|
}),
|
|
85
90
|
},
|
|
86
|
-
{
|
|
91
|
+
Logout: {
|
|
92
|
+
key: 'logout',
|
|
87
93
|
label: t('app.logout'),
|
|
88
94
|
icon: 'i-iconamoon-arrow-left-3-square-duotone',
|
|
89
|
-
|
|
95
|
+
onClick: () => userStore.logout(),
|
|
90
96
|
},
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const colorScheme = settingsStore.settings.app.colorScheme === 'dark' ? 'light' : 'dark';
|
|
97
|
-
settingsStore.setColorScheme(colorScheme);
|
|
98
|
-
await settingsStore.setPreferencesSetting({
|
|
99
|
-
app: {
|
|
100
|
-
colorScheme,
|
|
101
|
-
},
|
|
102
|
-
});
|
|
103
|
-
});
|
|
97
|
+
Divider: {
|
|
98
|
+
key: 'divider',
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
});
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const endRadius = Math.hypot(
|
|
109
|
-
Math.max(x, innerWidth - x),
|
|
110
|
-
Math.max(y, innerHeight - y),
|
|
111
|
-
);
|
|
112
|
-
const clipPath = [
|
|
113
|
-
`circle(0px at ${x}px ${y}px)`,
|
|
114
|
-
`circle(${endRadius}px at ${x}px ${y}px)`,
|
|
115
|
-
];
|
|
116
|
-
document.documentElement.animate(
|
|
117
|
-
{
|
|
118
|
-
clipPath: settingsStore.settings.app.colorScheme !== 'dark' ? clipPath : clipPath.reverse(),
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
duration: 300,
|
|
122
|
-
easing: 'ease-out',
|
|
123
|
-
pseudoElement: settingsStore.settings.app.colorScheme !== 'dark' ? '::view-transition-new(root)' : '::view-transition-old(root)',
|
|
124
|
-
},
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
}
|
|
103
|
+
const menus = computed(() => {
|
|
104
|
+
return props.dropdownMenuRender?.(userMenu.value);
|
|
105
|
+
});
|
|
128
106
|
|
|
129
107
|
const avatarError = ref(false);
|
|
130
108
|
|
|
@@ -133,73 +111,33 @@ watch(() => userStore.user.avatar, () => {
|
|
|
133
111
|
avatarError.value = false;
|
|
134
112
|
}
|
|
135
113
|
});
|
|
136
|
-
|
|
137
|
-
const searchComponentsClass = computed(() => {
|
|
138
|
-
const componentsClass = {
|
|
139
|
-
'side': 'ring-1 ',
|
|
140
|
-
'head': 'bg-[var(--g-header-menu-active-bg)]',
|
|
141
|
-
'single': ' ring-1',
|
|
142
|
-
'only-side': 'ring-1',
|
|
143
|
-
'only-head': ' bg-[var(--g-header-menu-active-bg)]',
|
|
144
|
-
};
|
|
145
|
-
const menuMode = settingsStore.settings.menu.menuMode;
|
|
146
|
-
return componentsClass[menuMode];
|
|
147
|
-
});
|
|
148
114
|
</script>
|
|
149
115
|
|
|
150
116
|
<template>
|
|
151
117
|
<div class="tools flex items-center gap-4 whitespace-nowrap px-4">
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
<HKbd
|
|
161
|
-
v-if="settingsStore.settings.navSearch.enableHotkeys"
|
|
162
|
-
class="ml-2"
|
|
163
|
-
>{{ settingsStore.os === 'mac' ? '⌥' : 'Alt' }} S</HKbd>
|
|
164
|
-
</span>
|
|
165
|
-
<div class="flex items-center empty:hidden">
|
|
166
|
-
<span
|
|
167
|
-
v-if="settingsStore.settings.navSearch.enable && settingsStore.mode === 'mobile'"
|
|
168
|
-
class="item"
|
|
169
|
-
@click="toggleSearch('menu')"
|
|
170
|
-
>
|
|
171
|
-
<IconamoonSearch text="14px" />
|
|
172
|
-
</span>
|
|
173
|
-
<span
|
|
174
|
-
v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.enableFullscreen"
|
|
175
|
-
class="item"
|
|
176
|
-
@click="toggle"
|
|
177
|
-
>
|
|
178
|
-
<FluentFullScreenMinimize16Filled v-if="isFullscreen" text="16px" />
|
|
179
|
-
<FluentFullScreenMaximize16Filled v-else text="16px" />
|
|
180
|
-
</span>
|
|
181
|
-
<span
|
|
182
|
-
v-if="settingsStore.settings.toolbar.enablePageReload"
|
|
183
|
-
class="item"
|
|
184
|
-
@click="mainPage.reload()"
|
|
185
|
-
>
|
|
186
|
-
<FluentArrowSync16Filled text="15px" />
|
|
187
|
-
</span>
|
|
188
|
-
<DayNightSwitch @click="toggleColorScheme" />
|
|
118
|
+
<SearchBar />
|
|
119
|
+
|
|
120
|
+
<div class="flex items-center empty:hidden gap-3">
|
|
121
|
+
<slot name="default">
|
|
122
|
+
<Fullscreen />
|
|
123
|
+
<PageReload />
|
|
124
|
+
<DarkModeToggle />
|
|
125
|
+
</slot>
|
|
189
126
|
</div>
|
|
127
|
+
|
|
190
128
|
<div flex-center cursor-pointer gap-1>
|
|
191
129
|
<img
|
|
192
130
|
v-if="userStore.user.avatar && !avatarError"
|
|
193
131
|
:src="userStore.user.avatar"
|
|
194
132
|
:onerror="() => (avatarError = true)"
|
|
195
|
-
class="
|
|
133
|
+
class="size-[24px] rounded-full"
|
|
196
134
|
>
|
|
197
135
|
<CarbonUserAvatarFilledAlt v-else text="20px" mr-2px />
|
|
198
136
|
<div class="flex-center cursor-pointer">
|
|
199
137
|
{{ userStore.userOrgName }}
|
|
200
138
|
</div>
|
|
201
|
-
<PhLineVerticalThin />
|
|
202
|
-
<HDropdownMenu :items="
|
|
139
|
+
<PhLineVerticalThin v-if="userStore?.userOrgName" />
|
|
140
|
+
<HDropdownMenu :items="menus">
|
|
203
141
|
<div flex-center cursor-pointer gap-1>
|
|
204
142
|
{{ userStore.user.account }}
|
|
205
143
|
<MaterialSymbolsExpandMoreRounded ml="5px" mr="10px" />
|
|
@@ -208,13 +146,7 @@ const searchComponentsClass = computed(() => {
|
|
|
208
146
|
</div>
|
|
209
147
|
|
|
210
148
|
<HotkeysIntro ref="hotkeysIntroRef" />
|
|
211
|
-
<
|
|
149
|
+
<SearchPanel />
|
|
212
150
|
<Preferences v-if="settingsStore.settings.app.enableUserPreferences" ref="preferencesRef" />
|
|
213
151
|
</div>
|
|
214
152
|
</template>
|
|
215
|
-
|
|
216
|
-
<style scoped>
|
|
217
|
-
.item {
|
|
218
|
-
--at-apply: flex px-2 py-1 cursor-pointer;
|
|
219
|
-
}
|
|
220
|
-
</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface DropdownMenu {
|
|
2
|
+
key?: string | 'divider'
|
|
3
|
+
icon?: string
|
|
4
|
+
label?: string
|
|
5
|
+
disabled?: boolean
|
|
6
|
+
hide?: boolean
|
|
7
|
+
onClick?: () => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type DropdownMenuRender = (items: {
|
|
11
|
+
/** 主页 */
|
|
12
|
+
Home: DropdownMenu
|
|
13
|
+
/** 个人偏好设置 */
|
|
14
|
+
Preferences: DropdownMenu
|
|
15
|
+
/** 快捷键介绍 */
|
|
16
|
+
Hotkeys: DropdownMenu
|
|
17
|
+
/** 切换组织 */
|
|
18
|
+
Org: DropdownMenu
|
|
19
|
+
/** 个人中心 */
|
|
20
|
+
Profile: DropdownMenu
|
|
21
|
+
/** 修改密码 */
|
|
22
|
+
Password: DropdownMenu
|
|
23
|
+
/** 登出 */
|
|
24
|
+
Logout: DropdownMenu
|
|
25
|
+
/** 分割线 */
|
|
26
|
+
Divider: DropdownMenu
|
|
27
|
+
}) => DropdownMenu[];
|