UNPKG

17.7 kBJavaScriptView Raw
1import "antd/es/drawer/style";
2import _Drawer from "antd/es/drawer";
3import "antd/es/button/style";
4import _Button from "antd/es/button";
5import "antd/es/message/style";
6import _message from "antd/es/message";
7import "antd/es/alert/style";
8import _Alert from "antd/es/alert";
9import "antd/es/list/style";
10import _List from "antd/es/list";
11import "antd/es/switch/style";
12import _Switch from "antd/es/switch";
13import "antd/es/divider/style";
14import _Divider from "antd/es/divider";
15import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
16import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
17import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
18import "antd/es/config-provider/style";
19import _ConfigProvider from "antd/es/config-provider";
20import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
21import { CloseOutlined, CopyOutlined, NotificationOutlined, SettingOutlined } from '@ant-design/icons';
22import { isBrowser, merge } from '@ant-design/pro-utils';
23import { disable as darkreaderDisable, enable as darkreaderEnable, setFetchMethod as setFetch } from '@umijs/ssr-darkreader';
24import { useUrlSearchParams } from '@umijs/use-params';
25import omit from 'omit.js';
26import useMergedState from "rc-util/es/hooks/useMergedState";
27import React, { useEffect, useRef, useState } from 'react';
28import defaultSettings from '../../defaultSettings';
29import { getLanguage, gLocaleObject } from '../../locales';
30import { genStringToTheme } from '../../utils/utils';
31import BlockCheckbox from './BlockCheckbox';
32import './index.less';
33import LayoutSetting, { renderLayoutSettingItem } from './LayoutChange';
34import RegionalSetting from './RegionalChange';
35import ThemeColor from './ThemeColor';
36
37var Body = function Body(_ref) {
38 var children = _ref.children,
39 prefixCls = _ref.prefixCls,
40 title = _ref.title;
41 return /*#__PURE__*/React.createElement("div", {
42 style: {
43 marginBottom: 24
44 }
45 }, /*#__PURE__*/React.createElement("h3", {
46 className: "".concat(prefixCls, "-drawer-title")
47 }, title), children);
48};
49
50var getDifferentSetting = function getDifferentSetting(state) {
51 var stateObj = {};
52 Object.keys(state).forEach(function (key) {
53 if (state[key] !== defaultSettings[key] && key !== 'collapse') {
54 stateObj[key] = state[key];
55 } else {
56 stateObj[key] = undefined;
57 }
58
59 if (key.includes('Render')) stateObj[key] = state[key] === false ? false : undefined;
60 });
61 stateObj.menu = undefined;
62 return stateObj;
63};
64
65export var getFormatMessage = function getFormatMessage() {
66 var formatMessage = function formatMessage(_ref2) {
67 var id = _ref2.id;
68 var locales = gLocaleObject();
69 return locales[id];
70 };
71
72 return formatMessage;
73};
74
75var updateTheme = /*#__PURE__*/function () {
76 var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(dark, color) {
77 var defaultTheme, defaultFixes;
78 return _regeneratorRuntime().wrap(function _callee$(_context) {
79 while (1) {
80 switch (_context.prev = _context.next) {
81 case 0:
82 if (!(typeof window === 'undefined')) {
83 _context.next = 2;
84 break;
85 }
86
87 return _context.abrupt("return");
88
89 case 2:
90 if (!(typeof window.MutationObserver === 'undefined')) {
91 _context.next = 4;
92 break;
93 }
94
95 return _context.abrupt("return");
96
97 case 4:
98 if (_ConfigProvider.config) {
99 _context.next = 6;
100 break;
101 }
102
103 return _context.abrupt("return");
104
105 case 6:
106 _ConfigProvider.config({
107 theme: {
108 primaryColor: genStringToTheme(color) || '#1890ff'
109 }
110 });
111
112 if (dark) {
113 defaultTheme = {
114 brightness: 100,
115 contrast: 90,
116 sepia: 10
117 };
118 defaultFixes = {
119 invert: [],
120 css: '',
121 ignoreInlineStyle: ['.react-switch-handle'],
122 ignoreImageAnalysis: [],
123 disableStyleSheetsProxy: true
124 };
125
126 if (window.MutationObserver && window.fetch) {
127 setFetch(window.fetch);
128 darkreaderEnable(defaultTheme, defaultFixes);
129 }
130 } else {
131 if (window.MutationObserver) darkreaderDisable();
132 }
133
134 case 8:
135 case "end":
136 return _context.stop();
137 }
138 }
139 }, _callee);
140 }));
141
142 return function updateTheme(_x, _x2) {
143 return _ref3.apply(this, arguments);
144 };
145}();
146/**
147 * 初始化的时候需要做的工作
148 *
149 * @param param0
150 */
151
152
153var initState = function initState(urlParams, settings, onSettingChange) {
154 if (!isBrowser()) return;
155 var replaceSetting = {};
156 Object.keys(urlParams).forEach(function (key) {
157 if (defaultSettings[key] || defaultSettings[key] === undefined) {
158 if (key === 'primaryColor') {
159 replaceSetting[key] = genStringToTheme(urlParams[key]);
160 return;
161 }
162
163 replaceSetting[key] = urlParams[key];
164 }
165 });
166 var newSettings = merge({}, settings, replaceSetting);
167 delete newSettings.menu;
168 delete newSettings.title;
169 delete newSettings.iconfontUrl; // 同步数据到外部
170
171 onSettingChange === null || onSettingChange === void 0 ? void 0 : onSettingChange(newSettings); // 如果 url 中设置主题,进行一次加载。
172
173 if (defaultSettings.navTheme !== urlParams.navTheme && urlParams.navTheme) {
174 updateTheme(settings.navTheme === 'realDark', urlParams.primaryColor);
175 }
176};
177
178var getParamsFromUrl = function getParamsFromUrl(urlParams, settings) {
179 if (!isBrowser()) return defaultSettings;
180 return _objectSpread(_objectSpread(_objectSpread({}, defaultSettings), settings || {}), urlParams);
181};
182
183var genCopySettingJson = function genCopySettingJson(settingState) {
184 return JSON.stringify(omit(_objectSpread(_objectSpread({}, settingState), {}, {
185 primaryColor: settingState.primaryColor
186 }), ['colorWeak']), null, 2);
187};
188/**
189 * 可视化配置组件
190 *
191 * @param props
192 */
193
194
195var SettingDrawer = function SettingDrawer(props) {
196 var _props$defaultSetting = props.defaultSettings,
197 propsDefaultSettings = _props$defaultSetting === void 0 ? undefined : _props$defaultSetting,
198 _props$settings = props.settings,
199 propsSettings = _props$settings === void 0 ? undefined : _props$settings,
200 hideHintAlert = props.hideHintAlert,
201 hideCopyButton = props.hideCopyButton,
202 _props$colorList = props.colorList,
203 colorList = _props$colorList === void 0 ? [{
204 key: 'daybreak',
205 color: '#1890ff'
206 }, {
207 key: 'dust',
208 color: '#F5222D'
209 }, {
210 key: 'volcano',
211 color: '#FA541C'
212 }, {
213 key: 'sunset',
214 color: '#FAAD14'
215 }, {
216 key: 'cyan',
217 color: '#13C2C2'
218 }, {
219 key: 'green',
220 color: '#52C41A'
221 }, {
222 key: 'geekblue',
223 color: '#2F54EB'
224 }, {
225 key: 'purple',
226 color: '#722ED1'
227 }] : _props$colorList,
228 getContainer = props.getContainer,
229 onSettingChange = props.onSettingChange,
230 enableDarkTheme = props.enableDarkTheme,
231 _props$prefixCls = props.prefixCls,
232 prefixCls = _props$prefixCls === void 0 ? 'ant-pro' : _props$prefixCls,
233 _props$pathname = props.pathname,
234 pathname = _props$pathname === void 0 ? window.location.pathname : _props$pathname,
235 _props$disableUrlPara = props.disableUrlParams,
236 disableUrlParams = _props$disableUrlPara === void 0 ? true : _props$disableUrlPara,
237 themeOnly = props.themeOnly;
238 var firstRender = useRef(true);
239
240 var _useMergedState = useMergedState(false, {
241 value: props.collapse,
242 onChange: props.onCollapseChange
243 }),
244 _useMergedState2 = _slicedToArray(_useMergedState, 2),
245 show = _useMergedState2[0],
246 setShow = _useMergedState2[1];
247
248 var _useState = useState(getLanguage()),
249 _useState2 = _slicedToArray(_useState, 2),
250 language = _useState2[0],
251 setLanguage = _useState2[1];
252
253 var _useUrlSearchParams = useUrlSearchParams({}, {
254 disabled: disableUrlParams
255 }),
256 _useUrlSearchParams2 = _slicedToArray(_useUrlSearchParams, 2),
257 urlParams = _useUrlSearchParams2[0],
258 setUrlParams = _useUrlSearchParams2[1];
259
260 var _useMergedState3 = useMergedState(function () {
261 return getParamsFromUrl(urlParams, propsSettings || propsDefaultSettings);
262 }, {
263 value: propsSettings,
264 onChange: onSettingChange
265 }),
266 _useMergedState4 = _slicedToArray(_useMergedState3, 2),
267 settingState = _useMergedState4[0],
268 setSettingState = _useMergedState4[1];
269
270 var _ref4 = settingState || {},
271 navTheme = _ref4.navTheme,
272 primaryColor = _ref4.primaryColor,
273 layout = _ref4.layout,
274 colorWeak = _ref4.colorWeak;
275
276 useEffect(function () {
277 // 语言修改,这个是和 locale 是配置起来的
278 var onLanguageChange = function onLanguageChange() {
279 if (language !== getLanguage()) {
280 setLanguage(getLanguage());
281 }
282 };
283 /** 如果不是浏览器 都没有必要做了 */
284
285
286 if (!isBrowser()) return function () {
287 return null;
288 };
289 initState(getParamsFromUrl(urlParams, propsSettings), settingState, setSettingState);
290 window.document.addEventListener('languagechange', onLanguageChange, {
291 passive: true
292 });
293 return function () {
294 return window.document.removeEventListener('languagechange', onLanguageChange);
295 }; // eslint-disable-next-line react-hooks/exhaustive-deps
296 }, []);
297 useEffect(function () {
298 updateTheme(settingState.navTheme === 'realDark', settingState.primaryColor);
299 }, [settingState.primaryColor, settingState.navTheme]);
300 /**
301 * 修改设置
302 *
303 * @param key
304 * @param value
305 */
306
307 var changeSetting = function changeSetting(key, value) {
308 var nextState = {};
309 nextState[key] = value;
310
311 if (key === 'layout') {
312 nextState.contentWidth = value === 'top' ? 'Fixed' : 'Fluid';
313 }
314
315 if (key === 'layout' && value !== 'mix') {
316 nextState.splitMenus = false;
317 }
318
319 if (key === 'layout' && value === 'mix') {
320 nextState.navTheme = 'light';
321 }
322
323 if (key === 'colorWeak' && value === true) {
324 var dom = document.querySelector('body');
325
326 if (dom) {
327 dom.dataset.prosettingdrawer = dom.style.filter;
328 dom.style.filter = 'invert(80%)';
329 }
330 }
331
332 if (key === 'colorWeak' && value === false) {
333 var _dom = document.querySelector('body');
334
335 if (_dom) {
336 _dom.style.filter = _dom.dataset.prosettingdrawer || 'none';
337 delete _dom.dataset.prosettingdrawer;
338 }
339 }
340
341 delete nextState.menu;
342 delete nextState.title;
343 delete nextState.iconfontUrl;
344 delete nextState.logo;
345 delete nextState.pwa;
346 setSettingState(_objectSpread(_objectSpread({}, settingState), nextState));
347 };
348
349 var formatMessage = getFormatMessage();
350 useEffect(function () {
351 /** 如果不是浏览器 都没有必要做了 */
352 if (!isBrowser()) return;
353 if (disableUrlParams) return;
354
355 if (firstRender.current) {
356 firstRender.current = false;
357 return;
358 }
359 /** 每次从url拿最新的防止记忆 */
360
361
362 var urlSearchParams = new URLSearchParams(window.location.search);
363 var params = Object.fromEntries(urlSearchParams.entries());
364 var diffParams = getDifferentSetting(_objectSpread(_objectSpread({}, params), settingState));
365 delete diffParams.logo;
366 delete diffParams.menu;
367 delete diffParams.title;
368 delete diffParams.iconfontUrl;
369 delete diffParams.pwa;
370 setUrlParams(diffParams);
371 }, [setUrlParams, settingState, urlParams, pathname, disableUrlParams]);
372 var baseClassName = "".concat(prefixCls, "-setting");
373 return /*#__PURE__*/React.createElement(_Drawer, {
374 visible: show,
375 width: 300,
376 closable: false,
377 onClose: function onClose() {
378 return setShow(false);
379 },
380 placement: "right",
381 getContainer: getContainer,
382 handler: /*#__PURE__*/React.createElement("div", {
383 className: "".concat(baseClassName, "-drawer-handle"),
384 onClick: function onClick() {
385 return setShow(!show);
386 }
387 }, show ? /*#__PURE__*/React.createElement(CloseOutlined, {
388 style: {
389 color: '#fff',
390 fontSize: 20
391 }
392 }) : /*#__PURE__*/React.createElement(SettingOutlined, {
393 style: {
394 color: '#fff',
395 fontSize: 20
396 }
397 })),
398 style: {
399 zIndex: 999
400 }
401 }, /*#__PURE__*/React.createElement("div", {
402 className: "".concat(baseClassName, "-drawer-content")
403 }, /*#__PURE__*/React.createElement(Body, {
404 title: formatMessage({
405 id: 'app.setting.pagestyle',
406 defaultMessage: 'Page style setting'
407 }),
408 prefixCls: baseClassName
409 }, /*#__PURE__*/React.createElement(BlockCheckbox, {
410 prefixCls: baseClassName,
411 list: [{
412 key: 'light',
413 title: formatMessage({
414 id: 'app.setting.pagestyle.light',
415 defaultMessage: '亮色菜单风格'
416 })
417 }, {
418 key: 'dark',
419 title: formatMessage({
420 id: 'app.setting.pagestyle.dark',
421 defaultMessage: '暗色菜单风格'
422 })
423 }, {
424 key: 'realDark',
425 title: formatMessage({
426 id: 'app.setting.pagestyle.realdark',
427 defaultMessage: '暗色菜单风格'
428 })
429 }].filter(function (item) {
430 if (item.key === 'dark' && settingState.layout === 'mix') return false;
431 if (item.key === 'realDark' && !enableDarkTheme) return false;
432 return true;
433 }),
434 value: navTheme,
435 configType: "theme",
436 key: "navTheme",
437 onChange: function onChange(value) {
438 return changeSetting('navTheme', value);
439 }
440 })), colorList !== false && /*#__PURE__*/React.createElement(Body, {
441 title: formatMessage({
442 id: 'app.setting.themecolor',
443 defaultMessage: 'Theme color'
444 }),
445 prefixCls: baseClassName
446 }, /*#__PURE__*/React.createElement(ThemeColor, {
447 colorList: colorList,
448 value: genStringToTheme(primaryColor),
449 formatMessage: formatMessage,
450 onChange: function onChange(color) {
451 return changeSetting('primaryColor', color);
452 }
453 })), !themeOnly && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(_Divider, null), /*#__PURE__*/React.createElement(Body, {
454 prefixCls: baseClassName,
455 title: formatMessage({
456 id: 'app.setting.navigationmode'
457 })
458 }, /*#__PURE__*/React.createElement(BlockCheckbox, {
459 prefixCls: baseClassName,
460 value: layout,
461 key: "layout",
462 configType: "layout",
463 list: [{
464 key: 'side',
465 title: formatMessage({
466 id: 'app.setting.sidemenu'
467 })
468 }, {
469 key: 'top',
470 title: formatMessage({
471 id: 'app.setting.topmenu'
472 })
473 }, {
474 key: 'mix',
475 title: formatMessage({
476 id: 'app.setting.mixmenu'
477 })
478 }],
479 onChange: function onChange(value) {
480 return changeSetting('layout', value);
481 }
482 })), /*#__PURE__*/React.createElement(LayoutSetting, {
483 settings: settingState,
484 changeSetting: changeSetting
485 }), /*#__PURE__*/React.createElement(_Divider, null), /*#__PURE__*/React.createElement(Body, {
486 prefixCls: baseClassName,
487 title: formatMessage({
488 id: 'app.setting.regionalsettings'
489 })
490 }, /*#__PURE__*/React.createElement(RegionalSetting, {
491 settings: settingState,
492 changeSetting: changeSetting
493 })), /*#__PURE__*/React.createElement(_Divider, null), /*#__PURE__*/React.createElement(Body, {
494 prefixCls: baseClassName,
495 title: formatMessage({
496 id: 'app.setting.othersettings'
497 })
498 }, /*#__PURE__*/React.createElement(_List, {
499 split: false,
500 renderItem: renderLayoutSettingItem,
501 dataSource: [{
502 title: formatMessage({
503 id: 'app.setting.weakmode'
504 }),
505 action: /*#__PURE__*/React.createElement(_Switch, {
506 size: "small",
507 className: "color-weak",
508 checked: !!colorWeak,
509 onChange: function onChange(checked) {
510 changeSetting('colorWeak', checked);
511 }
512 })
513 }]
514 })), hideHintAlert && hideCopyButton ? null : /*#__PURE__*/React.createElement(_Divider, null), hideHintAlert ? null : /*#__PURE__*/React.createElement(_Alert, {
515 type: "warning",
516 message: formatMessage({
517 id: 'app.setting.production.hint'
518 }),
519 icon: /*#__PURE__*/React.createElement(NotificationOutlined, null),
520 showIcon: true,
521 style: {
522 marginBottom: 16
523 }
524 }), hideCopyButton ? null : /*#__PURE__*/React.createElement(_Button, {
525 block: true,
526 icon: /*#__PURE__*/React.createElement(CopyOutlined, null),
527 style: {
528 marginBottom: 24
529 },
530 onClick: /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
531 return _regeneratorRuntime().wrap(function _callee2$(_context2) {
532 while (1) {
533 switch (_context2.prev = _context2.next) {
534 case 0:
535 _context2.prev = 0;
536 _context2.next = 3;
537 return navigator.clipboard.writeText(genCopySettingJson(settingState));
538
539 case 3:
540 _message.success(formatMessage({
541 id: 'app.setting.copyinfo'
542 }));
543
544 _context2.next = 8;
545 break;
546
547 case 6:
548 _context2.prev = 6;
549 _context2.t0 = _context2["catch"](0);
550
551 case 8:
552 case "end":
553 return _context2.stop();
554 }
555 }
556 }, _callee2, null, [[0, 6]]);
557 }))
558 }, formatMessage({
559 id: 'app.setting.copy'
560 })))));
561};
562
563export default SettingDrawer;
\No newline at end of file