Blame view

src/layouts/default/header/LayoutHeader.tsx 7.64 KB
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
11
12
import {
  defineComponent,
  unref,
  computed,
  ref,
  // nextTick
} from 'vue';
13
vben authored
14
import { Layout, Tooltip, Badge } from 'ant-design-vue';
vben authored
15
import { AppLogo } from '/@/components/Application';
陈文彬 authored
16
import UserDropdown from './UserDropdown';
vben authored
17
import LayoutMenu from '../menu';
vben authored
18
import LayoutBreadcrumb from './LayoutBreadcrumb.vue';
vben authored
19
import LockAction from '../lock/LockAction';
vben authored
20
21
import LayoutTrigger from '../LayoutTrigger';
import NoticeAction from './notice/NoticeActionItem.vue';
陈文彬 authored
22
23
24
25
26
import {
  RedoOutlined,
  FullscreenExitOutlined,
  FullscreenOutlined,
  LockOutlined,
vben authored
27
  BugOutlined,
陈文彬 authored
28
} from '@ant-design/icons-vue';
vben authored
29
import { useModal } from '/@/components/Modal';
30
陈文彬 authored
31
32
import { useFullscreen } from '/@/hooks/web/useFullScreen';
import { useTabs } from '/@/hooks/web/useTabs';
vben authored
33
// import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
vben authored
34
35
36
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
vben authored
37
import { useLocaleSetting } from '/@/hooks/setting/useLocaleSetting';
vben authored
38
39
import { useRouter } from 'vue-router';
40
41
42

import { errorStore } from '/@/store/modules/error';
vben authored
43
44
import { PageEnum } from '/@/enums/pageEnum';
import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
vben authored
45
46
import { AppLocalePicker } from '/@/components/Application';
import { useI18n } from '/@/hooks/web/useI18n';
vben authored
47
import { propTypes } from '/@/utils/propTypes';
vben authored
48
vben authored
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
interface TooltipItemProps {
  title: string;
}

const TooltipItem: FunctionalComponent<TooltipItemProps> = (props, { slots }) => {
  return (
    <Tooltip>
      {{
        title: () => props.title,
        default: () => slots.default?.(),
      }}
    </Tooltip>
  );
};
陈文彬 authored
64
export default defineComponent({
vben authored
65
  name: 'LayoutHeader',
vben authored
66
  props: {
vben authored
67
    fixed: propTypes.bool,
vben authored
68
69
  },
  setup(props) {
vben authored
70
    // let logoEl: Element | null | undefined;
71
vben authored
72
    // const logoWidthRef = ref(200);
vben authored
73
    const logoRef = ref<ComponentRef>(null);
74
    const { refreshPage } = useTabs();
75
    const { t } = useI18n();
vben authored
76
77
78

    const { getShowTopMenu, getShowHeaderTrigger, getSplit, getTopMenuAlign } = useMenuSetting();
vben authored
79
    const { getShowLocale } = useLocaleSetting();
vben authored
80
81
82
    const { getUseErrorHandle, getShowBreadCrumbIcon } = useRootSetting();

    const {
vben authored
83
      getHeaderTheme,
vben authored
84
85
86
87
88
89
90
91
92
      getShowRedo,
      getUseLockPage,
      getShowFullScreen,
      getShowNotice,
      getShowContent,
      getShowBread,
      getShowHeaderLogo,
    } = useHeaderSetting();
93
    const { push } = useRouter();
陈文彬 authored
94
95
    const [register, { openModal }] = useModal();
    const { toggleFullscreen, isFullscreenRef } = useFullscreen();
96
vben authored
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
    // useWindowSizeFn(
    //   () => {
    //     nextTick(() => {
    //       if (!unref(getShowTopMenu)) return;
    //       let width = 0;
    //       if (!logoEl) {
    //         logoEl = unref(logoRef)?.$el;
    //       } else {
    //         width += logoEl.clientWidth;
    //       }
    //       logoWidthRef.value = width + 80;
    //     });
    //   },
    //   200,
    //   { immediate: true }
    // );
陈文彬 authored
113
114

    const headerClass = computed(() => {
vben authored
115
      const theme = unref(getHeaderTheme);
陈文彬 authored
116
117
      return theme ? `layout-header__header--${theme}` : '';
    });
vben authored
118
vben authored
119
120
121
122
123
124
    const getSplitType = computed(() => {
      return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
    });

    const getMenuMode = computed(() => {
      return unref(getSplit) ? MenuModeEnum.HORIZONTAL : null;
125
126
    });
vben authored
127
    function handleToErrorList() {
vben authored
128
129
130
      push(PageEnum.ERROR_LOG_PAGE).then(() => {
        errorStore.commitErrorListCountState(0);
      });
vben authored
131
132
    }
陈文彬 authored
133
134
135
    function handleLockPage() {
      openModal(true);
    }
136
vben authored
137
    function renderHeaderContent() {
vben authored
138
      // const width = unref(logoWidthRef);
vben authored
139
140
141
      return (
        <div class="layout-header__content ">
          {unref(getShowHeaderLogo) && (
vben authored
142
            <AppLogo class={`layout-header__logo`} ref={logoRef} theme={unref(getHeaderTheme)} />
vben authored
143
          )}
陈文彬 authored
144
vben authored
145
146
147
          {unref(getShowContent) && (
            <div class="layout-header__left">
              {unref(getShowHeaderTrigger) && (
vben authored
148
                <LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
vben authored
149
150
151
152
              )}
              {unref(getShowBread) && <LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />}
            </div>
          )}
153
vben authored
154
          {unref(getShowTopMenu) && (
vben authored
155
156
            // <div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
            <div class={[`layout-header__menu `]}>
vben authored
157
158
159
              <LayoutMenu
                isHorizontal={true}
                class={`justify-${unref(getTopMenuAlign)}`}
vben authored
160
                theme={unref(getHeaderTheme)}
vben authored
161
162
163
164
165
166
167
168
169
                splitType={unref(getSplitType)}
                menuMode={unref(getMenuMode)}
                showSearch={false}
              />
            </div>
          )}
        </div>
      );
    }
170
vben authored
171
    function renderActionDefault(Comp: Component | any, event: Fn) {
陈文彬 authored
172
      return (
vben authored
173
174
        <div class="layout-header__action-item" onClick={event}>
          <Comp class="layout-header__action-icon" />
vben authored
175
176
177
        </div>
      );
    }
178
vben authored
179
180
181
182
    function renderAction() {
      return (
        <div class={`layout-header__action`}>
          {unref(getUseErrorHandle) && (
vben authored
183
            <TooltipItem title={t('layout.header.tooltipErrorLog')}>
vben authored
184
185
186
187
188
189
190
191
192
193
194
              {() => (
                <Badge
                  count={errorStore.getErrorListCountState}
                  offset={[0, 10]}
                  dot
                  overflowCount={99}
                >
                  {() => renderActionDefault(BugOutlined, handleToErrorList)}
                </Badge>
              )}
            </TooltipItem>
vben authored
195
          )}
陈文彬 authored
196
vben authored
197
          {unref(getUseLockPage) && (
vben authored
198
            <TooltipItem title={t('layout.header.tooltipLock')}>
vben authored
199
200
              {() => renderActionDefault(LockOutlined, handleLockPage)}
            </TooltipItem>
vben authored
201
202
203
          )}

          {unref(getShowNotice) && (
vben authored
204
205
206
            <TooltipItem title={t('layout.header.tooltipNotify')}>
              {() => <NoticeAction />}
            </TooltipItem>
vben authored
207
          )}
vben authored
208
vben authored
209
          {unref(getShowRedo) && (
vben authored
210
            <TooltipItem title={t('layout.header.tooltipRedo')}>
vben authored
211
212
              {() => renderActionDefault(RedoOutlined, refreshPage)}
            </TooltipItem>
陈文彬 authored
213
          )}
vben authored
214
215

          {unref(getShowFullScreen) && (
vben authored
216
217
218
219
220
221
222
            <TooltipItem
              title={
                unref(isFullscreenRef)
                  ? t('layout.header.tooltipExitFull')
                  : t('layout.header.tooltipEntryFull')
              }
            >
vben authored
223
224
225
226
227
228
229
              {() => {
                const Icon = !unref(isFullscreenRef) ? (
                  <FullscreenOutlined />
                ) : (
                  <FullscreenExitOutlined />
                );
                return renderActionDefault(Icon, toggleFullscreen);
vben authored
230
              }}
vben authored
231
            </TooltipItem>
vben authored
232
          )}
vben authored
233
234
235
236
237
238
239
240
          <UserDropdown class="layout-header__user-dropdown" />
          {unref(getShowLocale) && (
            <AppLocalePicker
              reload={true}
              showText={false}
              class="layout-header__action-item locale"
            />
          )}
vben authored
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
        </div>
      );
    }

    function renderHeaderDefault() {
      return (
        <>
          {renderHeaderContent()}
          {renderAction()}
          <LockAction onRegister={register} />
        </>
      );
    }

    return () => {
      return (
vben authored
257
258
259
        <Layout.Header
          class={['layout-header', 'flex p-0 px-4 ', unref(headerClass), { fixed: props.fixed }]}
        >
vben authored
260
          {() => renderHeaderDefault()}
陈文彬 authored
261
262
263
264
265
        </Layout.Header>
      );
    };
  },
});