Blame view

src/layouts/default/setting/SettingDrawer.tsx 16.4 KB
vben authored
1
2
3
4
5
import type { ProjectConfig } from '/@/types/config';

import defaultSetting from '/@/settings/projectSetting';

import { defineComponent, computed, unref, FunctionalComponent } from 'vue';
陈文彬 authored
6
7
import { BasicDrawer } from '/@/components/Drawer/index';
import { Divider, Switch, Tooltip, InputNumber, Select } from 'ant-design-vue';
vben authored
8
import { Button } from '/@/components/Button';
陈文彬 authored
9
import { CopyOutlined, RedoOutlined, CheckOutlined } from '@ant-design/icons-vue';
vben authored
10
11

import { MenuTypeEnum } from '/@/enums/menuEnum';
陈文彬 authored
12
13
14
15
import { appStore } from '/@/store/modules/app';

import { useMessage } from '/@/hooks/web/useMessage';
import { useCopyToClipboard } from '/@/hooks/web/useCopyToClipboard';
vben authored
16
17
18
19
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting';
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
vben authored
20
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
vben authored
21
import { useI18n } from '/@/hooks/web/useI18n';
陈文彬 authored
22
23

import { updateColorWeak, updateGrayMode } from '/@/setup/theme';
vben authored
24
25
import { baseHandler } from './handler';
vben authored
26
27
28
29
30
31
32
import {
  HandlerEnum,
  contentModeOptions,
  topMenuAlignOptions,
  menuTriggerOptions,
  routerTransitionOptions,
vben authored
33
34
35
  menuTypeList,
} from './enum';
36
import { HEADER_PRESET_BG_COLOR_LIST, SIDE_BAR_BG_COLOR_LIST } from '/@/settings/colorSetting';
陈文彬 authored
37
38
39
40
41
42
43
44
45

interface SwitchOptions {
  config?: DeepPartial<ProjectConfig>;
  def?: any;
  disabled?: boolean;
  handler?: Fn;
}

interface SelectConfig {
vben authored
46
  options?: LabelValueOptions;
陈文彬 authored
47
48
49
50
51
  def?: any;
  disabled?: boolean;
  handler?: Fn;
}
vben authored
52
53
54
55
interface ThemePickerProps {
  colorList: string[];
  handler: Fn;
  def: string;
56
57
}
vben authored
58
const { createSuccessModal, createMessage } = useMessage();
59
const { t } = useI18n();
vben authored
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

/**
 * Menu type Picker comp
 */
const MenuTypePicker: FunctionalComponent = () => {
  const { getIsHorizontal, getMenuType } = useMenuSetting();
  return (
    <div class={`setting-drawer__siderbar`}>
      {menuTypeList.map((item) => {
        const { title, type: ItemType, mode, src } = item;
        return (
          <Tooltip title={title} placement="bottom" key={title}>
            {{
              default: () => (
                <div
                  onClick={baseHandler.bind(null, HandlerEnum.CHANGE_LAYOUT, {
                    mode: mode,
                    type: ItemType,
                    split: unref(getIsHorizontal) ? false : undefined,
                  })}
                >
                  <CheckOutlined
                    class={['check-icon', unref(getMenuType) === ItemType ? 'active' : '']}
                  />
                  <img src={src} />
                </div>
              ),
            }}
          </Tooltip>
        );
      })}
    </div>
  );
};

const ThemePicker: FunctionalComponent<ThemePickerProps> = (props) => {
  return (
    <div class={`setting-drawer__theme-item`}>
      {props.colorList.map((color) => {
        return (
          <span
            onClick={() => props.handler?.(color)}
            key={color}
            class={[props.def === color ? 'active' : '']}
            style={{
              background: color,
            }}
          >
            <CheckOutlined class="icon" />
          </span>
        );
      })}
    </div>
  );
};

/**
 * FooterButton component
 */
const FooterButton: FunctionalComponent = () => {
  const { getRootSetting } = useRootSetting();
  function handleCopy() {
    const { isSuccessRef } = useCopyToClipboard(JSON.stringify(unref(getRootSetting), null, 2));
    unref(isSuccessRef) &&
      createSuccessModal({
125
126
        title: t('layout.setting.operatingTitle'),
        content: t('layout.setting.operatingContent'),
vben authored
127
128
129
130
131
132
133
134
135
      });
  }
  function handleResetSetting() {
    try {
      appStore.commitProjectConfigState(defaultSetting);
      const { colorWeak, grayMode } = defaultSetting;
      // updateTheme(themeColor);
      updateColorWeak(colorWeak);
      updateGrayMode(grayMode);
136
      createMessage.success(t('layout.setting.resetSuccess'));
vben authored
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    } catch (error) {
      createMessage.error(error);
    }
  }

  function handleClearAndRedo() {
    localStorage.clear();
    appStore.resumeAllState();
    location.reload();
  }

  return (
    <div class="setting-drawer__footer">
      <Button type="primary" block onClick={handleCopy}>
        {() => (
          <>
            <CopyOutlined class="mr-2" />
154
            {t('layout.setting.copyBtn')}
vben authored
155
156
157
158
159
160
161
          </>
        )}
      </Button>
      <Button block class="mt-2" onClick={handleResetSetting} color="warning">
        {() => (
          <>
            <RedoOutlined class="mr-2" />
162
            {t('layout.setting.resetBtn')}
vben authored
163
164
165
166
167
168
169
          </>
        )}
      </Button>
      <Button block class="mt-2" onClick={handleClearAndRedo} color="error">
        {() => (
          <>
            <RedoOutlined class="mr-2" />
170
            {t('layout.setting.clearBtn')}
vben authored
171
172
173
174
175
176
177
          </>
        )}
      </Button>
    </div>
  );
};
陈文彬 authored
178
179
180
export default defineComponent({
  name: 'SettingDrawer',
  setup(_, { attrs }) {
vben authored
181
182
183
184
185
186
187
188
189
190
    const {
      getContentMode,
      getShowFooter,
      getShowBreadCrumb,
      getShowBreadCrumbIcon,
      getShowLogo,
      getFullContent,
      getColorWeak,
      getGrayMode,
    } = useRootSetting();
陈文彬 authored
191
vben authored
192
    const {
vben authored
193
194
195
196
197
198
199
      getOpenPageLoading,
      getBasicTransition,
      getEnableTransition,
      getOpenNProgress,
    } = useTransitionSetting();

    const {
vben authored
200
201
202
203
204
205
206
207
      getIsHorizontal,
      getShowMenu,
      getMenuType,
      getTrigger,
      getCollapsedShowTitle,
      getMenuFixed,
      getCollapsed,
      getShowSearch,
208
      getCanDrag,
vben authored
209
210
211
212
213
214
215
      getTopMenuAlign,
      getAccordion,
      getMenuWidth,
      getMenuBgColor,
      getIsTopMenu,
      getSplit,
    } = useMenuSetting();
陈文彬 authored
216
vben authored
217
    const { getShowHeader, getFixed: getHeaderFixed, getHeaderBgColor } = useHeaderSetting();
陈文彬 authored
218
vben authored
219
    const { getShowMultipleTab, getShowQuick } = useMultipleTabSetting();
陈文彬 authored
220
221

    const getShowMenuRef = computed(() => {
vben authored
222
      return unref(getShowMenu) && !unref(getIsHorizontal);
陈文彬 authored
223
224
    });
vben authored
225
226
227
228
    function renderSidebar() {
      return (
        <>
          <MenuTypePicker />
229
          {renderSwitchItem(t('layout.setting.splitMenu'), {
vben authored
230
231
232
233
234
235
236
            handler: (e) => {
              baseHandler(HandlerEnum.MENU_SPLIT, e);
            },
            def: unref(getSplit),
            disabled: !unref(getShowMenuRef) || unref(getMenuType) !== MenuTypeEnum.MIX,
          })}
        </>
陈文彬 authored
237
238
239
      );
    }
vben authored
240
241
242
    function renderTheme() {
      return (
        <>
243
          <Divider>{() => t('layout.setting.headerTheme')}</Divider>
vben authored
244
245
246
247
248
249
250
          <ThemePicker
            colorList={HEADER_PRESET_BG_COLOR_LIST}
            def={unref(getHeaderBgColor)}
            handler={(e) => {
              baseHandler(HandlerEnum.HEADER_THEME, e);
            }}
          />
251
          <Divider>{() => t('layout.setting.sidebarTheme')}</Divider>
vben authored
252
253
254
255
256
257
258
259
260
          <ThemePicker
            colorList={SIDE_BAR_BG_COLOR_LIST}
            def={unref(getMenuBgColor)}
            handler={(e) => {
              baseHandler(HandlerEnum.MENU_THEME, e);
            }}
          />
        </>
      );
261
262
    }
陈文彬 authored
263
264
265
266
267
    /**
     * @description:
     */
    function renderFeatures() {
      return [
268
        renderSwitchItem(t('layout.setting.menuDrag'), {
陈文彬 authored
269
          handler: (e) => {
270
            baseHandler(HandlerEnum.MENU_HAS_DRAG, e);
陈文彬 authored
271
          },
272
          def: unref(getCanDrag),
陈文彬 authored
273
274
          disabled: !unref(getShowMenuRef),
        }),
275
        renderSwitchItem(t('layout.setting.menuSearch'), {
陈文彬 authored
276
          handler: (e) => {
277
            baseHandler(HandlerEnum.MENU_SHOW_SEARCH, e);
陈文彬 authored
278
          },
vben authored
279
          def: unref(getShowSearch),
陈文彬 authored
280
281
          disabled: !unref(getShowMenuRef),
        }),
282
        renderSwitchItem(t('layout.setting.menuAccordion'), {
283
284
285
          handler: (e) => {
            baseHandler(HandlerEnum.MENU_ACCORDION, e);
          },
vben authored
286
          def: unref(getAccordion),
287
288
          disabled: !unref(getShowMenuRef),
        }),
289
        renderSwitchItem(t('layout.setting.menuCollapse'), {
陈文彬 authored
290
          handler: (e) => {
291
            baseHandler(HandlerEnum.MENU_COLLAPSED, e);
陈文彬 authored
292
          },
vben authored
293
          def: unref(getCollapsed),
陈文彬 authored
294
295
          disabled: !unref(getShowMenuRef),
        }),
296
        renderSwitchItem(t('layout.setting.collapseMenuDisplayName'), {
297
          handler: (e) => {
298
            baseHandler(HandlerEnum.MENU_COLLAPSED_SHOW_TITLE, e);
299
          },
vben authored
300
301
          def: unref(getCollapsedShowTitle),
          disabled: !unref(getShowMenuRef) || !unref(getCollapsed),
302
        }),
303
        renderSwitchItem(t('layout.setting.fixedHeader'), {
vben authored
304
305
306
          handler: (e) => {
            baseHandler(HandlerEnum.HEADER_FIXED, e);
          },
vben authored
307
308
309
          def: unref(getHeaderFixed),
          disabled: !unref(getShowHeader),
        }),
310
        renderSwitchItem(t('layout.setting.fixedSideBar'), {
vben authored
311
312
313
314
315
          handler: (e) => {
            baseHandler(HandlerEnum.MENU_FIXED, e);
          },
          def: unref(getMenuFixed),
          disabled: !unref(getShowMenuRef),
vben authored
316
        }),
317
        renderSelectItem(t('layout.setting.topMenuLayout'), {
陈文彬 authored
318
          handler: (e) => {
319
            baseHandler(HandlerEnum.MENU_TOP_ALIGN, e);
陈文彬 authored
320
          },
vben authored
321
          def: unref(getTopMenuAlign),
陈文彬 authored
322
          options: topMenuAlignOptions,
vben authored
323
          disabled: !unref(getShowHeader) || (!unref(getIsTopMenu) && !unref(getSplit)),
陈文彬 authored
324
        }),
325
        renderSelectItem(t('layout.setting.menuCollapseButton'), {
326
          handler: (e) => {
327
            baseHandler(HandlerEnum.MENU_TRIGGER, e);
328
          },
vben authored
329
330
          disabled: !unref(getShowMenuRef),
          def: unref(getTrigger),
331
332
          options: menuTriggerOptions,
        }),
vben authored
333
334
        renderSelectItem(t('layout.setting.contentMode'), {
陈文彬 authored
335
          handler: (e) => {
336
            baseHandler(HandlerEnum.CONTENT_MODE, e);
陈文彬 authored
337
          },
vben authored
338
          def: unref(getContentMode),
陈文彬 authored
339
340
341
          options: contentModeOptions,
        }),
        <div class={`setting-drawer__cell-item`}>
342
          <span>{t('layout.setting.autoScreenLock')}</span>
陈文彬 authored
343
          <InputNumber
vben authored
344
            style="width:126px"
陈文彬 authored
345
346
            size="small"
            min={0}
347
348
            onChange={(e: any) => {
              baseHandler(HandlerEnum.LOCK_TIME, e);
陈文彬 authored
349
350
351
352
            }}
            defaultValue={appStore.getProjectConfig.lockTime}
            formatter={(value: string) => {
              if (parseInt(value) === 0) {
353
                return `0(${t('layout.setting.notAutoScreenLock')})`;
陈文彬 authored
354
              }
355
              return `${value}${t('layout.setting.minute')}`;
陈文彬 authored
356
357
358
359
            }}
          />
        </div>,
        <div class={`setting-drawer__cell-item`}>
360
          <span>{t('layout.setting.expandedMenuWidth')}</span>
陈文彬 authored
361
          <InputNumber
vben authored
362
            style="width:126px"
陈文彬 authored
363
364
365
366
367
            size="small"
            max={600}
            min={100}
            step={10}
            disabled={!unref(getShowMenuRef)}
vben authored
368
            defaultValue={unref(getMenuWidth)}
陈文彬 authored
369
            formatter={(value: string) => `${parseInt(value)}px`}
370
            onChange={(e: any) => {
371
              baseHandler(HandlerEnum.MENU_WIDTH, e);
陈文彬 authored
372
373
374
375
376
377
378
379
            }}
          />
        </div>,
      ];
    }

    function renderContent() {
      return [
380
        renderSwitchItem(t('layout.setting.breadcrumb'), {
陈文彬 authored
381
          handler: (e) => {
382
            baseHandler(HandlerEnum.SHOW_BREADCRUMB, e);
陈文彬 authored
383
          },
vben authored
384
385
          def: unref(getShowBreadCrumb),
          disabled: !unref(getShowHeader),
陈文彬 authored
386
        }),
387
        renderSwitchItem(t('layout.setting.breadcrumbIcon'), {
388
          handler: (e) => {
389
            baseHandler(HandlerEnum.SHOW_BREADCRUMB_ICON, e);
390
          },
vben authored
391
392
          def: unref(getShowBreadCrumbIcon),
          disabled: !unref(getShowHeader),
393
        }),
394
        renderSwitchItem(t('layout.setting.tabs'), {
陈文彬 authored
395
          handler: (e) => {
396
            baseHandler(HandlerEnum.TABS_SHOW, e);
陈文彬 authored
397
          },
vben authored
398
          def: unref(getShowMultipleTab),
陈文彬 authored
399
        }),
400
        renderSwitchItem(t('layout.setting.tabsQuickBtn'), {
陈文彬 authored
401
          handler: (e) => {
402
            baseHandler(HandlerEnum.TABS_SHOW_QUICK, e);
陈文彬 authored
403
          },
vben authored
404
405
          def: unref(getShowQuick),
          disabled: !unref(getShowMultipleTab),
陈文彬 authored
406
        }),
vben authored
407
408
        renderSwitchItem(t('layout.setting.sidebar'), {
陈文彬 authored
409
          handler: (e) => {
410
            baseHandler(HandlerEnum.MENU_SHOW_SIDEBAR, e);
陈文彬 authored
411
          },
vben authored
412
413
          def: unref(getShowMenu),
          disabled: unref(getIsHorizontal),
陈文彬 authored
414
        }),
415
        renderSwitchItem(t('layout.setting.header'), {
陈文彬 authored
416
          handler: (e) => {
417
            baseHandler(HandlerEnum.HEADER_SHOW, e);
陈文彬 authored
418
          },
vben authored
419
          def: unref(getShowHeader),
陈文彬 authored
420
421
422
        }),
        renderSwitchItem('Logo', {
          handler: (e) => {
423
            baseHandler(HandlerEnum.SHOW_LOGO, e);
陈文彬 authored
424
          },
vben authored
425
426
          def: unref(getShowLogo),
        }),
427
        renderSwitchItem(t('layout.setting.footer'), {
vben authored
428
429
430
431
          handler: (e) => {
            baseHandler(HandlerEnum.SHOW_FOOTER, e);
          },
          def: unref(getShowFooter),
陈文彬 authored
432
        }),
433
        renderSwitchItem(t('layout.setting.fullContent'), {
陈文彬 authored
434
          handler: (e) => {
435
            baseHandler(HandlerEnum.FULL_CONTENT, e);
陈文彬 authored
436
          },
vben authored
437
          def: unref(getFullContent),
陈文彬 authored
438
        }),
439
        renderSwitchItem(t('layout.setting.grayMode'), {
陈文彬 authored
440
          handler: (e) => {
441
            baseHandler(HandlerEnum.GRAY_MODE, e);
陈文彬 authored
442
          },
vben authored
443
          def: unref(getGrayMode),
陈文彬 authored
444
        }),
445
        renderSwitchItem(t('layout.setting.colorWeak'), {
陈文彬 authored
446
          handler: (e) => {
447
            baseHandler(HandlerEnum.COLOR_WEAK, e);
陈文彬 authored
448
          },
vben authored
449
          def: unref(getColorWeak),
陈文彬 authored
450
451
452
453
        }),
      ];
    }
vben authored
454
455
456
    function renderTransition() {
      return (
        <>
457
          {renderSwitchItem(t('layout.setting.progress'), {
vben authored
458
459
460
461
462
            handler: (e) => {
              baseHandler(HandlerEnum.OPEN_PROGRESS, e);
            },
            def: unref(getOpenNProgress),
          })}
463
          {renderSwitchItem(t('layout.setting.switchLoading'), {
vben authored
464
465
466
467
468
469
            handler: (e) => {
              baseHandler(HandlerEnum.OPEN_PAGE_LOADING, e);
            },
            def: unref(getOpenPageLoading),
          })}
470
          {renderSwitchItem(t('layout.setting.switchAnimation'), {
vben authored
471
472
473
            handler: (e) => {
              baseHandler(HandlerEnum.OPEN_ROUTE_TRANSITION, e);
            },
vben authored
474
            def: unref(getEnableTransition),
vben authored
475
476
          })}
477
          {renderSelectItem(t('layout.setting.animationType'), {
vben authored
478
479
480
            handler: (e) => {
              baseHandler(HandlerEnum.ROUTER_TRANSITION, e);
            },
vben authored
481
            def: unref(getBasicTransition),
vben authored
482
            options: routerTransitionOptions,
vben authored
483
            disabled: !unref(getEnableTransition),
vben authored
484
485
486
487
488
          })}
        </>
      );
    }
陈文彬 authored
489
490
491
492
493
494
495
496
497
498
    function renderSelectItem(text: string, config?: SelectConfig) {
      const { handler, def, disabled = false, options } = config || {};
      const opt = def ? { value: def, defaultValue: def } : {};
      return (
        <div class={`setting-drawer__cell-item`}>
          <span>{text}</span>
          <Select
            {...opt}
            disabled={disabled}
            size="small"
vben authored
499
            style={{ width: '126px' }}
陈文彬 authored
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
            onChange={(e) => {
              handler && handler(e);
            }}
            options={options}
          />
        </div>
      );
    }

    function renderSwitchItem(text: string, options?: SwitchOptions) {
      const { handler, def, disabled = false } = options || {};
      const opt = def ? { checked: def } : {};
      return (
        <div class={`setting-drawer__cell-item`}>
          <span>{text}</span>
          <Switch
            {...opt}
            disabled={disabled}
518
            onChange={(e: any) => {
陈文彬 authored
519
520
              handler && handler(e);
            }}
521
522
            checkedChildren={t('layout.setting.on')}
            unCheckedChildren={t('layout.setting.off')}
陈文彬 authored
523
524
525
526
          />
        </div>
      );
    }
527
陈文彬 authored
528
    return () => (
529
530
531
532
533
534
      <BasicDrawer
        {...attrs}
        title={t('layout.setting.drawerTitle')}
        width={330}
        wrapClassName="setting-drawer"
      >
陈文彬 authored
535
536
537
        {{
          default: () => (
            <>
538
              <Divider>{() => t('layout.setting.navMode')}</Divider>
陈文彬 authored
539
              {renderSidebar()}
540
              {renderTheme()}
541
              <Divider>{() => t('layout.setting.interfaceFunction')}</Divider>
陈文彬 authored
542
              {renderFeatures()}
543
              <Divider>{() => t('layout.setting.interfaceDisplay')}</Divider>
陈文彬 authored
544
              {renderContent()}
545
              <Divider>{() => t('layout.setting.animation')}</Divider>
陈文彬 authored
546
547
              {renderTransition()}
              <Divider />
vben authored
548
              <FooterButton />
陈文彬 authored
549
550
551
552
553
554
555
            </>
          ),
        }}
      </BasicDrawer>
    );
  },
});