@zat-design/sisyphus-react 4.5.6-beta.1 → 4.5.6-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.css +1 -1
- package/dist/less.esm.css +1 -1
- package/es/ProConfigProvider/demo/locale.js +58 -0
- package/es/ProForm/components/base/RangePicker/index.js +2 -7
- package/es/ProForm/components/render/ConfirmWrapper.js +3 -2
- package/es/ProForm/components/render/RenderFields.js +1 -1
- package/es/ProLayout/components/ProHeader/PropTypes.d.ts +3 -3
- package/es/ProLayout/components/ProHeader/components/Describe/index.d.ts +26 -0
- package/es/ProLayout/components/ProHeader/components/Describe/index.js +109 -0
- package/es/ProLayout/components/ProHeader/index.js +54 -118
- package/es/ProLayout/components/ProHeader/utils/index.d.ts +15 -0
- package/es/ProLayout/components/ProHeader/utils/index.js +23 -1
- package/es/ProLayout/components/TabsManager/components/TabContextMenu.js +7 -5
- package/es/ProLayout/components/TabsManager/index.js +87 -3
- package/es/ProLayout/components/TabsManager/style/index.less +6 -3
- package/es/ProLayout/index.js +28 -10
- package/es/ProLayout/propTypes.d.ts +17 -0
- package/es/ProLayout/style/index.less +32 -0
- package/es/ProTable/components/RenderColumn/index.js +2 -1
- package/es/ProUpload/components/FileItem.js +4 -3
- package/es/locale/en_US.d.ts +9 -0
- package/es/locale/en_US.js +42 -33
- package/es/locale/zh_CN.d.ts +9 -0
- package/es/locale/zh_CN.js +13 -4
- package/package.json +3 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iframe: 400
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
import { Button, Space } from 'antd';
|
|
7
|
+
import { ProConfigProvider, ProForm } from '@zat-design/sisyphus-react';
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const LocaleDemo = () => {
|
|
10
|
+
const [locale, setLocale] = useState(localStorage.getItem('locale') || 'zh-CN');
|
|
11
|
+
const handleChange = value => {
|
|
12
|
+
setLocale(value);
|
|
13
|
+
localStorage.setItem('locale', value);
|
|
14
|
+
window.location.reload();
|
|
15
|
+
};
|
|
16
|
+
return /*#__PURE__*/_jsxs(Space, {
|
|
17
|
+
direction: "vertical",
|
|
18
|
+
size: 16,
|
|
19
|
+
style: {
|
|
20
|
+
width: '100%'
|
|
21
|
+
},
|
|
22
|
+
children: [/*#__PURE__*/_jsxs(Space, {
|
|
23
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
24
|
+
type: locale === 'zh-CN' ? 'primary' : 'default',
|
|
25
|
+
onClick: () => handleChange('zh-CN'),
|
|
26
|
+
children: "\u4E2D\u6587"
|
|
27
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
28
|
+
type: locale === 'en-US' ? 'primary' : 'default',
|
|
29
|
+
onClick: () => handleChange('en-US'),
|
|
30
|
+
children: "English"
|
|
31
|
+
})]
|
|
32
|
+
}), /*#__PURE__*/_jsx(ProConfigProvider, {
|
|
33
|
+
locale: locale,
|
|
34
|
+
children: /*#__PURE__*/_jsx(ProForm, {
|
|
35
|
+
columns: [{
|
|
36
|
+
type: 'Input',
|
|
37
|
+
label: locale === 'zh-CN' ? '姓名' : 'Name',
|
|
38
|
+
name: 'name',
|
|
39
|
+
required: true
|
|
40
|
+
}, {
|
|
41
|
+
type: 'Select',
|
|
42
|
+
label: locale === 'zh-CN' ? '状态' : 'Status',
|
|
43
|
+
name: 'status',
|
|
44
|
+
fieldProps: {
|
|
45
|
+
options: [{
|
|
46
|
+
label: locale === 'zh-CN' ? '启用' : 'Enabled',
|
|
47
|
+
value: '1'
|
|
48
|
+
}, {
|
|
49
|
+
label: locale === 'zh-CN' ? '禁用' : 'Disabled',
|
|
50
|
+
value: '0'
|
|
51
|
+
}]
|
|
52
|
+
}
|
|
53
|
+
}]
|
|
54
|
+
})
|
|
55
|
+
})]
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
export default LocaleDemo;
|
|
@@ -9,6 +9,7 @@ import dayjs from 'dayjs';
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { useProConfig } from "../../../../ProConfigProvider";
|
|
11
11
|
import locale from "../../../../locale";
|
|
12
|
+
import enUS from "../../../../locale/en_US";
|
|
12
13
|
import ProForm from "../../../../ProForm";
|
|
13
14
|
import Container from "../../Container";
|
|
14
15
|
import { useDateRange } from "./useDateRange";
|
|
@@ -35,13 +36,7 @@ const getDefaultFormat = picker => {
|
|
|
35
36
|
|
|
36
37
|
// 获取默认快捷选项(presets 格式)
|
|
37
38
|
const getDefaultPresets = () => {
|
|
38
|
-
const rangeLabels = locale?.RangePicker?.ranges ||
|
|
39
|
-
today: '今天',
|
|
40
|
-
lastWeek: '近1周',
|
|
41
|
-
lastMonth: '近1月',
|
|
42
|
-
last3Months: '近3月',
|
|
43
|
-
lastYear: '近1年'
|
|
44
|
-
};
|
|
39
|
+
const rangeLabels = locale?.RangePicker?.ranges || enUS.RangePicker.ranges;
|
|
45
40
|
return [{
|
|
46
41
|
label: rangeLabels.today,
|
|
47
42
|
value: [dayjs().startOf('day'), dayjs().endOf('day')]
|
|
@@ -3,10 +3,11 @@ import _isFunction from "lodash/isFunction";
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Modal } from 'antd';
|
|
5
5
|
import ProForm from "../../index";
|
|
6
|
+
import locale from "../../../locale";
|
|
6
7
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
7
8
|
const defaultConfirmProps = {
|
|
8
|
-
title:
|
|
9
|
-
content:
|
|
9
|
+
title: locale.ProForm.confirmTitle,
|
|
10
|
+
content: locale.ProForm.confirmContent
|
|
10
11
|
};
|
|
11
12
|
const ConfirmWrapper = props => {
|
|
12
13
|
const {
|
|
@@ -115,7 +115,7 @@ const RenderFields = props => {
|
|
|
115
115
|
}
|
|
116
116
|
if (component && /*#__PURE__*/React.isValidElement(component)) {
|
|
117
117
|
const newComponent = component;
|
|
118
|
-
const isProEditTable = newComponent?.props?.onlyOneLineMsg
|
|
118
|
+
const isProEditTable = newComponent?.props?.onlyOneLineMsg != null;
|
|
119
119
|
TargetComponent = _isView ? viewRenderHandle || '' : component;
|
|
120
120
|
// 可编辑表格内部支持
|
|
121
121
|
if (isProEditTable) {
|
|
@@ -172,7 +172,7 @@ export interface ProHeaderType {
|
|
|
172
172
|
*/
|
|
173
173
|
fixedTop?: string | number;
|
|
174
174
|
/**
|
|
175
|
-
* @description
|
|
175
|
+
* @description 是否显示返回按钮。显式传值优先;不传时若有 onBack 则显示,否则由 autoBack 按浏览器历史长度判断
|
|
176
176
|
* @default -
|
|
177
177
|
*/
|
|
178
178
|
showBack?: boolean;
|
|
@@ -198,8 +198,8 @@ export interface ProHeaderType {
|
|
|
198
198
|
*/
|
|
199
199
|
zIndex?: number;
|
|
200
200
|
/**
|
|
201
|
-
* @description
|
|
202
|
-
* @default
|
|
201
|
+
* @description 返回按钮点击回调;不传时默认执行 window.history.back()
|
|
202
|
+
* @default -
|
|
203
203
|
*/
|
|
204
204
|
onBack?: () => void;
|
|
205
205
|
[key: string]: any;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { DescribeColumnType } from '../../PropTypes';
|
|
3
|
+
/** 描述项里的单条值(link / copyable / tag 组合),对应 items 数组元素 */
|
|
4
|
+
type DescribeValueItem = Pick<DescribeColumnType, 'tag' | 'link' | 'value' | 'copyable'>;
|
|
5
|
+
/**
|
|
6
|
+
* 标签渲染:数组 tag 逐个渲染,单值渲染一个,空则不渲染
|
|
7
|
+
*/
|
|
8
|
+
export declare const DescribeTag: ({ tag, parentKey, }: {
|
|
9
|
+
tag?: DescribeColumnType["tag"];
|
|
10
|
+
parentKey: string;
|
|
11
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
/**
|
|
13
|
+
* 单行值渲染:link → <a>,copyable+字符串 → 复制按钮,末尾追加 tag
|
|
14
|
+
*/
|
|
15
|
+
export declare const DescribeValue: ({ value, link, copyable, tag, parentKey, }: DescribeValueItem & {
|
|
16
|
+
parentKey: string;
|
|
17
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
/**
|
|
19
|
+
* 多值渲染:以「、」连接;超 3 个显示「共N个,」前缀;内容溢出时显示「...」并用 Tooltip 展示全部
|
|
20
|
+
*/
|
|
21
|
+
export declare const DescribeItems: ({ items, parentKey, containerRef, }: {
|
|
22
|
+
items: DescribeValueItem[];
|
|
23
|
+
parentKey: string;
|
|
24
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
25
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import _isString from "lodash/isString";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Space, Tooltip } from 'antd';
|
|
4
|
+
import classnames from 'classnames';
|
|
5
|
+
import Copy from "../Copy";
|
|
6
|
+
import { checkDescribeItemsHidden, getTagKey, getDescribeValueKey } from "../../utils";
|
|
7
|
+
import locale, { formatMessage } from "../../../../../locale";
|
|
8
|
+
|
|
9
|
+
/** 描述项里的单条值(link / copyable / tag 组合),对应 items 数组元素 */
|
|
10
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
|
+
/**
|
|
12
|
+
* 标签渲染:数组 tag 逐个渲染,单值渲染一个,空则不渲染
|
|
13
|
+
*/
|
|
14
|
+
export const DescribeTag = ({
|
|
15
|
+
tag,
|
|
16
|
+
parentKey
|
|
17
|
+
}) => {
|
|
18
|
+
if (Array.isArray(tag) && tag.length) {
|
|
19
|
+
return /*#__PURE__*/_jsx(Space, {
|
|
20
|
+
size: 4,
|
|
21
|
+
children: tag.map((tagItem, tagIndex) => /*#__PURE__*/_jsx("div", {
|
|
22
|
+
className: "pro-header-tag",
|
|
23
|
+
children: tagItem
|
|
24
|
+
}, getTagKey(tagItem, parentKey, tagIndex)))
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return tag ? /*#__PURE__*/_jsx("div", {
|
|
28
|
+
className: "pro-header-tag",
|
|
29
|
+
children: tag
|
|
30
|
+
}) : null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 单行值渲染:link → <a>,copyable+字符串 → 复制按钮,末尾追加 tag
|
|
35
|
+
*/
|
|
36
|
+
export const DescribeValue = ({
|
|
37
|
+
value,
|
|
38
|
+
link,
|
|
39
|
+
copyable,
|
|
40
|
+
tag,
|
|
41
|
+
parentKey
|
|
42
|
+
}) => {
|
|
43
|
+
return /*#__PURE__*/_jsxs(Space, {
|
|
44
|
+
size: 4,
|
|
45
|
+
align: tag ? 'baseline' : 'center',
|
|
46
|
+
children: [link ? /*#__PURE__*/_jsx("a", {
|
|
47
|
+
onClick: () => {
|
|
48
|
+
const newWindow = window.open(link);
|
|
49
|
+
newWindow.opener = null;
|
|
50
|
+
},
|
|
51
|
+
children: value
|
|
52
|
+
}) : value, copyable && _isString(value) ? /*#__PURE__*/_jsx(Copy, {
|
|
53
|
+
text: value
|
|
54
|
+
}) : null, /*#__PURE__*/_jsx(DescribeTag, {
|
|
55
|
+
tag: tag,
|
|
56
|
+
parentKey: parentKey
|
|
57
|
+
})]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 多值渲染:以「、」连接;超 3 个显示「共N个,」前缀;内容溢出时显示「...」并用 Tooltip 展示全部
|
|
63
|
+
*/
|
|
64
|
+
export const DescribeItems = ({
|
|
65
|
+
items,
|
|
66
|
+
parentKey,
|
|
67
|
+
containerRef
|
|
68
|
+
}) => {
|
|
69
|
+
// items 配置是否超长,超长则展示 ... + tip 提示
|
|
70
|
+
const itemsHidden = checkDescribeItemsHidden(containerRef?.current);
|
|
71
|
+
const result = /*#__PURE__*/_jsxs("div", {
|
|
72
|
+
ref: containerRef,
|
|
73
|
+
className: classnames({
|
|
74
|
+
'pro-header-describe-items': true,
|
|
75
|
+
'pro-header-describe-items-more': items.length >= 2
|
|
76
|
+
}),
|
|
77
|
+
children: [items?.length > 3 ? formatMessage(locale.ProHeader.itemsCountPrefix, {
|
|
78
|
+
count: items.length
|
|
79
|
+
}) : null, items.map((item, itemIndex) => /*#__PURE__*/_jsxs("span", {
|
|
80
|
+
children: [/*#__PURE__*/_jsx(DescribeValue, {
|
|
81
|
+
...item,
|
|
82
|
+
parentKey: parentKey
|
|
83
|
+
}), items?.length !== itemIndex + 1 ? locale.ProHeader.itemsSeparator : null]
|
|
84
|
+
}, getDescribeValueKey(item, parentKey, itemIndex))), itemsHidden ? /*#__PURE__*/_jsx("span", {
|
|
85
|
+
className: "pro-header-describe-items-omit",
|
|
86
|
+
children: "..."
|
|
87
|
+
}) : null]
|
|
88
|
+
});
|
|
89
|
+
if (itemsHidden) {
|
|
90
|
+
const tipResult = /*#__PURE__*/_jsx(_Fragment, {
|
|
91
|
+
children: items.map((item, itemIndex) => /*#__PURE__*/_jsx("p", {
|
|
92
|
+
className: "pro-header-describe-items-tip-value",
|
|
93
|
+
children: /*#__PURE__*/_jsx(DescribeValue, {
|
|
94
|
+
...item,
|
|
95
|
+
parentKey: parentKey
|
|
96
|
+
})
|
|
97
|
+
}, getDescribeValueKey(item, parentKey, itemIndex)))
|
|
98
|
+
});
|
|
99
|
+
return /*#__PURE__*/_jsx(Tooltip, {
|
|
100
|
+
placement: "bottomLeft",
|
|
101
|
+
classNames: {
|
|
102
|
+
root: 'pro-header-describe-items-tip'
|
|
103
|
+
},
|
|
104
|
+
title: tipResult,
|
|
105
|
+
children: result
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
};
|
|
@@ -7,26 +7,18 @@ import React, { memo, useEffect, useState, useRef } from 'react';
|
|
|
7
7
|
import { tools } from '@zat-design/utils';
|
|
8
8
|
import classnames from 'classnames';
|
|
9
9
|
import dayjs from 'dayjs';
|
|
10
|
-
import { useToggle
|
|
10
|
+
import { useToggle } from 'ahooks';
|
|
11
11
|
import { ReactSVG } from 'react-svg';
|
|
12
12
|
import foldSvg from "../../../assets/arrow.svg";
|
|
13
13
|
import { Copy, ProBackBtn } from "./components";
|
|
14
|
+
import { DescribeItems, DescribeValue } from "./components/Describe";
|
|
14
15
|
import getEnumLabel from "../../../ProEnum/utils/getEnumLabel";
|
|
15
16
|
import locale from "../../../locale";
|
|
16
|
-
import {
|
|
17
|
+
import { toKeyPart, getDescribeColumnKey, getTagKey, getSubDescribeKey } from "./utils";
|
|
17
18
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
18
19
|
const {
|
|
19
20
|
formatAmount
|
|
20
21
|
} = tools;
|
|
21
|
-
const toKeyPart = value => {
|
|
22
|
-
if (value == null || value === '') return undefined;
|
|
23
|
-
if (typeof value === 'string' || typeof value === 'number') return String(value);
|
|
24
|
-
return undefined;
|
|
25
|
-
};
|
|
26
|
-
const getDescribeColumnKey = (item, index) => toKeyPart(item.label) ?? toKeyPart(item.value) ?? `describe-${index}`;
|
|
27
|
-
const getDescribeValueKey = (item, parentKey, index) => toKeyPart(item.link) ?? toKeyPart(item.value) ?? `${parentKey}-value-${index}`;
|
|
28
|
-
const getTagKey = (tagItem, parentKey, index) => toKeyPart(tagItem) ?? `${parentKey}-tag-${index}`;
|
|
29
|
-
const getSubDescribeKey = (item, index) => toKeyPart(item.label) ?? toKeyPart(item.code) ?? `sub-describe-${index}`;
|
|
30
22
|
const ProHeader = props => {
|
|
31
23
|
const {
|
|
32
24
|
breadcrumbColumns,
|
|
@@ -37,7 +29,6 @@ const ProHeader = props => {
|
|
|
37
29
|
className,
|
|
38
30
|
bodyOverFlowHidden = false,
|
|
39
31
|
fixedTop,
|
|
40
|
-
showBack = true,
|
|
41
32
|
showShadow = false,
|
|
42
33
|
zIndex = 98,
|
|
43
34
|
title,
|
|
@@ -47,19 +38,32 @@ const ProHeader = props => {
|
|
|
47
38
|
isConfirmBack = false,
|
|
48
39
|
isConfirmBackModalProps = {}
|
|
49
40
|
} = props;
|
|
50
|
-
|
|
41
|
+
|
|
42
|
+
// 返回按钮是否显示。
|
|
43
|
+
// 显式意图优先于 autoBack 启发式:
|
|
44
|
+
// 1) 用户显式传了 showBack → 完全尊重该值;
|
|
45
|
+
// 2) 传了 onBack(返回不依赖浏览器历史,如 tab 内返回 / 自定义跳转)→ 显示;
|
|
46
|
+
// 3) 都没传(纯默认,返回兜底走 window.history.back)→ 由 autoBack 按历史长度智能判断:
|
|
47
|
+
// 新开页面(history.length <= autoBack)无处可返回,则隐藏。
|
|
48
|
+
const computeBackState = () => {
|
|
49
|
+
if (props.showBack !== undefined) return props.showBack;
|
|
50
|
+
if (onBack) return true;
|
|
51
|
+
return window.history.length > autoBack;
|
|
52
|
+
};
|
|
53
|
+
const [backState, setBackState] = useState(computeBackState);
|
|
51
54
|
const [fold, {
|
|
52
55
|
toggle
|
|
53
56
|
}] = useToggle(collapsed);
|
|
54
57
|
const ref = useRef(null);
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
|
|
59
|
+
// 最终用于渲染的标题(title + showBack 时会被转成面包屑,此处置空)
|
|
60
|
+
let finalTitle = title;
|
|
57
61
|
|
|
58
62
|
// 面包屑配置数据源
|
|
59
|
-
const
|
|
63
|
+
const finalBreadcrumbColumns = breadcrumbColumns || [];
|
|
60
64
|
|
|
61
65
|
// 次级配置数据源
|
|
62
|
-
const
|
|
66
|
+
const finalSubDescribeColumns = subDescribeColumns || [];
|
|
63
67
|
useEffect(() => {
|
|
64
68
|
if (bodyOverFlowHidden) {
|
|
65
69
|
const bodyElement = document.querySelector('body');
|
|
@@ -70,13 +74,11 @@ const ProHeader = props => {
|
|
|
70
74
|
bodyElement.style.overflow = '';
|
|
71
75
|
};
|
|
72
76
|
}, [bodyOverFlowHidden]);
|
|
77
|
+
|
|
78
|
+
// showBack / onBack / autoBack 变化时同步 backState(避免 props 更新后按钮显隐不同步)
|
|
73
79
|
useEffect(() => {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (isNewPage <= autoBack) {
|
|
77
|
-
setBackState(false);
|
|
78
|
-
}
|
|
79
|
-
}, []);
|
|
80
|
+
setBackState(computeBackState());
|
|
81
|
+
}, [props.showBack, onBack, autoBack]);
|
|
80
82
|
|
|
81
83
|
/**
|
|
82
84
|
* 主级描述数据渲染
|
|
@@ -108,82 +110,6 @@ const ProHeader = props => {
|
|
|
108
110
|
return null;
|
|
109
111
|
}
|
|
110
112
|
const onlyTag = tag && !label && !value;
|
|
111
|
-
const tagRender = params => {
|
|
112
|
-
if (Array.isArray(params?.tag) && params?.tag.length) {
|
|
113
|
-
return /*#__PURE__*/_jsx(Space, {
|
|
114
|
-
size: 4,
|
|
115
|
-
children: params.tag.map((tagItem, tagIndex) => {
|
|
116
|
-
return /*#__PURE__*/_jsx("div", {
|
|
117
|
-
className: "pro-header-tag",
|
|
118
|
-
children: tagItem
|
|
119
|
-
}, getTagKey(tagItem, describeItemKey, tagIndex));
|
|
120
|
-
})
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
return params?.tag ? /*#__PURE__*/_jsx("div", {
|
|
124
|
-
className: "pro-header-tag",
|
|
125
|
-
children: params?.tag
|
|
126
|
-
}) : null;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
/** 单行渲染 */
|
|
130
|
-
const valueRender = params => {
|
|
131
|
-
return /*#__PURE__*/_jsxs(Space, {
|
|
132
|
-
size: 4,
|
|
133
|
-
align: params?.tag ? 'baseline' : 'center',
|
|
134
|
-
children: [params?.link ? /*#__PURE__*/_jsx("a", {
|
|
135
|
-
onClick: () => {
|
|
136
|
-
const newWindow = window.open(params.link);
|
|
137
|
-
newWindow.opener = null;
|
|
138
|
-
},
|
|
139
|
-
children: params?.value
|
|
140
|
-
}) : params?.value, params?.copyable && _isString(params?.value) ? /*#__PURE__*/_jsx(Copy, {
|
|
141
|
-
text: params.value
|
|
142
|
-
}) : null, tagRender({
|
|
143
|
-
tag: params?.tag
|
|
144
|
-
})]
|
|
145
|
-
});
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
/** 多行渲染 */
|
|
149
|
-
const itemsRender = () => {
|
|
150
|
-
// items配置是否超长,超长配置... + tip 提示
|
|
151
|
-
const itemsHidden = checkDescribeItemsHidden(ref?.current);
|
|
152
|
-
const result = /*#__PURE__*/_jsxs("div", {
|
|
153
|
-
ref: ref,
|
|
154
|
-
className: classnames({
|
|
155
|
-
'pro-header-describe-items': true,
|
|
156
|
-
'pro-header-describe-items-more': items.length >= 2
|
|
157
|
-
}),
|
|
158
|
-
children: [items?.length > 3 ? `共${items?.length}个,` : null, items.map((item, itemIndex) => {
|
|
159
|
-
return /*#__PURE__*/_jsxs("span", {
|
|
160
|
-
children: [valueRender(item), items?.length !== itemIndex + 1 ? ' 、' : null]
|
|
161
|
-
}, getDescribeValueKey(item, describeItemKey, itemIndex));
|
|
162
|
-
}), itemsHidden ? /*#__PURE__*/_jsx("span", {
|
|
163
|
-
className: "pro-header-describe-items-omit",
|
|
164
|
-
children: "..."
|
|
165
|
-
}) : null]
|
|
166
|
-
});
|
|
167
|
-
if (itemsHidden) {
|
|
168
|
-
const tipResult = /*#__PURE__*/_jsx(_Fragment, {
|
|
169
|
-
children: items.map((item, itemIndex) => {
|
|
170
|
-
return /*#__PURE__*/_jsx("p", {
|
|
171
|
-
className: "pro-header-describe-items-tip-value",
|
|
172
|
-
children: valueRender(item)
|
|
173
|
-
}, getDescribeValueKey(item, describeItemKey, itemIndex));
|
|
174
|
-
})
|
|
175
|
-
});
|
|
176
|
-
return /*#__PURE__*/_jsx(Tooltip, {
|
|
177
|
-
placement: "bottomLeft",
|
|
178
|
-
classNames: {
|
|
179
|
-
root: 'pro-header-describe-items-tip'
|
|
180
|
-
},
|
|
181
|
-
title: tipResult,
|
|
182
|
-
children: result
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
return result;
|
|
186
|
-
};
|
|
187
113
|
const tagCls = classnames({
|
|
188
114
|
'pro-header-only-tag': onlyTag,
|
|
189
115
|
'pro-header-describe-items-calc': _isString(width) ? width.includes('calc') : false
|
|
@@ -200,12 +126,17 @@ const ProHeader = props => {
|
|
|
200
126
|
children: label
|
|
201
127
|
}) : null, /*#__PURE__*/_jsx("span", {
|
|
202
128
|
className: "pro-header-describe-value",
|
|
203
|
-
children: items?.length ?
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
129
|
+
children: items?.length ? /*#__PURE__*/_jsx(DescribeItems, {
|
|
130
|
+
items: items,
|
|
131
|
+
parentKey: describeItemKey,
|
|
132
|
+
containerRef: ref
|
|
133
|
+
}) : /*#__PURE__*/_jsx("span", {
|
|
134
|
+
children: /*#__PURE__*/_jsx(DescribeValue, {
|
|
135
|
+
value: value,
|
|
136
|
+
copyable: copyable,
|
|
137
|
+
tag: tag,
|
|
138
|
+
link: link,
|
|
139
|
+
parentKey: describeItemKey
|
|
209
140
|
})
|
|
210
141
|
})
|
|
211
142
|
})]
|
|
@@ -302,10 +233,10 @@ const ProHeader = props => {
|
|
|
302
233
|
* 总结信息面板渲染
|
|
303
234
|
*/
|
|
304
235
|
const breadcrumbRender = () => {
|
|
305
|
-
if (Array.isArray(
|
|
236
|
+
if (Array.isArray(finalBreadcrumbColumns) && !finalBreadcrumbColumns.length) {
|
|
306
237
|
return [];
|
|
307
238
|
}
|
|
308
|
-
const list =
|
|
239
|
+
const list = finalBreadcrumbColumns?.filter(item => {
|
|
309
240
|
return item.type === 'breadcrumb';
|
|
310
241
|
});
|
|
311
242
|
return list.map((item, index) => {
|
|
@@ -355,10 +286,10 @@ const ProHeader = props => {
|
|
|
355
286
|
* 头部左侧导航栏后业务信息
|
|
356
287
|
*/
|
|
357
288
|
const infoRender = () => {
|
|
358
|
-
if (!Array.isArray(
|
|
289
|
+
if (!Array.isArray(finalBreadcrumbColumns)) {
|
|
359
290
|
return '';
|
|
360
291
|
}
|
|
361
|
-
const list =
|
|
292
|
+
const list = finalBreadcrumbColumns?.filter(item => {
|
|
362
293
|
return item.type !== 'breadcrumb';
|
|
363
294
|
});
|
|
364
295
|
if (!list.length) {
|
|
@@ -436,24 +367,29 @@ const ProHeader = props => {
|
|
|
436
367
|
})
|
|
437
368
|
});
|
|
438
369
|
};
|
|
370
|
+
|
|
371
|
+
// 说明:以下两个 class 的判断沿用原有等价逻辑(去掉了原表达式里对 describeColumns 的重复判断)。
|
|
372
|
+
// has = 有次级描述 或 有主级描述;no = 无主级描述。二者非严格互斥(原实现即如此,未改动其行为)。
|
|
373
|
+
const noDescribe = _isEmpty(describeColumns);
|
|
374
|
+
const hasDescribe = !_isEmpty(finalSubDescribeColumns) || !noDescribe;
|
|
439
375
|
const cls = classnames({
|
|
440
376
|
'pro-header': true,
|
|
441
377
|
'pro-header-fixed': fixedTop,
|
|
442
378
|
'pro-header-shadow': showShadow,
|
|
443
379
|
// 内部窗口滚动自带阴影场景
|
|
444
380
|
'pro-header-no-back': !backState,
|
|
445
|
-
'pro-header-has-describe':
|
|
446
|
-
'pro-header-no-describe':
|
|
381
|
+
'pro-header-has-describe': hasDescribe,
|
|
382
|
+
'pro-header-no-describe': noDescribe,
|
|
447
383
|
[`${className}`]: className
|
|
448
384
|
});
|
|
449
|
-
if (title && !_isEmpty(
|
|
385
|
+
if (title && !_isEmpty(finalBreadcrumbColumns)) {
|
|
450
386
|
console.error('warning: The title and the breadcrumbList cannot be used together');
|
|
451
387
|
}
|
|
452
388
|
|
|
453
389
|
// title默认不显示返回按钮,只有showBack设置为true时才显示
|
|
454
390
|
if (title && props.showBack) {
|
|
455
|
-
|
|
456
|
-
|
|
391
|
+
finalTitle = null;
|
|
392
|
+
finalBreadcrumbColumns.push({
|
|
457
393
|
type: 'breadcrumb',
|
|
458
394
|
value: title
|
|
459
395
|
});
|
|
@@ -492,9 +428,9 @@ const ProHeader = props => {
|
|
|
492
428
|
top: fixedTop,
|
|
493
429
|
zIndex
|
|
494
430
|
},
|
|
495
|
-
children:
|
|
431
|
+
children: finalTitle ? /*#__PURE__*/_jsx("div", {
|
|
496
432
|
className: "pro-header-title",
|
|
497
|
-
children:
|
|
433
|
+
children: finalTitle
|
|
498
434
|
}) : /*#__PURE__*/_jsxs(_Fragment, {
|
|
499
435
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
500
436
|
className: "pro-header-top",
|
|
@@ -516,14 +452,14 @@ const ProHeader = props => {
|
|
|
516
452
|
className: "pro-header-right",
|
|
517
453
|
children: actionsRender()
|
|
518
454
|
})]
|
|
519
|
-
}), describeRender(describeColumns), !_isEmpty(
|
|
455
|
+
}), describeRender(describeColumns), !_isEmpty(finalSubDescribeColumns) ? /*#__PURE__*/_jsxs("div", {
|
|
520
456
|
className: classnames({
|
|
521
457
|
'pro-header-nav': true,
|
|
522
458
|
'pro-header-nav-open': fold,
|
|
523
459
|
'pro-header-nav-hidden': !fold
|
|
524
460
|
}),
|
|
525
461
|
children: [/*#__PURE__*/_jsx("ul", {
|
|
526
|
-
children:
|
|
462
|
+
children: finalSubDescribeColumns.map((item, index) => {
|
|
527
463
|
return /*#__PURE__*/_jsx("li", {
|
|
528
464
|
children: subDescribeRender(item)
|
|
529
465
|
}, getSubDescribeKey(item, index));
|
|
@@ -1,5 +1,20 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { DescribeColumnType, SubDescribeColumnType } from '../PropTypes';
|
|
1
3
|
/**
|
|
2
4
|
* 检查描述dom是否部分隐藏
|
|
3
5
|
* @param ele dom节点
|
|
4
6
|
*/
|
|
5
7
|
export declare const checkDescribeItemsHidden: (ele?: any) => boolean;
|
|
8
|
+
/**
|
|
9
|
+
* 将值转为可用于 React key 的字符串片段
|
|
10
|
+
* 仅 string / number 有效,其余(含 ReactNode、对象、数组、boolean)返回 undefined
|
|
11
|
+
*/
|
|
12
|
+
export declare const toKeyPart: (value: unknown) => string | undefined;
|
|
13
|
+
/** 主级描述项 key:label → value → describe-${index} */
|
|
14
|
+
export declare const getDescribeColumnKey: (item: DescribeColumnType, index: number) => string;
|
|
15
|
+
/** 描述值 key:link → value → ${parentKey}-value-${index} */
|
|
16
|
+
export declare const getDescribeValueKey: (item: Pick<DescribeColumnType, "tag" | "link" | "value" | "copyable">, parentKey: string, index: number) => string;
|
|
17
|
+
/** 标签 key:tagItem → ${parentKey}-tag-${index} */
|
|
18
|
+
export declare const getTagKey: (tagItem: string | React.ReactNode, parentKey: string, index: number) => string;
|
|
19
|
+
/** 次级描述项 key:label → code → sub-describe-${index} */
|
|
20
|
+
export declare const getSubDescribeKey: (item: SubDescribeColumnType, index: number) => string;
|
|
@@ -11,4 +11,26 @@ export const checkDescribeItemsHidden = ele => {
|
|
|
11
11
|
const itemsScrollWidth = element.scrollWidth;
|
|
12
12
|
const itemsClientWidth = element.clientWidth;
|
|
13
13
|
return itemsScrollWidth > itemsClientWidth;
|
|
14
|
-
};
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 将值转为可用于 React key 的字符串片段
|
|
18
|
+
* 仅 string / number 有效,其余(含 ReactNode、对象、数组、boolean)返回 undefined
|
|
19
|
+
*/
|
|
20
|
+
export const toKeyPart = value => {
|
|
21
|
+
if (value == null || value === '') return undefined;
|
|
22
|
+
if (typeof value === 'string' || typeof value === 'number') return String(value);
|
|
23
|
+
return undefined;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** 主级描述项 key:label → value → describe-${index} */
|
|
27
|
+
export const getDescribeColumnKey = (item, index) => toKeyPart(item.label) ?? toKeyPart(item.value) ?? `describe-${index}`;
|
|
28
|
+
|
|
29
|
+
/** 描述值 key:link → value → ${parentKey}-value-${index} */
|
|
30
|
+
export const getDescribeValueKey = (item, parentKey, index) => toKeyPart(item.link) ?? toKeyPart(item.value) ?? `${parentKey}-value-${index}`;
|
|
31
|
+
|
|
32
|
+
/** 标签 key:tagItem → ${parentKey}-tag-${index} */
|
|
33
|
+
export const getTagKey = (tagItem, parentKey, index) => toKeyPart(tagItem) ?? `${parentKey}-tag-${index}`;
|
|
34
|
+
|
|
35
|
+
/** 次级描述项 key:label → code → sub-describe-${index} */
|
|
36
|
+
export const getSubDescribeKey = (item, index) => toKeyPart(item.label) ?? toKeyPart(item.code) ?? `sub-describe-${index}`;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useState, useCallback } from 'react';
|
|
2
2
|
import { Dropdown } from 'antd';
|
|
3
|
-
import
|
|
3
|
+
import locale from "../../../../locale";
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* 右键菜单组件 - 兼容Antd 4.x和5.x
|
|
6
7
|
*/
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
9
|
function TabContextMenu({
|
|
8
10
|
tabId,
|
|
9
11
|
children,
|
|
@@ -53,17 +55,17 @@ function TabContextMenu({
|
|
|
53
55
|
// 默认右键菜单配置 - 统一使用items方式(antd 4.20+都支持)
|
|
54
56
|
const defaultMenuItems = [{
|
|
55
57
|
key: 'close',
|
|
56
|
-
label:
|
|
58
|
+
label: locale.ProLayout.tabMenuClose,
|
|
57
59
|
disabled: !closable
|
|
58
60
|
}, {
|
|
59
61
|
key: 'closeOthers',
|
|
60
|
-
label:
|
|
62
|
+
label: locale.ProLayout.tabMenuCloseOthers
|
|
61
63
|
}, {
|
|
62
64
|
key: 'closeRight',
|
|
63
|
-
label:
|
|
65
|
+
label: locale.ProLayout.tabMenuCloseRight
|
|
64
66
|
}, {
|
|
65
67
|
key: 'closeAll',
|
|
66
|
-
label:
|
|
68
|
+
label: locale.ProLayout.tabMenuCloseAll
|
|
67
69
|
}];
|
|
68
70
|
|
|
69
71
|
// 合并自定义菜单项和默认菜单项
|