vben
authored
|
1
2
|
import './index.less';
|
vben
authored
|
3
|
import type { FunctionalComponent } from 'vue';
|
vben
authored
|
4
|
import type { Component } from '/@/components/types';
|
vben
authored
|
5
|
|
vben
authored
|
6
7
8
9
10
|
import {
defineComponent,
unref,
computed,
ref,
|
vben
authored
|
11
12
|
nextTick,
watchEffect,
|
vben
authored
|
13
14
|
// nextTick
} from 'vue';
|
vben
authored
|
15
|
|
vben
authored
|
16
|
import { Layout, Tooltip, Badge } from 'ant-design-vue';
|
vben
authored
|
17
|
import { AppLogo } from '/@/components/Application';
|
|
18
|
import UserDropdown from './UserDropdown';
|
vben
authored
|
19
|
import LayoutMenu from '../menu';
|
vben
authored
|
20
|
import LayoutBreadcrumb from './LayoutBreadcrumb.vue';
|
vben
authored
|
21
|
import LockAction from './actions/LockAction';
|
vben
authored
|
22
23
|
import LayoutTrigger from '../LayoutTrigger';
import NoticeAction from './notice/NoticeActionItem.vue';
|
|
24
25
26
27
28
|
import {
RedoOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
LockOutlined,
|
vben
authored
|
29
|
BugOutlined,
|
|
30
|
} from '@ant-design/icons-vue';
|
vben
authored
|
31
32
|
import { AppSearch } from '/@/components/Application';
|
vben
authored
|
33
|
import { useModal } from '/@/components/Modal';
|
vben
authored
|
34
|
|
|
35
36
|
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
|
vben
authored
|
37
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
vben
authored
|
38
39
40
|
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
vben
authored
|
41
|
import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
|
vben
authored
|
42
|
|
vben
authored
|
43
|
import { useRouter } from 'vue-router';
|
vben
authored
|
44
45
46
|
import { errorStore } from '/@/store/modules/error';
|
vben
authored
|
47
48
|
import { PageEnum } from '/@/enums/pageEnum';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
vben
authored
|
49
50
|
import { AppLocalePicker } from '/@/components/Application';
import { useI18n } from '/@/hooks/web/useI18n';
|
vben
authored
|
51
|
import { propTypes } from '/@/utils/propTypes';
|
vben
authored
|
52
|
import { useLayoutContext } from '../useLayoutContext';
|
vben
authored
|
53
|
|
vben
authored
|
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
interface TooltipItemProps {
title: string;
}
const TooltipItem: FunctionalComponent<TooltipItemProps> = (props, { slots }) => {
return (
<Tooltip>
{{
title: () => props.title,
default: () => slots.default?.(),
}}
</Tooltip>
);
};
|
|
69
|
export default defineComponent({
|
vben
authored
|
70
|
name: 'LayoutHeader',
|
vben
authored
|
71
|
props: {
|
vben
authored
|
72
|
fixed: propTypes.bool,
|
vben
authored
|
73
74
|
},
setup(props) {
|
vben
authored
|
75
|
let logoEl: Element | null | undefined;
|
vben
authored
|
76
|
|
vben
authored
|
77
|
const logoWidthRef = ref(200);
|
vben
authored
|
78
|
const logoRef = ref<ComponentRef>(null);
|
vben
authored
|
79
80
81
|
const injectValue = useLayoutContext();
|
vben
authored
|
82
|
const { refreshPage } = useTabs();
|
vben
authored
|
83
|
const { t } = useI18n();
|
vben
authored
|
84
|
|
vben
authored
|
85
|
const { getShowTopMenu, getShowHeaderTrigger, getSplit, getIsHorizontal } = useMenuSetting();
|
vben
authored
|
86
|
|
vben
authored
|
87
|
const { getShowLocale } = useLocaleSetting();
|
vben
authored
|
88
89
90
|
const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();
const {
|
vben
authored
|
91
|
getHeaderTheme,
|
vben
authored
|
92
93
94
95
96
97
98
99
100
|
getShowRedo,
getUseLockPage,
getShowFullScreen,
getShowNotice,
getShowContent,
getShowBread,
getShowHeaderLogo,
} = useHeaderSetting();
|
vben
authored
|
101
|
const { push } = useRouter();
|
|
102
103
|
const [register, { openModal }] = useModal();
const { toggleFullscreen, isFullscreenRef } = useFullscreen();
|
vben
authored
|
104
|
|
vben
authored
|
105
106
107
108
109
110
111
|
useWindowSizeFn(
() => {
calcTopMenuWidth();
},
100,
{ immediate: false }
);
|
|
112
113
|
const headerClass = computed(() => {
|
vben
authored
|
114
|
const theme = unref(getHeaderTheme);
|
|
115
116
|
return theme ? `layout-header__header--${theme}` : '';
});
|
vben
authored
|
117
|
|
vben
authored
|
118
119
120
121
|
const isPc = computed(() => {
return !unref(injectValue.isMobile);
});
|
vben
authored
|
122
123
124
125
126
127
|
const getSplitType = computed(() => {
return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
});
const getMenuMode = computed(() => {
return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
|
vben
authored
|
128
129
|
});
|
vben
authored
|
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
watchEffect(() => {
if (unref(getIsHorizontal)) {
calcTopMenuWidth();
}
});
function calcTopMenuWidth() {
nextTick(() => {
if (!unref(getShowTopMenu)) return;
let width = 0;
if (!logoEl) {
logoEl = unref(logoRef)?.$el;
}
if (!logoEl) return;
width += logoEl.clientWidth;
logoWidthRef.value = width + 80;
});
}
|
vben
authored
|
149
|
function handleToErrorList() {
|
vben
authored
|
150
151
152
|
push(PageEnum.ERROR_LOG_PAGE).then(() => {
errorStore.commitErrorListCountState(0);
});
|
vben
authored
|
153
154
|
}
|
|
155
156
157
|
function handleLockPage() {
openModal(true);
}
|
vben
authored
|
158
|
|
vben
authored
|
159
|
function renderHeaderContent() {
|
vben
authored
|
160
|
const width = unref(logoWidthRef);
|
vben
authored
|
161
162
163
|
return (
<div class="layout-header__content ">
{unref(getShowHeaderLogo) && (
|
vben
authored
|
164
|
<AppLogo class={`layout-header__logo`} ref={logoRef} theme={unref(getHeaderTheme)} />
|
vben
authored
|
165
|
)}
|
|
166
|
|
vben
authored
|
167
168
169
|
{unref(getShowContent) && (
<div class="layout-header__left">
{unref(getShowHeaderTrigger) && (
|
vben
authored
|
170
|
<LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
|
vben
authored
|
171
|
)}
|
vben
authored
|
172
173
174
|
{unref(getShowBread) && unref(isPc) && (
<LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />
)}
|
vben
authored
|
175
176
|
</div>
)}
|
vben
authored
|
177
|
|
vben
authored
|
178
|
{unref(getShowTopMenu) && unref(isPc) && (
|
vben
authored
|
179
180
|
<div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
{/* <div class={[`layout-header__menu `]}> */}
|
vben
authored
|
181
182
|
<LayoutMenu
isHorizontal={true}
|
vben
authored
|
183
|
// class={`justify-${unref(getTopMenuAlign)}`}
|
vben
authored
|
184
|
theme={unref(getHeaderTheme)}
|
vben
authored
|
185
186
187
188
189
190
191
192
|
splitType={unref(getSplitType)}
menuMode={unref(getMenuMode)}
/>
</div>
)}
</div>
);
}
|
vben
authored
|
193
|
|
vben
authored
|
194
|
function renderActionDefault(Comp: Component | any, event: Fn) {
|
|
195
|
return (
|
vben
authored
|
196
197
|
<div class="layout-header__action-item" onClick={event}>
<Comp class="layout-header__action-icon" />
|
vben
authored
|
198
199
200
|
</div>
);
}
|
vben
authored
|
201
|
|
vben
authored
|
202
203
204
|
function renderAction() {
return (
<div class={`layout-header__action`}>
|
vben
authored
|
205
206
|
{unref(isPc) && <AppSearch class="layout-header__action-item" />}
|
vben
authored
|
207
|
{unref(getUseErrorHandle) && unref(isPc) && (
|
vben
authored
|
208
|
<TooltipItem title={t('layout.header.tooltipErrorLog')}>
|
vben
authored
|
209
210
211
212
213
214
215
216
217
218
219
|
{() => (
<Badge
count={errorStore.getErrorListCountState}
offset={[0, 10]}
dot
overflowCount={99}
>
{() => renderActionDefault(BugOutlined, handleToErrorList)}
</Badge>
)}
</TooltipItem>
|
vben
authored
|
220
|
)}
|
|
221
|
|
vben
authored
|
222
|
{unref(getUseLockPage) && unref(isPc) && (
|
vben
authored
|
223
|
<TooltipItem title={t('layout.header.tooltipLock')}>
|
vben
authored
|
224
225
|
{() => renderActionDefault(LockOutlined, handleLockPage)}
</TooltipItem>
|
vben
authored
|
226
227
|
)}
|
vben
authored
|
228
|
{unref(getShowNotice) && unref(isPc) && (
|
vben
authored
|
229
230
231
|
<TooltipItem title={t('layout.header.tooltipNotify')}>
{() => <NoticeAction />}
</TooltipItem>
|
vben
authored
|
232
|
)}
|
vben
authored
|
233
|
|
vben
authored
|
234
|
{unref(getShowRedo) && unref(isPc) && (
|
vben
authored
|
235
|
<TooltipItem title={t('layout.header.tooltipRedo')}>
|
vben
authored
|
236
237
|
{() => renderActionDefault(RedoOutlined, refreshPage)}
</TooltipItem>
|
|
238
|
)}
|
vben
authored
|
239
|
|
vben
authored
|
240
|
{unref(getShowFullScreen) && unref(isPc) && (
|
vben
authored
|
241
242
243
244
245
246
247
|
<TooltipItem
title={
unref(isFullscreenRef)
? t('layout.header.tooltipExitFull')
: t('layout.header.tooltipEntryFull')
}
>
|
vben
authored
|
248
249
250
251
252
253
254
|
{() => {
const Icon = !unref(isFullscreenRef) ? (
<FullscreenOutlined />
) : (
<FullscreenExitOutlined />
);
return renderActionDefault(Icon, toggleFullscreen);
|
vben
authored
|
255
|
}}
|
vben
authored
|
256
|
</TooltipItem>
|
vben
authored
|
257
|
)}
|
vben
authored
|
258
259
260
261
262
263
264
265
|
<UserDropdown class="layout-header__user-dropdown" />
{unref(getShowLocale) && (
<AppLocalePicker
reload={true}
showText={false}
class="layout-header__action-item locale"
/>
)}
|
vben
authored
|
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
|
</div>
);
}
function renderHeaderDefault() {
return (
<>
{renderHeaderContent()}
{renderAction()}
<LockAction onRegister={register} />
</>
);
}
return () => {
return (
|
vben
authored
|
282
283
284
|
<Layout.Header
class={['layout-header', 'flex p-0 px-4 ', unref(headerClass), { fixed: props.fixed }]}
>
|
vben
authored
|
285
|
{() => renderHeaderDefault()}
|
|
286
287
288
289
290
|
</Layout.Header>
);
};
},
});
|