Commit 0e7c57bd5ecafd8283bcc950b24bb63b59b70e5a
1 parent
144ab577
feat(tabs): added tab folding
Showing
30 changed files
with
271 additions
and
177 deletions
CHANGELOG.zh_CN.md
@@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
6 | - 新增`mixSideFixed`配置。用于固定左侧混合模式菜单 | 6 | - 新增`mixSideFixed`配置。用于固定左侧混合模式菜单 |
7 | - modal 组件新增`height`和`min-height`属性 | 7 | - modal 组件新增`height`和`min-height`属性 |
8 | - 新增`PageWrapper`组件。并应用于示例页面 | 8 | - 新增`PageWrapper`组件。并应用于示例页面 |
9 | +- 新增标签页折叠功能 | ||
9 | 10 | ||
10 | ### 🐛 Bug Fixes | 11 | ### 🐛 Bug Fixes |
11 | 12 |
mock/_createProductionServer.ts
@@ -2,10 +2,18 @@ import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'; | @@ -2,10 +2,18 @@ import { createProdMockServer } from 'vite-plugin-mock/es/createProdMockServer'; | ||
2 | import userMock from './sys/user'; | 2 | import userMock from './sys/user'; |
3 | import menuMock from './sys/menu'; | 3 | import menuMock from './sys/menu'; |
4 | import tableDemoMock from './demo/table-demo'; | 4 | import tableDemoMock from './demo/table-demo'; |
5 | +import accountDemoMock from './demo/account'; | ||
6 | +import selectDemoMock from './demo/select-demo'; | ||
5 | 7 | ||
6 | /** | 8 | /** |
7 | * Used in a production environment. Need to manually import all modules | 9 | * Used in a production environment. Need to manually import all modules |
8 | */ | 10 | */ |
9 | export function setupProdMockServer() { | 11 | export function setupProdMockServer() { |
10 | - createProdMockServer([...userMock, ...menuMock, ...tableDemoMock]); | 12 | + createProdMockServer([ |
13 | + ...userMock, | ||
14 | + ...menuMock, | ||
15 | + ...tableDemoMock, | ||
16 | + ...accountDemoMock, | ||
17 | + ...selectDemoMock, | ||
18 | + ]); | ||
11 | } | 19 | } |
src/components/Icon/src/index.vue
src/components/Menu/src/useOpenKeys.ts
@@ -16,16 +16,20 @@ export function useOpenKeys( | @@ -16,16 +16,20 @@ export function useOpenKeys( | ||
16 | mode: Ref<MenuModeEnum>, | 16 | mode: Ref<MenuModeEnum>, |
17 | accordion: Ref<boolean> | 17 | accordion: Ref<boolean> |
18 | ) { | 18 | ) { |
19 | - const { getCollapsed, getIsMixSidebar, getMixSideFixed } = useMenuSetting(); | 19 | + const { getCollapsed, getIsMixSidebar } = useMenuSetting(); |
20 | 20 | ||
21 | async function setOpenKeys(path: string) { | 21 | async function setOpenKeys(path: string) { |
22 | if (mode.value === MenuModeEnum.HORIZONTAL) { | 22 | if (mode.value === MenuModeEnum.HORIZONTAL) { |
23 | return; | 23 | return; |
24 | } | 24 | } |
25 | - const native = unref(getIsMixSidebar) && unref(getMixSideFixed); | 25 | + const native = unref(getIsMixSidebar); |
26 | useTimeoutFn( | 26 | useTimeoutFn( |
27 | () => { | 27 | () => { |
28 | const menuList = toRaw(menus.value); | 28 | const menuList = toRaw(menus.value); |
29 | + if (menuList?.length === 0) { | ||
30 | + menuState.openKeys = []; | ||
31 | + return; | ||
32 | + } | ||
29 | if (!unref(accordion)) { | 33 | if (!unref(accordion)) { |
30 | menuState.openKeys = es6Unique([ | 34 | menuState.openKeys = es6Unique([ |
31 | ...menuState.openKeys, | 35 | ...menuState.openKeys, |
src/components/Modal/src/BasicModal.vue
@@ -51,7 +51,6 @@ | @@ -51,7 +51,6 @@ | ||
51 | watchEffect, | 51 | watchEffect, |
52 | toRef, | 52 | toRef, |
53 | getCurrentInstance, | 53 | getCurrentInstance, |
54 | - nextTick, | ||
55 | } from 'vue'; | 54 | } from 'vue'; |
56 | 55 | ||
57 | import Modal from './components/Modal'; | 56 | import Modal from './components/Modal'; |
@@ -111,7 +110,6 @@ | @@ -111,7 +110,6 @@ | ||
111 | visible: unref(visibleRef), | 110 | visible: unref(visibleRef), |
112 | title: undefined, | 111 | title: undefined, |
113 | }; | 112 | }; |
114 | - | ||
115 | return { | 113 | return { |
116 | ...opt, | 114 | ...opt, |
117 | wrapClassName: unref(getWrapClassName), | 115 | wrapClassName: unref(getWrapClassName), |
src/components/Modal/src/components/ModalWrapper.vue
1 | <template> | 1 | <template> |
2 | - <ScrollContainer ref="wrapperRef" :style="wrapStyle"> | 2 | + <ScrollContainer ref="wrapperRef"> |
3 | <div ref="spinRef" :style="spinStyle" v-loading="loading" :loading-tip="loadingTip"> | 3 | <div ref="spinRef" :style="spinStyle" v-loading="loading" :loading-tip="loadingTip"> |
4 | <slot /> | 4 | <slot /> |
5 | </div> | 5 | </div> |
@@ -62,19 +62,10 @@ | @@ -62,19 +62,10 @@ | ||
62 | redoModalHeight: setModalHeight, | 62 | redoModalHeight: setModalHeight, |
63 | }); | 63 | }); |
64 | 64 | ||
65 | - const wrapStyle = computed( | ||
66 | - (): CSSProperties => { | ||
67 | - return { | ||
68 | - minHeight: `${props.minHeight}px`, | ||
69 | - height: `${unref(realHeightRef)}px`, | ||
70 | - // overflow: 'auto', | ||
71 | - }; | ||
72 | - } | ||
73 | - ); | ||
74 | - | ||
75 | const spinStyle = computed( | 65 | const spinStyle = computed( |
76 | (): CSSProperties => { | 66 | (): CSSProperties => { |
77 | return { | 67 | return { |
68 | + minHeight: `${props.minHeight}px`, | ||
78 | // padding 28 | 69 | // padding 28 |
79 | height: `${unref(realHeightRef) - 28}px`, | 70 | height: `${unref(realHeightRef) - 28}px`, |
80 | }; | 71 | }; |
@@ -159,7 +150,7 @@ | @@ -159,7 +150,7 @@ | ||
159 | } | 150 | } |
160 | } | 151 | } |
161 | 152 | ||
162 | - return { wrapStyle, wrapperRef, spinRef, spinStyle }; | 153 | + return { wrapperRef, spinRef, spinStyle }; |
163 | }, | 154 | }, |
164 | }); | 155 | }); |
165 | </script> | 156 | </script> |
src/components/Modal/src/index.less
@@ -21,12 +21,9 @@ | @@ -21,12 +21,9 @@ | ||
21 | width: 520px; | 21 | width: 520px; |
22 | padding-bottom: 0; | 22 | padding-bottom: 0; |
23 | 23 | ||
24 | - .scroll-container { | 24 | + .scrollbar { |
25 | padding: 14px; | 25 | padding: 14px; |
26 | } | 26 | } |
27 | - // .ant-spin-nested-loading { | ||
28 | - // padding: 16px; | ||
29 | - // } | ||
30 | 27 | ||
31 | &-title { | 28 | &-title { |
32 | font-size: 16px; | 29 | font-size: 16px; |
src/components/Scrollbar/src/index.vue
@@ -18,7 +18,8 @@ | @@ -18,7 +18,8 @@ | ||
18 | </template> | 18 | </template> |
19 | <script lang="ts"> | 19 | <script lang="ts"> |
20 | import { addResizeListener, removeResizeListener } from '/@/utils/event/resizeEvent'; | 20 | import { addResizeListener, removeResizeListener } from '/@/utils/event/resizeEvent'; |
21 | - | 21 | + import componentSetting from '/@/settings/componentSetting'; |
22 | + const { scrollbar } = componentSetting; | ||
22 | import { toObject } from './util'; | 23 | import { toObject } from './util'; |
23 | import { | 24 | import { |
24 | defineComponent, | 25 | defineComponent, |
@@ -38,7 +39,7 @@ | @@ -38,7 +39,7 @@ | ||
38 | props: { | 39 | props: { |
39 | native: { | 40 | native: { |
40 | type: Boolean, | 41 | type: Boolean, |
41 | - default: false, | 42 | + default: scrollbar?.native ?? false, |
42 | }, | 43 | }, |
43 | wrapStyle: { | 44 | wrapStyle: { |
44 | type: [String, Array], | 45 | type: [String, Array], |
src/components/Table/src/components/settings/ColumnSetting.vue
src/components/Table/src/const.ts
1 | -import type { SorterResult } from './types/table'; | 1 | +import componentSetting from '/@/settings/componentSetting'; |
2 | + | ||
3 | +const { table } = componentSetting; | ||
4 | + | ||
5 | +const { pageSizeOptions, defaultPageSize, fetchSetting, defaultSortFn, defaultFilterFn } = table; | ||
2 | 6 | ||
3 | export const ROW_KEY = 'key'; | 7 | export const ROW_KEY = 'key'; |
4 | 8 | ||
5 | // 可选的每页显示条数; | 9 | // 可选的每页显示条数; |
6 | -export const PAGE_SIZE_OPTIONS = ['10', '50', '80', '100']; | 10 | +export const PAGE_SIZE_OPTIONS = pageSizeOptions; |
7 | 11 | ||
8 | // 每页显示条数 | 12 | // 每页显示条数 |
9 | -export const PAGE_SIZE = ~~PAGE_SIZE_OPTIONS[0]; | 13 | +export const PAGE_SIZE = defaultPageSize; |
10 | 14 | ||
11 | // 通用接口字段设置 | 15 | // 通用接口字段设置 |
12 | -// 支持 xxx.xxx.xxx格式 | ||
13 | -export const FETCH_SETTING = { | ||
14 | - // 传给后台的当前页字段名 | ||
15 | - pageField: 'page', | ||
16 | - // 传给后台的每页显示记录数字段名 | ||
17 | - sizeField: 'pageSize', | ||
18 | - // 接口返回的表格数据字段名 | ||
19 | - listField: 'items', | ||
20 | - // 接口返回的表格总数字段名 | ||
21 | - totalField: 'total', | ||
22 | -}; | 16 | +export const FETCH_SETTING = fetchSetting; |
23 | 17 | ||
24 | // 配置通用排序函数 | 18 | // 配置通用排序函数 |
25 | -export function DEFAULT_SORT_FN(sortInfo: SorterResult) { | ||
26 | - const { field, order } = sortInfo; | ||
27 | - return { | ||
28 | - // 传给后台的排序字段你 | ||
29 | - field, | ||
30 | - // 传给后台的排序方式 asc/desc | ||
31 | - order, | ||
32 | - }; | ||
33 | -} | ||
34 | - | ||
35 | -export function DEFAULT_FILTER_FN(data: Partial<Recordable<string[]>>) { | ||
36 | - return data; | ||
37 | -} | 19 | +export const DEFAULT_SORT_FN = defaultSortFn; |
20 | + | ||
21 | +export const DEFAULT_FILTER_FN = defaultFilterFn; | ||
38 | 22 | ||
39 | // 表格单元格默认布局 | 23 | // 表格单元格默认布局 |
40 | export const DEFAULT_ALIGN = 'center'; | 24 | export const DEFAULT_ALIGN = 'center'; |
src/hooks/setting/useMenuSetting.ts
@@ -78,7 +78,9 @@ const getIsMixMode = computed(() => { | @@ -78,7 +78,9 @@ const getIsMixMode = computed(() => { | ||
78 | }); | 78 | }); |
79 | 79 | ||
80 | const getRealWidth = computed(() => { | 80 | const getRealWidth = computed(() => { |
81 | - return unref(getCollapsed) ? unref(getMiniWidthNumber) : unref(getMenuWidth); | 81 | + return unref(getCollapsed) && !unref(getMixSideFixed) |
82 | + ? unref(getMiniWidthNumber) | ||
83 | + : unref(getMenuWidth); | ||
82 | }); | 84 | }); |
83 | 85 | ||
84 | const getMiniWidthNumber = computed(() => { | 86 | const getMiniWidthNumber = computed(() => { |
@@ -94,7 +96,6 @@ const getCalcContentWidth = computed(() => { | @@ -94,7 +96,6 @@ const getCalcContentWidth = computed(() => { | ||
94 | ? SIDE_BAR_SHOW_TIT_MINI_WIDTH + | 96 | ? SIDE_BAR_SHOW_TIT_MINI_WIDTH + |
95 | (unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0) | 97 | (unref(getMixSideFixed) && unref(mixSideHasChildren) ? unref(getRealWidth) : 0) |
96 | : unref(getRealWidth); | 98 | : unref(getRealWidth); |
97 | - | ||
98 | return `calc(100% - ${unref(width)}px)`; | 99 | return `calc(100% - ${unref(width)}px)`; |
99 | }); | 100 | }); |
100 | 101 |
src/hooks/setting/useMultipleTabSetting.ts
@@ -12,6 +12,8 @@ const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick); | @@ -12,6 +12,8 @@ const getShowQuick = computed(() => unref(getMultipleTabSetting).showQuick); | ||
12 | 12 | ||
13 | const getShowRedo = computed(() => unref(getMultipleTabSetting).showRedo); | 13 | const getShowRedo = computed(() => unref(getMultipleTabSetting).showRedo); |
14 | 14 | ||
15 | +const getShowFold = computed(() => unref(getMultipleTabSetting).showFold); | ||
16 | + | ||
15 | function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { | 17 | function setMultipleTabSetting(multiTabsSetting: Partial<MultiTabsSetting>) { |
16 | appStore.commitProjectConfigState({ multiTabsSetting }); | 18 | appStore.commitProjectConfigState({ multiTabsSetting }); |
17 | } | 19 | } |
@@ -24,5 +26,6 @@ export function useMultipleTabSetting() { | @@ -24,5 +26,6 @@ export function useMultipleTabSetting() { | ||
24 | getShowMultipleTab, | 26 | getShowMultipleTab, |
25 | getShowQuick, | 27 | getShowQuick, |
26 | getShowRedo, | 28 | getShowRedo, |
29 | + getShowFold, | ||
27 | }; | 30 | }; |
28 | } | 31 | } |
src/hooks/web/useTabs.ts
1 | import { tabStore } from '/@/store/modules/tab'; | 1 | import { tabStore } from '/@/store/modules/tab'; |
2 | import { appStore } from '/@/store/modules/app'; | 2 | import { appStore } from '/@/store/modules/app'; |
3 | +import type { RouteLocationNormalized } from 'vue-router'; | ||
3 | 4 | ||
4 | export function useTabs() { | 5 | export function useTabs() { |
5 | function canIUseFn(): boolean { | 6 | function canIUseFn(): boolean { |
@@ -21,5 +22,7 @@ export function useTabs() { | @@ -21,5 +22,7 @@ export function useTabs() { | ||
21 | closeRight: () => canIUseFn() && tabStore.closeRightTabAction(tabStore.getCurrentTab), | 22 | closeRight: () => canIUseFn() && tabStore.closeRightTabAction(tabStore.getCurrentTab), |
22 | closeOther: () => canIUseFn() && tabStore.closeOtherTabAction(tabStore.getCurrentTab), | 23 | closeOther: () => canIUseFn() && tabStore.closeOtherTabAction(tabStore.getCurrentTab), |
23 | closeCurrent: () => canIUseFn() && tabStore.closeTabAction(tabStore.getCurrentTab), | 24 | closeCurrent: () => canIUseFn() && tabStore.closeTabAction(tabStore.getCurrentTab), |
25 | + close: (tab?: RouteLocationNormalized) => | ||
26 | + canIUseFn() && tabStore.closeTabAction(tab || tabStore.getCurrentTab), | ||
24 | }; | 27 | }; |
25 | } | 28 | } |
src/layouts/default/setting/SettingDrawer.tsx
@@ -85,7 +85,7 @@ export default defineComponent({ | @@ -85,7 +85,7 @@ export default defineComponent({ | ||
85 | getShowSearch, | 85 | getShowSearch, |
86 | } = useHeaderSetting(); | 86 | } = useHeaderSetting(); |
87 | 87 | ||
88 | - const { getShowMultipleTab, getShowQuick, getShowRedo } = useMultipleTabSetting(); | 88 | + const { getShowMultipleTab, getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting(); |
89 | 89 | ||
90 | const getShowMenuRef = computed(() => { | 90 | const getShowMenuRef = computed(() => { |
91 | return unref(getShowMenu) && !unref(getIsHorizontal); | 91 | return unref(getShowMenu) && !unref(getIsHorizontal); |
@@ -105,33 +105,6 @@ export default defineComponent({ | @@ -105,33 +105,6 @@ export default defineComponent({ | ||
105 | }} | 105 | }} |
106 | def={unref(getMenuType)} | 106 | def={unref(getMenuType)} |
107 | /> | 107 | /> |
108 | - <SwitchItem | ||
109 | - title={t('layout.setting.splitMenu')} | ||
110 | - event={HandlerEnum.MENU_SPLIT} | ||
111 | - def={unref(getSplit)} | ||
112 | - disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX} | ||
113 | - /> | ||
114 | - <SwitchItem | ||
115 | - title={t('layout.setting.mixSidebarFixed')} | ||
116 | - event={HandlerEnum.MENU_FIXED_MIX_SIDEBAR} | ||
117 | - def={unref(getMixSideFixed)} | ||
118 | - disabled={!unref(getIsMixSidebar)} | ||
119 | - /> | ||
120 | - | ||
121 | - <SwitchItem | ||
122 | - title={t('layout.setting.closeMixSidebarOnChange')} | ||
123 | - event={HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE} | ||
124 | - def={unref(getCloseMixSidebarOnChange)} | ||
125 | - disabled={!unref(getIsMixSidebar)} | ||
126 | - /> | ||
127 | - | ||
128 | - <SelectItem | ||
129 | - title={t('layout.setting.mixSidebarTrigger')} | ||
130 | - event={HandlerEnum.MENU_TRIGGER_MIX_SIDEBAR} | ||
131 | - def={unref(getMixSideTrigger)} | ||
132 | - options={mixSidebarTriggerOptions} | ||
133 | - disabled={!unref(getIsMixSidebar)} | ||
134 | - /> | ||
135 | </> | 108 | </> |
136 | ); | 109 | ); |
137 | } | 110 | } |
@@ -171,6 +144,32 @@ export default defineComponent({ | @@ -171,6 +144,32 @@ export default defineComponent({ | ||
171 | return ( | 144 | return ( |
172 | <> | 145 | <> |
173 | <SwitchItem | 146 | <SwitchItem |
147 | + title={t('layout.setting.splitMenu')} | ||
148 | + event={HandlerEnum.MENU_SPLIT} | ||
149 | + def={unref(getSplit)} | ||
150 | + disabled={!unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX} | ||
151 | + /> | ||
152 | + <SwitchItem | ||
153 | + title={t('layout.setting.mixSidebarFixed')} | ||
154 | + event={HandlerEnum.MENU_FIXED_MIX_SIDEBAR} | ||
155 | + def={unref(getMixSideFixed)} | ||
156 | + disabled={!unref(getIsMixSidebar)} | ||
157 | + /> | ||
158 | + | ||
159 | + <SwitchItem | ||
160 | + title={t('layout.setting.closeMixSidebarOnChange')} | ||
161 | + event={HandlerEnum.MENU_CLOSE_MIX_SIDEBAR_ON_CHANGE} | ||
162 | + def={unref(getCloseMixSidebarOnChange)} | ||
163 | + disabled={!unref(getIsMixSidebar)} | ||
164 | + /> | ||
165 | + <SwitchItem | ||
166 | + title={t('layout.setting.menuCollapse')} | ||
167 | + event={HandlerEnum.MENU_COLLAPSED} | ||
168 | + def={unref(getCollapsed)} | ||
169 | + disabled={!unref(getShowMenuRef)} | ||
170 | + /> | ||
171 | + | ||
172 | + <SwitchItem | ||
174 | title={t('layout.setting.menuDrag')} | 173 | title={t('layout.setting.menuDrag')} |
175 | event={HandlerEnum.MENU_HAS_DRAG} | 174 | event={HandlerEnum.MENU_HAS_DRAG} |
176 | def={unref(getCanDrag)} | 175 | def={unref(getCanDrag)} |
@@ -188,17 +187,12 @@ export default defineComponent({ | @@ -188,17 +187,12 @@ export default defineComponent({ | ||
188 | def={unref(getAccordion)} | 187 | def={unref(getAccordion)} |
189 | disabled={!unref(getShowMenuRef)} | 188 | disabled={!unref(getShowMenuRef)} |
190 | /> | 189 | /> |
191 | - <SwitchItem | ||
192 | - title={t('layout.setting.menuCollapse')} | ||
193 | - event={HandlerEnum.MENU_COLLAPSED} | ||
194 | - def={unref(getCollapsed)} | ||
195 | - disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)} | ||
196 | - /> | 190 | + |
197 | <SwitchItem | 191 | <SwitchItem |
198 | title={t('layout.setting.collapseMenuDisplayName')} | 192 | title={t('layout.setting.collapseMenuDisplayName')} |
199 | event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE} | 193 | event={HandlerEnum.MENU_COLLAPSED_SHOW_TITLE} |
200 | def={unref(getCollapsedShowTitle)} | 194 | def={unref(getCollapsedShowTitle)} |
201 | - disabled={!unref(getShowMenuRef) || !unref(getCollapsed)} | 195 | + disabled={!unref(getShowMenuRef) || !unref(getCollapsed) || unref(getIsMixSidebar)} |
202 | /> | 196 | /> |
203 | 197 | ||
204 | <SwitchItem | 198 | <SwitchItem |
@@ -214,6 +208,13 @@ export default defineComponent({ | @@ -214,6 +208,13 @@ export default defineComponent({ | ||
214 | disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)} | 208 | disabled={!unref(getShowMenuRef) || unref(getIsMixSidebar)} |
215 | /> | 209 | /> |
216 | <SelectItem | 210 | <SelectItem |
211 | + title={t('layout.setting.mixSidebarTrigger')} | ||
212 | + event={HandlerEnum.MENU_TRIGGER_MIX_SIDEBAR} | ||
213 | + def={unref(getMixSideTrigger)} | ||
214 | + options={mixSidebarTriggerOptions} | ||
215 | + disabled={!unref(getIsMixSidebar)} | ||
216 | + /> | ||
217 | + <SelectItem | ||
217 | title={t('layout.setting.topMenuLayout')} | 218 | title={t('layout.setting.topMenuLayout')} |
218 | event={HandlerEnum.MENU_TOP_ALIGN} | 219 | event={HandlerEnum.MENU_TOP_ALIGN} |
219 | def={unref(getTopMenuAlign)} | 220 | def={unref(getTopMenuAlign)} |
@@ -299,6 +300,12 @@ export default defineComponent({ | @@ -299,6 +300,12 @@ export default defineComponent({ | ||
299 | def={unref(getShowQuick)} | 300 | def={unref(getShowQuick)} |
300 | disabled={!unref(getShowMultipleTab)} | 301 | disabled={!unref(getShowMultipleTab)} |
301 | /> | 302 | /> |
303 | + <SwitchItem | ||
304 | + title={t('layout.setting.tabsFoldBtn')} | ||
305 | + event={HandlerEnum.TABS_SHOW_FOLD} | ||
306 | + def={unref(getShowFold)} | ||
307 | + disabled={!unref(getShowMultipleTab)} | ||
308 | + /> | ||
302 | 309 | ||
303 | <SwitchItem | 310 | <SwitchItem |
304 | title={t('layout.setting.sidebar')} | 311 | title={t('layout.setting.sidebar')} |
src/layouts/default/setting/enum.ts
src/layouts/default/setting/handler.ts
@@ -71,7 +71,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | @@ -71,7 +71,7 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | ||
71 | return { menuSetting: { mixSideTrigger: value } }; | 71 | return { menuSetting: { mixSideTrigger: value } }; |
72 | 72 | ||
73 | case HandlerEnum.MENU_FIXED_MIX_SIDEBAR: | 73 | case HandlerEnum.MENU_FIXED_MIX_SIDEBAR: |
74 | - return { menuSetting: { mixSideTrigger: value } }; | 74 | + return { menuSetting: { mixSideFixed: value } }; |
75 | 75 | ||
76 | // ============transition================== | 76 | // ============transition================== |
77 | case HandlerEnum.OPEN_PAGE_LOADING: | 77 | case HandlerEnum.OPEN_PAGE_LOADING: |
@@ -123,9 +123,13 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | @@ -123,9 +123,13 @@ export function handler(event: HandlerEnum, value: any): DeepPartial<ProjectConf | ||
123 | 123 | ||
124 | case HandlerEnum.TABS_SHOW: | 124 | case HandlerEnum.TABS_SHOW: |
125 | return { multiTabsSetting: { show: value } }; | 125 | return { multiTabsSetting: { show: value } }; |
126 | + | ||
126 | case HandlerEnum.TABS_SHOW_REDO: | 127 | case HandlerEnum.TABS_SHOW_REDO: |
127 | return { multiTabsSetting: { showRedo: value } }; | 128 | return { multiTabsSetting: { showRedo: value } }; |
128 | 129 | ||
130 | + case HandlerEnum.TABS_SHOW_FOLD: | ||
131 | + return { multiTabsSetting: { showFold: value } }; | ||
132 | + | ||
129 | // ============header================== | 133 | // ============header================== |
130 | case HandlerEnum.HEADER_THEME: | 134 | case HandlerEnum.HEADER_THEME: |
131 | updateHeaderBgColor(value); | 135 | updateHeaderBgColor(value); |
src/layouts/default/sider/MixSider.vue
@@ -3,11 +3,13 @@ | @@ -3,11 +3,13 @@ | ||
3 | 3 | ||
4 | <div | 4 | <div |
5 | v-click-outside="handleClickOutside" | 5 | v-click-outside="handleClickOutside" |
6 | + :style="getWrapStyle" | ||
6 | :class="[ | 7 | :class="[ |
7 | prefixCls, | 8 | prefixCls, |
8 | getMenuTheme, | 9 | getMenuTheme, |
9 | { | 10 | { |
10 | open: openMenu, | 11 | open: openMenu, |
12 | + mini: getCollapsed, | ||
11 | }, | 13 | }, |
12 | ]" | 14 | ]" |
13 | v-bind="getMenuEvents" | 15 | v-bind="getMenuEvents" |
@@ -29,7 +31,7 @@ | @@ -29,7 +31,7 @@ | ||
29 | <MenuTag :item="item" :showTitle="false" :isHorizontal="false" /> | 31 | <MenuTag :item="item" :showTitle="false" :isHorizontal="false" /> |
30 | <Icon | 32 | <Icon |
31 | :class="`${prefixCls}-module__icon`" | 33 | :class="`${prefixCls}-module__icon`" |
32 | - :size="22" | 34 | + :size="getCollapsed ? 16 : 20" |
33 | :icon="item.meta && item.meta.icon" | 35 | :icon="item.meta && item.meta.icon" |
34 | /> | 36 | /> |
35 | <p :class="`${prefixCls}-module__name`">{{ t(item.name) }}</p> | 37 | <p :class="`${prefixCls}-module__name`">{{ t(item.name) }}</p> |
@@ -50,12 +52,10 @@ | @@ -50,12 +52,10 @@ | ||
50 | <span class="text"> {{ title }}</span> | 52 | <span class="text"> {{ title }}</span> |
51 | <Icon | 53 | <Icon |
52 | :size="16" | 54 | :size="16" |
53 | - v-if="getMixSideFixed" | ||
54 | - icon="ri:pushpin-2-fill" | 55 | + :icon="getMixSideFixed ? 'ri:pushpin-2-fill' : 'ri:pushpin-2-line'" |
55 | class="pushpin" | 56 | class="pushpin" |
56 | @click="handleFixedMenu" | 57 | @click="handleFixedMenu" |
57 | /> | 58 | /> |
58 | - <Icon :size="16" v-else icon="ri:pushpin-2-line" class="pushpin" @click="handleFixedMenu" /> | ||
59 | </div> | 59 | </div> |
60 | <ScrollContainer :class="`${prefixCls}-menu-list__content`"> | 60 | <ScrollContainer :class="`${prefixCls}-menu-list__content`"> |
61 | <BasicMenu | 61 | <BasicMenu |
@@ -92,7 +92,7 @@ | @@ -92,7 +92,7 @@ | ||
92 | import { useDragLine } from './useLayoutSider'; | 92 | import { useDragLine } from './useLayoutSider'; |
93 | import { useGlobSetting } from '/@/hooks/setting'; | 93 | import { useGlobSetting } from '/@/hooks/setting'; |
94 | 94 | ||
95 | - import { SIDE_BAR_SHOW_TIT_MINI_WIDTH } from '/@/enums/appEnum'; | 95 | + import { SIDE_BAR_SHOW_TIT_MINI_WIDTH, SIDE_BAR_MINI_WIDTH } from '/@/enums/appEnum'; |
96 | 96 | ||
97 | import clickOutside from '/@/directives/clickOutside'; | 97 | import clickOutside from '/@/directives/clickOutside'; |
98 | 98 | ||
@@ -130,6 +130,8 @@ | @@ -130,6 +130,8 @@ | ||
130 | getMixSideFixed, | 130 | getMixSideFixed, |
131 | mixSideHasChildren, | 131 | mixSideHasChildren, |
132 | setMenuSetting, | 132 | setMenuSetting, |
133 | + getIsMixSidebar, | ||
134 | + getCollapsed, | ||
133 | } = useMenuSetting(); | 135 | } = useMenuSetting(); |
134 | 136 | ||
135 | const { title } = useGlobSetting(); | 137 | const { title } = useGlobSetting(); |
@@ -140,6 +142,7 @@ | @@ -140,6 +142,7 @@ | ||
140 | (): CSSProperties => { | 142 | (): CSSProperties => { |
141 | return { | 143 | return { |
142 | width: unref(openMenu) ? `${unref(getMenuWidth)}px` : 0, | 144 | width: unref(openMenu) ? `${unref(getMenuWidth)}px` : 0, |
145 | + left: `${unref(getMixSideWidth)}px`, | ||
143 | }; | 146 | }; |
144 | } | 147 | } |
145 | ); | 148 | ); |
@@ -153,32 +156,33 @@ | @@ -153,32 +156,33 @@ | ||
153 | return isFixed; | 156 | return isFixed; |
154 | }); | 157 | }); |
155 | 158 | ||
159 | + const getMixSideWidth = computed(() => { | ||
160 | + return unref(getCollapsed) ? SIDE_BAR_MINI_WIDTH : SIDE_BAR_SHOW_TIT_MINI_WIDTH; | ||
161 | + }); | ||
162 | + | ||
156 | const getDomStyle = computed( | 163 | const getDomStyle = computed( |
157 | (): CSSProperties => { | 164 | (): CSSProperties => { |
158 | const fixedWidth = unref(getIsFixed) ? unref(getRealWidth) : 0; | 165 | const fixedWidth = unref(getIsFixed) ? unref(getRealWidth) : 0; |
159 | - const width = `${SIDE_BAR_SHOW_TIT_MINI_WIDTH + fixedWidth}px`; | ||
160 | - return { | ||
161 | - width, | ||
162 | - maxWidth: width, | ||
163 | - minWidth: width, | ||
164 | - flex: `0 0 ${width}`, | ||
165 | - }; | 166 | + const width = `${unref(getMixSideWidth) + fixedWidth}px`; |
167 | + return getWrapCommonStyle(width); | ||
168 | + } | ||
169 | + ); | ||
170 | + | ||
171 | + const getWrapStyle = computed( | ||
172 | + (): CSSProperties => { | ||
173 | + const width = `${unref(getMixSideWidth)}px`; | ||
174 | + return getWrapCommonStyle(width); | ||
166 | } | 175 | } |
167 | ); | 176 | ); |
168 | 177 | ||
169 | const getMenuEvents = computed(() => { | 178 | const getMenuEvents = computed(() => { |
170 | - // return unref(getMixSideTrigger) === 'hover' | ||
171 | - // ? { | ||
172 | - // onMouseleave: () => { | ||
173 | - // closeMenu(); | ||
174 | - // }, | ||
175 | - // } | ||
176 | - // : {}; | ||
177 | - return { | ||
178 | - onMouseleave: () => { | ||
179 | - closeMenu(); | ||
180 | - }, | ||
181 | - }; | 179 | + return !unref(getMixSideFixed) |
180 | + ? { | ||
181 | + onMouseleave: () => { | ||
182 | + closeMenu(); | ||
183 | + }, | ||
184 | + } | ||
185 | + : {}; | ||
182 | }); | 186 | }); |
183 | 187 | ||
184 | const getShowDragBar = computed(() => unref(getCanDrag)); | 188 | const getShowDragBar = computed(() => unref(getCanDrag)); |
@@ -195,6 +199,16 @@ | @@ -195,6 +199,16 @@ | ||
195 | } | 199 | } |
196 | }); | 200 | }); |
197 | 201 | ||
202 | + function getWrapCommonStyle(width: string): CSSProperties { | ||
203 | + return { | ||
204 | + width, | ||
205 | + maxWidth: width, | ||
206 | + minWidth: width, | ||
207 | + flex: `0 0 ${width}`, | ||
208 | + }; | ||
209 | + } | ||
210 | + | ||
211 | + // Process module menu click | ||
198 | async function hanldeModuleClick(path: string, hover = false) { | 212 | async function hanldeModuleClick(path: string, hover = false) { |
199 | const children = await getChildrenMenus(path); | 213 | const children = await getChildrenMenus(path); |
200 | 214 | ||
@@ -223,20 +237,24 @@ | @@ -223,20 +237,24 @@ | ||
223 | chilrenMenus.value = children; | 237 | chilrenMenus.value = children; |
224 | } | 238 | } |
225 | 239 | ||
240 | + // Set the currently active menu and submenu | ||
226 | async function setActive(setChildren = false) { | 241 | async function setActive(setChildren = false) { |
227 | const path = currentRoute.value?.path; | 242 | const path = currentRoute.value?.path; |
228 | if (!path) return; | 243 | if (!path) return; |
229 | const parentPath = await getCurrentParentPath(path); | 244 | const parentPath = await getCurrentParentPath(path); |
230 | activePath.value = parentPath; | 245 | activePath.value = parentPath; |
231 | // hanldeModuleClick(parentPath); | 246 | // hanldeModuleClick(parentPath); |
232 | - if (unref(getMixSideFixed)) { | 247 | + if (unref(getIsMixSidebar)) { |
233 | const activeMenu = unref(menuModules).find((item) => item.path === unref(activePath)); | 248 | const activeMenu = unref(menuModules).find((item) => item.path === unref(activePath)); |
234 | const p = activeMenu?.path; | 249 | const p = activeMenu?.path; |
235 | if (p) { | 250 | if (p) { |
236 | const children = await getChildrenMenus(p); | 251 | const children = await getChildrenMenus(p); |
237 | if (setChildren) { | 252 | if (setChildren) { |
238 | chilrenMenus.value = children; | 253 | chilrenMenus.value = children; |
239 | - openMenu.value = children.length > 0; | 254 | + |
255 | + if (unref(getMixSideFixed)) { | ||
256 | + openMenu.value = children.length > 0; | ||
257 | + } | ||
240 | } | 258 | } |
241 | if (children.length === 0) { | 259 | if (children.length === 0) { |
242 | chilrenMenus.value = []; | 260 | chilrenMenus.value = []; |
@@ -271,6 +289,7 @@ | @@ -271,6 +289,7 @@ | ||
271 | }); | 289 | }); |
272 | } | 290 | } |
273 | 291 | ||
292 | + // Close menu | ||
274 | function closeMenu() { | 293 | function closeMenu() { |
275 | if (!unref(getIsFixed)) { | 294 | if (!unref(getIsFixed)) { |
276 | openMenu.value = false; | 295 | openMenu.value = false; |
@@ -298,6 +317,8 @@ | @@ -298,6 +317,8 @@ | ||
298 | getDomStyle, | 317 | getDomStyle, |
299 | handleFixedMenu, | 318 | handleFixedMenu, |
300 | getMixSideFixed, | 319 | getMixSideFixed, |
320 | + getWrapStyle, | ||
321 | + getCollapsed, | ||
301 | }; | 322 | }; |
302 | }, | 323 | }, |
303 | }); | 324 | }); |
@@ -312,14 +333,10 @@ | @@ -312,14 +333,10 @@ | ||
312 | top: 0; | 333 | top: 0; |
313 | left: 0; | 334 | left: 0; |
314 | z-index: @layout-mix-sider-fixed-z-index; | 335 | z-index: @layout-mix-sider-fixed-z-index; |
315 | - width: @width; | ||
316 | height: 100%; | 336 | height: 100%; |
317 | - max-width: @width; | ||
318 | - min-width: @width; | ||
319 | overflow: hidden; | 337 | overflow: hidden; |
320 | background: @sider-dark-bg-color; | 338 | background: @sider-dark-bg-color; |
321 | - transition: all 0.3s ease 0s; | ||
322 | - flex: 0 0 @width; | 339 | + transition: all 0.2s ease 0s; |
323 | .@{tag-prefix-cls} { | 340 | .@{tag-prefix-cls} { |
324 | position: absolute; | 341 | position: absolute; |
325 | top: 6px; | 342 | top: 6px; |
@@ -327,13 +344,9 @@ | @@ -327,13 +344,9 @@ | ||
327 | } | 344 | } |
328 | 345 | ||
329 | &-dom { | 346 | &-dom { |
330 | - width: @width; | ||
331 | height: 100%; | 347 | height: 100%; |
332 | - max-width: @width; | ||
333 | - min-width: @width; | ||
334 | overflow: hidden; | 348 | overflow: hidden; |
335 | transition: all 0.2s ease 0s; | 349 | transition: all 0.2s ease 0s; |
336 | - flex: 0 0 @width; | ||
337 | } | 350 | } |
338 | 351 | ||
339 | &-logo { | 352 | &-logo { |
@@ -354,7 +367,7 @@ | @@ -354,7 +367,7 @@ | ||
354 | } | 367 | } |
355 | 368 | ||
356 | &.open { | 369 | &.open { |
357 | - > .scroll-container { | 370 | + > .scrollbar { |
358 | border-right: 1px solid rgb(238, 238, 238); | 371 | border-right: 1px solid rgb(238, 238, 238); |
359 | } | 372 | } |
360 | } | 373 | } |
@@ -390,7 +403,7 @@ | @@ -390,7 +403,7 @@ | ||
390 | border-bottom: 1px solid @border-color; | 403 | border-bottom: 1px solid @border-color; |
391 | } | 404 | } |
392 | 405 | ||
393 | - > .scroll-container { | 406 | + > .scrollbar { |
394 | border-right: 1px solid @border-color; | 407 | border-right: 1px solid @border-color; |
395 | } | 408 | } |
396 | } | 409 | } |
@@ -409,6 +422,16 @@ | @@ -409,6 +422,16 @@ | ||
409 | height: calc(100% - @header-height) !important; | 422 | height: calc(100% - @header-height) !important; |
410 | } | 423 | } |
411 | 424 | ||
425 | + &.mini &-module { | ||
426 | + &__name { | ||
427 | + display: none; | ||
428 | + } | ||
429 | + | ||
430 | + &__icon { | ||
431 | + margin-bottom: 0; | ||
432 | + } | ||
433 | + } | ||
434 | + | ||
412 | &-module { | 435 | &-module { |
413 | position: relative; | 436 | position: relative; |
414 | padding-top: 1px; | 437 | padding-top: 1px; |
@@ -456,7 +479,6 @@ | @@ -456,7 +479,6 @@ | ||
456 | &-menu-list { | 479 | &-menu-list { |
457 | position: fixed; | 480 | position: fixed; |
458 | top: 0; | 481 | top: 0; |
459 | - left: 80px; | ||
460 | width: 0; | 482 | width: 0; |
461 | width: 200px; | 483 | width: 200px; |
462 | height: calc(100%); | 484 | height: calc(100%); |
src/layouts/default/tabs/components/FoldButton.vue
0 → 100644
1 | +<template> | ||
2 | + <span :class="`${prefixCls}__extra-fold`" @click="handleFold"> | ||
3 | + <Icon :icon="getIcon" /> | ||
4 | + </span> | ||
5 | +</template> | ||
6 | +<script lang="ts"> | ||
7 | + import { defineComponent, unref, computed } from 'vue'; | ||
8 | + import { RedoOutlined } from '@ant-design/icons-vue'; | ||
9 | + import { useDesign } from '/@/hooks/web/useDesign'; | ||
10 | + import { Tooltip } from 'ant-design-vue'; | ||
11 | + import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; | ||
12 | + import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
13 | + | ||
14 | + import Icon from '/@/components/Icon'; | ||
15 | + | ||
16 | + export default defineComponent({ | ||
17 | + name: 'FoldButton', | ||
18 | + components: { RedoOutlined, Tooltip, Icon }, | ||
19 | + | ||
20 | + setup() { | ||
21 | + const { prefixCls } = useDesign('multiple-tabs-content'); | ||
22 | + const { getShowMenu, setMenuSetting } = useMenuSetting(); | ||
23 | + const { getShowHeader, setHeaderSetting } = useHeaderSetting(); | ||
24 | + | ||
25 | + const getIsUnFold = computed(() => { | ||
26 | + return !unref(getShowMenu) && !unref(getShowHeader); | ||
27 | + }); | ||
28 | + | ||
29 | + const getIcon = computed(() => { | ||
30 | + return unref(getIsUnFold) ? 'codicon:screen-normal' : 'codicon:screen-full'; | ||
31 | + }); | ||
32 | + | ||
33 | + function handleFold() { | ||
34 | + const isScale = !unref(getShowMenu) && !unref(getShowHeader); | ||
35 | + setMenuSetting({ | ||
36 | + show: isScale, | ||
37 | + hidden: !isScale, | ||
38 | + }); | ||
39 | + setHeaderSetting({ | ||
40 | + show: isScale, | ||
41 | + }); | ||
42 | + } | ||
43 | + | ||
44 | + return { prefixCls, getIcon, handleFold }; | ||
45 | + }, | ||
46 | + }); | ||
47 | +</script> |
src/layouts/default/tabs/index.less
@@ -153,7 +153,8 @@ | @@ -153,7 +153,8 @@ | ||
153 | 153 | ||
154 | &-content { | 154 | &-content { |
155 | &__extra-quick, | 155 | &__extra-quick, |
156 | - &__extra-redo { | 156 | + &__extra-redo, |
157 | + &__extra-fold { | ||
157 | display: inline-block; | 158 | display: inline-block; |
158 | width: 36px; | 159 | width: 36px; |
159 | height: @multiple-height; | 160 | height: @multiple-height; |
src/layouts/default/tabs/index.vue
@@ -21,6 +21,7 @@ | @@ -21,6 +21,7 @@ | ||
21 | <template #tabBarExtraContent v-if="getShowRedo || getShowQuick"> | 21 | <template #tabBarExtraContent v-if="getShowRedo || getShowQuick"> |
22 | <TabRedo v-if="getShowRedo" /> | 22 | <TabRedo v-if="getShowRedo" /> |
23 | <QuickButton v-if="getShowQuick" /> | 23 | <QuickButton v-if="getShowQuick" /> |
24 | + <FoldButton v-if="getShowFold" /> | ||
24 | </template> | 25 | </template> |
25 | </Tabs> | 26 | </Tabs> |
26 | </div> | 27 | </div> |
@@ -51,6 +52,7 @@ | @@ -51,6 +52,7 @@ | ||
51 | components: { | 52 | components: { |
52 | QuickButton: createAsyncComponent(() => import('./components/QuickButton.vue')), | 53 | QuickButton: createAsyncComponent(() => import('./components/QuickButton.vue')), |
53 | TabRedo: createAsyncComponent(() => import('./components/TabRedo.vue')), | 54 | TabRedo: createAsyncComponent(() => import('./components/TabRedo.vue')), |
55 | + FoldButton: createAsyncComponent(() => import('./components/FoldButton.vue')), | ||
54 | Tabs, | 56 | Tabs, |
55 | TabPane: Tabs.TabPane, | 57 | TabPane: Tabs.TabPane, |
56 | TabContent, | 58 | TabContent, |
@@ -62,7 +64,7 @@ | @@ -62,7 +64,7 @@ | ||
62 | useTabsDrag(affixTextList); | 64 | useTabsDrag(affixTextList); |
63 | const { prefixCls } = useDesign('multiple-tabs'); | 65 | const { prefixCls } = useDesign('multiple-tabs'); |
64 | const go = useGo(); | 66 | const go = useGo(); |
65 | - const { getShowQuick, getShowRedo } = useMultipleTabSetting(); | 67 | + const { getShowQuick, getShowRedo, getShowFold } = useMultipleTabSetting(); |
66 | 68 | ||
67 | const getTabsState = computed(() => { | 69 | const getTabsState = computed(() => { |
68 | return tabStore.getTabsState.filter((item) => !item.meta?.hideTab); | 70 | return tabStore.getTabsState.filter((item) => !item.meta?.hideTab); |
@@ -125,6 +127,7 @@ | @@ -125,6 +127,7 @@ | ||
125 | getTabsState, | 127 | getTabsState, |
126 | getShowQuick, | 128 | getShowQuick, |
127 | getShowRedo, | 129 | getShowRedo, |
130 | + getShowFold, | ||
128 | }; | 131 | }; |
129 | }, | 132 | }, |
130 | }); | 133 | }); |
src/layouts/default/tabs/useTabDropdown.ts
@@ -8,8 +8,6 @@ import router from '/@/router'; | @@ -8,8 +8,6 @@ import router from '/@/router'; | ||
8 | import { RouteLocationNormalized } from 'vue-router'; | 8 | import { RouteLocationNormalized } from 'vue-router'; |
9 | import { useTabs } from '/@/hooks/web/useTabs'; | 9 | import { useTabs } from '/@/hooks/web/useTabs'; |
10 | import { useI18n } from '/@/hooks/web/useI18n'; | 10 | import { useI18n } from '/@/hooks/web/useI18n'; |
11 | -import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; | ||
12 | -import { useMenuSetting } from '/@/hooks/setting/useMenuSetting'; | ||
13 | 11 | ||
14 | const { t } = useI18n(); | 12 | const { t } = useI18n(); |
15 | 13 | ||
@@ -21,9 +19,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -21,9 +19,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
21 | 19 | ||
22 | const { currentRoute } = router; | 20 | const { currentRoute } = router; |
23 | 21 | ||
24 | - const { getShowMenu, setMenuSetting } = useMenuSetting(); | ||
25 | - const { getShowHeader, setHeaderSetting } = useHeaderSetting(); | ||
26 | - | ||
27 | const isTabs = computed(() => tabContentProps.type === TabContentEnum.TAB_TYPE); | 22 | const isTabs = computed(() => tabContentProps.type === TabContentEnum.TAB_TYPE); |
28 | 23 | ||
29 | const getCurrentTab = computed( | 24 | const getCurrentTab = computed( |
@@ -32,10 +27,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -32,10 +27,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
32 | } | 27 | } |
33 | ); | 28 | ); |
34 | 29 | ||
35 | - const getIsScale = computed(() => { | ||
36 | - return !unref(getShowMenu) && !unref(getShowHeader); | ||
37 | - }); | ||
38 | - | ||
39 | /** | 30 | /** |
40 | * @description: drop-down list | 31 | * @description: drop-down list |
41 | */ | 32 | */ |
@@ -98,16 +89,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -98,16 +89,6 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
98 | }, | 89 | }, |
99 | ]; | 90 | ]; |
100 | 91 | ||
101 | - if (!unref(isTabs)) { | ||
102 | - const isScale = unref(getIsScale); | ||
103 | - dropMenuList.unshift({ | ||
104 | - icon: isScale ? 'codicon:screen-normal' : 'codicon:screen-full', | ||
105 | - event: MenuEventEnum.SCALE, | ||
106 | - text: isScale ? t('layout.multipleTab.putAway') : t('layout.multipleTab.unfold'), | ||
107 | - disabled: false, | ||
108 | - }); | ||
109 | - } | ||
110 | - | ||
111 | return dropMenuList; | 92 | return dropMenuList; |
112 | }); | 93 | }); |
113 | 94 | ||
@@ -125,20 +106,9 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -125,20 +106,9 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
125 | }; | 106 | }; |
126 | } | 107 | } |
127 | 108 | ||
128 | - function scaleScreen() { | ||
129 | - const isScale = !unref(getShowMenu) && !unref(getShowHeader); | ||
130 | - setMenuSetting({ | ||
131 | - show: isScale, | ||
132 | - hidden: !isScale, | ||
133 | - }); | ||
134 | - setHeaderSetting({ | ||
135 | - show: isScale, | ||
136 | - }); | ||
137 | - } | ||
138 | - | ||
139 | // Handle right click event | 109 | // Handle right click event |
140 | function handleMenuEvent(menu: DropMenu): void { | 110 | function handleMenuEvent(menu: DropMenu): void { |
141 | - const { refreshPage, closeAll, closeCurrent, closeLeft, closeOther, closeRight } = useTabs(); | 111 | + const { refreshPage, closeAll, close, closeLeft, closeOther, closeRight } = useTabs(); |
142 | const { event } = menu; | 112 | const { event } = menu; |
143 | switch (event) { | 113 | switch (event) { |
144 | case MenuEventEnum.SCALE: | 114 | case MenuEventEnum.SCALE: |
@@ -150,7 +120,7 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | @@ -150,7 +120,7 @@ export function useTabDropdown(tabContentProps: TabContentProps) { | ||
150 | break; | 120 | break; |
151 | // Close current | 121 | // Close current |
152 | case MenuEventEnum.CLOSE_CURRENT: | 122 | case MenuEventEnum.CLOSE_CURRENT: |
153 | - closeCurrent(); | 123 | + close(tabContentProps.tabItem); |
154 | break; | 124 | break; |
155 | // Close left | 125 | // Close left |
156 | case MenuEventEnum.CLOSE_LEFT: | 126 | case MenuEventEnum.CLOSE_LEFT: |
src/locales/lang/en/layout/multipleTab.ts
@@ -5,7 +5,5 @@ export default { | @@ -5,7 +5,5 @@ export default { | ||
5 | closeRight: 'Close Right', | 5 | closeRight: 'Close Right', |
6 | closeOther: 'Close Other', | 6 | closeOther: 'Close Other', |
7 | closeAll: 'Close All', | 7 | closeAll: 'Close All', |
8 | - putAway: 'PutAway', | ||
9 | - unfold: 'Unfold', | ||
10 | tooltipRedo: 'Refresh', | 8 | tooltipRedo: 'Refresh', |
11 | }; | 9 | }; |
src/locales/lang/en/layout/setting.ts
@@ -56,6 +56,7 @@ export default { | @@ -56,6 +56,7 @@ export default { | ||
56 | tabs: 'Tabs', | 56 | tabs: 'Tabs', |
57 | tabsQuickBtn: 'Tabs quick button', | 57 | tabsQuickBtn: 'Tabs quick button', |
58 | tabsRedoBtn: 'Tabs redo button', | 58 | tabsRedoBtn: 'Tabs redo button', |
59 | + tabsFoldBtn: 'Tabs flod button', | ||
59 | sidebar: 'Sidebar', | 60 | sidebar: 'Sidebar', |
60 | header: 'Header', | 61 | header: 'Header', |
61 | footer: 'Footer', | 62 | footer: 'Footer', |
src/locales/lang/zh_CN/layout/multipleTab.ts
1 | export default { | 1 | export default { |
2 | - redo: '刷新当前', | ||
3 | - close: '关闭当前', | ||
4 | - closeLeft: '关闭左侧', | ||
5 | - closeRight: '关闭右侧', | ||
6 | - closeOther: '关闭其他', | ||
7 | - closeAll: '关闭全部', | ||
8 | - putAway: '收起', | ||
9 | - unfold: '展开', | 2 | + redo: '重新加载', |
3 | + close: '关闭标签页', | ||
4 | + closeLeft: '关闭左侧标签页', | ||
5 | + closeRight: '关闭右侧标签页', | ||
6 | + closeOther: '关闭其它标签页', | ||
7 | + closeAll: '关闭全部标签页', | ||
10 | tooltipRedo: '刷新', | 8 | tooltipRedo: '刷新', |
11 | }; | 9 | }; |
src/locales/lang/zh_CN/layout/setting.ts
@@ -55,6 +55,7 @@ export default { | @@ -55,6 +55,7 @@ export default { | ||
55 | tabs: '标签页', | 55 | tabs: '标签页', |
56 | tabsQuickBtn: '标签页快捷按钮', | 56 | tabsQuickBtn: '标签页快捷按钮', |
57 | tabsRedoBtn: '标签页刷新按钮', | 57 | tabsRedoBtn: '标签页刷新按钮', |
58 | + tabsFoldBtn: '标签页折叠按钮', | ||
58 | sidebar: '左侧菜单', | 59 | sidebar: '左侧菜单', |
59 | header: '顶栏', | 60 | header: '顶栏', |
60 | footer: '页脚', | 61 | footer: '页脚', |
src/settings/componentSetting.ts
0 → 100644
1 | +// Used to configure the general configuration of some components without modifying the components | ||
2 | + | ||
3 | +import type { SorterResult } from '../components/Table'; | ||
4 | + | ||
5 | +export default { | ||
6 | + // basic-table setting | ||
7 | + table: { | ||
8 | + // Form interface request general configuration | ||
9 | + // support xxx.xxx.xxx | ||
10 | + fetchSetting: { | ||
11 | + // The field name of the current page passed to the background | ||
12 | + pageField: 'page', | ||
13 | + // The number field name of each page displayed in the background | ||
14 | + sizeField: 'pageSize', | ||
15 | + // Field name of the form data returned by the interface | ||
16 | + listField: 'items', | ||
17 | + // Total number of tables returned by the interface field name | ||
18 | + totalField: 'total', | ||
19 | + }, | ||
20 | + // Number of pages that can be selected | ||
21 | + pageSizeOptions: ['10', '50', '80', '100'], | ||
22 | + // Default display quantity on one page | ||
23 | + defaultPageSize: 10, | ||
24 | + // Custom general sort function | ||
25 | + defaultSortFn: (sortInfo: SorterResult) => { | ||
26 | + const { field, order } = sortInfo; | ||
27 | + return { | ||
28 | + // The sort field passed to the backend you | ||
29 | + field, | ||
30 | + // Sorting method passed to the background asc/desc | ||
31 | + order, | ||
32 | + }; | ||
33 | + }, | ||
34 | + // Custom general filter function | ||
35 | + defaultFilterFn: (data: Partial<Recordable<string[]>>) => { | ||
36 | + return data; | ||
37 | + }, | ||
38 | + }, | ||
39 | + // scrollbar setting | ||
40 | + scrollbar: { | ||
41 | + // Whether to use native scroll bar | ||
42 | + // After opening, the menu, modal, drawer will change the pop-up scroll bar to native | ||
43 | + native: false, | ||
44 | + }, | ||
45 | +}; |
src/settings/encryptionSetting.ts
@@ -5,8 +5,8 @@ export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7; | @@ -5,8 +5,8 @@ export const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7; | ||
5 | 5 | ||
6 | // aes encryption key | 6 | // aes encryption key |
7 | export const cacheCipher = { | 7 | export const cacheCipher = { |
8 | - key: '_12345678901234@', | ||
9 | - iv: '@12345678901234_', | 8 | + key: '_11111000001111@', |
9 | + iv: '@11111000001111_', | ||
10 | }; | 10 | }; |
11 | 11 | ||
12 | // Whether the system cache is encrypted using aes | 12 | // Whether the system cache is encrypted using aes |
src/settings/projectSetting.ts
@@ -125,6 +125,8 @@ const setting: ProjectConfig = { | @@ -125,6 +125,8 @@ const setting: ProjectConfig = { | ||
125 | 125 | ||
126 | // Whether to show the refresh button | 126 | // Whether to show the refresh button |
127 | showRedo: true, | 127 | showRedo: true, |
128 | + // Whether to show the collapse button | ||
129 | + showFold: true, | ||
128 | }, | 130 | }, |
129 | 131 | ||
130 | // Transition Setting | 132 | // Transition Setting |
src/types/config.d.ts
@@ -33,6 +33,9 @@ export interface MultiTabsSetting { | @@ -33,6 +33,9 @@ export interface MultiTabsSetting { | ||
33 | 33 | ||
34 | // 显示刷新按钮 | 34 | // 显示刷新按钮 |
35 | showRedo: boolean; | 35 | showRedo: boolean; |
36 | + | ||
37 | + // 显示折叠按钮 | ||
38 | + showFold: boolean; | ||
36 | } | 39 | } |
37 | 40 | ||
38 | export interface HeaderSetting { | 41 | export interface HeaderSetting { |
src/views/demo/page/desc/high/index.vue
1 | <template> | 1 | <template> |
2 | <PageWrapper title="单号:234231029431" contentBackgrond> | 2 | <PageWrapper title="单号:234231029431" contentBackgrond> |
3 | <template #extra> | 3 | <template #extra> |
4 | - <a-button key="3"> 操作一 </a-button> | ||
5 | - <a-button key="2"> 操作二 </a-button> | ||
6 | - <a-button key="1" type="primary"> 主操作 </a-button> | 4 | + <a-button> 操作一 </a-button> |
5 | + <a-button> 操作二 </a-button> | ||
6 | + <a-button type="primary"> 主操作 </a-button> | ||
7 | </template> | 7 | </template> |
8 | 8 | ||
9 | <template #footer> | 9 | <template #footer> |