cfel-base-components 2.5.53 → 2.5.55

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.
@@ -150,7 +150,25 @@ export default function LiosLayout(props: LiosLayoutlProps) {
150
150
  })
151
151
 
152
152
  const onOpenChange: MenuProps['onOpenChange'] = (keys) => {
153
- setOpenKeys(keys)
153
+ // Find the last opened key
154
+ const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1)
155
+
156
+ if (latestOpenKey) {
157
+ // If opening a new key
158
+ const rootSubmenuKeys = menuList.map((item) => item.key)
159
+
160
+ if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
161
+ // If it's a third level menu, only keep its parent menu open
162
+ const parentKey = keys.find((key) => rootSubmenuKeys.includes(key))
163
+ setOpenKeys(parentKey ? [parentKey, latestOpenKey] : [latestOpenKey])
164
+ } else {
165
+ // If it's a second level menu, only keep it open
166
+ setOpenKeys([latestOpenKey])
167
+ }
168
+ } else {
169
+ // If closing a menu
170
+ setOpenKeys(keys)
171
+ }
154
172
  }
155
173
 
156
174
  const copyTextToClipboard = async (text: string, key: string) => {
@@ -204,6 +222,7 @@ export default function LiosLayout(props: LiosLayoutlProps) {
204
222
  setCollapsed(value)
205
223
  }}
206
224
  >
225
+ <div className="layout-side-mask1-console"></div>
207
226
  <div className="layout-side-mask2-console"></div>
208
227
 
209
228
  <div className="header-logo-console" style={{ justifyContent: collapsed ? 'center' : '', paddingLeft: collapsed ? '0' : '' }}>
@@ -217,16 +236,16 @@ export default function LiosLayout(props: LiosLayoutlProps) {
217
236
  {/* {collapsed && <img className={`logo-base sub-logo`} src={logo || subLogoUrl} />} */}
218
237
  </div>
219
238
 
220
- {/* {!collapsed && (
239
+ {!collapsed && (
221
240
  <div
222
- className='trigger'
241
+ className="trigger-console"
223
242
  onClick={() => {
224
243
  setCollapsed(true)
225
244
  }}
226
245
  >
227
246
  <Arrow collapsed={true} type={type} />
228
247
  </div>
229
- )} */}
248
+ )}
230
249
  </div>
231
250
 
232
251
  {collapsed && (
@@ -274,9 +293,26 @@ export default function LiosLayout(props: LiosLayoutlProps) {
274
293
  if (isSelected) {
275
294
  classNames += ' submenu-selected'
276
295
  }
296
+ if (collapsed) {
297
+ return (
298
+ <Popover placement="right" arrow={false} content={<div>123</div>} trigger="hover">
299
+ <SubMenu
300
+ key={item.key}
301
+ className="menu-item-content"
302
+ title={
303
+ <div className="sub-list">
304
+ <div className="menu-item-inner">
305
+ <span className={`menu-item-icon ${isSelected ? 'submenu-selected' : ''}`}>{item.icon}</span>
306
+ {!collapsed && <span className={classNames}>{item.label}</span>}
307
+ </div>
308
+ </div>
309
+ }
310
+ ></SubMenu>
311
+ </Popover>
312
+ )
313
+ }
277
314
  return (
278
315
  <SubMenu
279
- popupClassName="rc-menu-submenu-popup"
280
316
  key={item.key}
281
317
  className="menu-item-content"
282
318
  title={
@@ -299,7 +335,6 @@ export default function LiosLayout(props: LiosLayoutlProps) {
299
335
  if (child.children) {
300
336
  return (
301
337
  <SubMenu
302
- popupClassName="rc-menu-submenu-popup"
303
338
  className="menu-item-content sub-li"
304
339
  key={child.key}
305
340
  title={<div className="sub-list">{!collapsed && <span className={`menu-item-label ${isSelected ? 'submenu-selected' : ''}`}>{child.label}</span>}</div>}
@@ -417,7 +452,7 @@ function Arrow({ collapsed, type }: { collapsed?: boolean; type?: string }) {
417
452
  return (
418
453
  <svg style={{ transform: !collapsed ? 'rotate(180deg)' : 'rotate(0deg)' }} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
419
454
  <path
420
- fill="FFFFFF"
455
+ fill="#FFFFFF"
421
456
  d="M564.6336 775.168a41.5744 41.5744 0 0 0-13.312-28.672l-230.4-234.4448 229.9904-234.1888a42.0864 42.0864 0 0 0-26.3168-73.0112 42.0864 42.0864 0 0 0-30.6176 11.264L231.0656 481.024a41.984 41.984 0 0 0-2.4576 59.5968l1.9968 2.048 263.7824 265.6256a41.984 41.984 0 0 0 70.2464-33.0752z m254.5152 0a41.472 41.472 0 0 0-13.312-28.672L575.488 512l229.9904-234.1376a41.984 41.984 0 1 0-56.9344-61.7984L485.632 480.9728a42.0864 42.0864 0 0 0-2.4064 59.6992l0.8704 0.9216 0.8704 0.8192 0.4096 0.4096 263.5776 265.4208a41.984 41.984 0 0 0 70.1952-33.0752z"
422
457
  ></path>
423
458
  </svg>
@@ -455,9 +490,20 @@ function Search({ menuList, collapsed, type, umiHistory, setSelectKey, findKeyPa
455
490
  }
456
491
  }
457
492
 
493
+ const handleClickOutside = (event: MouseEvent) => {
494
+ console.log(1)
495
+ const searchContainer = document.querySelector('.search-container')
496
+ if (searchContainer && !searchContainer.contains(event.target as Node)) {
497
+ setIsFocused(false)
498
+ }
499
+ }
500
+
458
501
  document.addEventListener('keydown', handleKeyDown)
502
+ document.addEventListener('mousedown', handleClickOutside)
503
+
459
504
  return () => {
460
505
  document.removeEventListener('keydown', handleKeyDown)
506
+ document.removeEventListener('mousedown', handleClickOutside)
461
507
  }
462
508
  }, [])
463
509
 
@@ -541,7 +587,7 @@ function Search({ menuList, collapsed, type, umiHistory, setSelectKey, findKeyPa
541
587
  </div>
542
588
  </div>
543
589
  ) : (
544
- <div>
590
+ <div className="search-container">
545
591
  <div className="search-console">
546
592
  <div className="search-bg-mask">
547
593
  <img src="https://cfel-front.oss-cn-hangzhou.aliyuncs.com/logo/base-component/menu-search-bg-console.png" />
@@ -189,7 +189,6 @@ export default function AccountInfo() {
189
189
  </Divider>
190
190
  <Descriptions className='basicInfoWrap'>
191
191
  <Descriptions.Item label="账号">{accountInfo?.account || ''}</Descriptions.Item>
192
- <Descriptions.Item label="员工工号">{accountInfo?.jobNumber || ''}</Descriptions.Item>
193
192
  <Descriptions.Item label="名称">{accountInfo?.name || ''}</Descriptions.Item>
194
193
  <Descriptions.Item label="手机号">{accountInfo?.mobile || ''}</Descriptions.Item>
195
194
  <Descriptions.Item label="邮箱">{accountInfo?.email || ''}</Descriptions.Item>
@@ -384,7 +384,6 @@ export default function AccountInfo({ isShowTab, getAuthTree, getAccountAuthTree
384
384
  </div>
385
385
  <Descriptions className='basicInfoWrap'>
386
386
  <Descriptions.Item label='账号'>{accountInfo?.account || ''}</Descriptions.Item>
387
- <Descriptions.Item label='员工工号'>{accountInfo?.jobNumber || ''}</Descriptions.Item>
388
387
  <Descriptions.Item label='名称'>{accountInfo?.name || ''}</Descriptions.Item>
389
388
  <Descriptions.Item label='手机号'>{accountInfo?.mobile || ''}</Descriptions.Item>
390
389
  <Descriptions.Item label='邮箱'>{accountInfo?.email || ''}</Descriptions.Item>
@@ -1,169 +0,0 @@
1
- $header-height: 60px;
2
- $base-color: #c6538c;
3
-
4
- body {
5
- overflow: hidden;
6
- }
7
-
8
- .layout-warp {
9
- display: flex;
10
- }
11
-
12
- .ant-layout .ant-layout-sider {
13
- background-image: linear-gradient(
14
- -45deg,
15
- rgba(103, 200, 21, 0.5),
16
- rgba(55, 96, 244, 0.5),
17
- rgba(245, 34, 45, 0.7)
18
- );
19
- background-position: center;
20
- // background-color: #fff;
21
- // background-color: #13c2c2;
22
- background-color: #08979c;
23
- // background-color: #531dab;
24
- // background-color: #389e0d;
25
-
26
- .ant-layout-sider-trigger {
27
- background: transparent;
28
- &:hover {
29
- background: rgba(0, 0, 0, 0.12);
30
- }
31
- }
32
- }
33
-
34
- .layout-side {
35
- height: 100vh;
36
- user-select: none;
37
- overflow: hidden;
38
-
39
- .layout-logo {
40
- cursor: pointer;
41
- height: 60px;
42
- margin: 8px auto;
43
- display: flex;
44
- justify-content: center;
45
- align-items: center;
46
- width: 100%;
47
- z-index: 1;
48
-
49
- .logo-img {
50
- position: absolute;
51
- height: 60px;
52
- line-height: 60px;
53
- object-fit: cover;
54
- transition: all 0.8s cubic-bezier(0.645, 0.045, 0.355, 1);
55
- }
56
-
57
- .current-logo {
58
- left: 0;
59
- right: 0;
60
- margin: auto;
61
- }
62
-
63
- .hide-logo {
64
- left: -500px;
65
- }
66
- .hide-sub-logo {
67
- right: -500px;
68
- }
69
- }
70
-
71
- .layout-menu-container {
72
- height: calc(100vh - 60px - 16px - 48px);
73
- overflow: auto;
74
- .ant-menu {
75
- background: transparent !important;
76
- }
77
- .ant-menu-item-selected {
78
- background: rgba(255, 255, 255, 0.3) !important;
79
- }
80
- }
81
- }
82
-
83
- .layout-header {
84
- height: $header-height;
85
- background: white;
86
- z-index: 1;
87
- position: relative;
88
- display: flex;
89
- justify-content: flex-start;
90
- align-items: center;
91
-
92
- .app-name {
93
- margin-left: 24px;
94
- font-weight: 500;
95
- color: rgba(0, 0, 0, 0.65);
96
- }
97
-
98
- .layout-header-fill {
99
- flex: 1;
100
- }
101
-
102
- .layout-header-actions {
103
- display: flex;
104
- justify-content: flex-start;
105
- align-items: center;
106
- height: 100%;
107
- max-width: 400px;
108
- z-index: 2;
109
-
110
- .actions-item {
111
- height: 36px;
112
- border-radius: 6px;
113
- transition: all 0.3s;
114
- cursor: pointer;
115
- margin: 0 4px;
116
- padding: 0 4px;
117
-
118
- display: flex;
119
- justify-content: center;
120
- align-items: center;
121
-
122
- &:hover {
123
- background: rgba(0, 0, 0, 0.06);
124
- }
125
- }
126
- }
127
-
128
- .layout-header-user {
129
- height: 48px;
130
- display: flex;
131
- justify-content: flex-start;
132
- align-items: center;
133
- z-index: 2;
134
- transition: all 0.3s;
135
- padding: 4px 12px;
136
- margin: 0 12px;
137
- border-radius: 6px;
138
- cursor: pointer;
139
-
140
- &:hover {
141
- background: rgba(0, 0, 0, 0.06);
142
- }
143
-
144
- .avatar {
145
- width: 40px;
146
- height: 40px;
147
- border-radius: 50%;
148
- margin-right: 12px;
149
- }
150
- }
151
- }
152
-
153
- .layout-main {
154
- flex: 1;
155
- height: 100%;
156
- overflow: auto;
157
- }
158
-
159
- .layout-content {
160
- width: 100%;
161
- height: calc(100vh - #{$header-height});
162
- overflow: auto;
163
- }
164
-
165
- .ant-menu-submenu-popup {
166
- .ant-menu-item-selected {
167
- background: rgba(255, 255, 255, 0.12) !important;
168
- }
169
- }
@@ -1,218 +0,0 @@
1
- import React, { useEffect, useState } from 'react'
2
- import { Layout, Menu, MenuProps, Popover } from 'antd'
3
- import UserCard from './user-card'
4
- import './index.scss'
5
-
6
- const { Sider } = Layout
7
-
8
- export interface LiosLayoutlProps {
9
- appName?: any
10
- productCode: string
11
- children: any
12
- menuList: any
13
- onMenuClick: (item: any) => void
14
- selectedKeys: string[]
15
- customAction?: (item: any) => void
16
- actions?: any[]
17
- myWalletInfo?: {
18
- availableCashAmount: string
19
- availableAmount: string
20
- currency: string
21
- }
22
- MyLoginInfo?: {
23
- isAdmin: any
24
- }
25
- amountInfo?: {
26
- residueNum: string
27
- currencyCode: string
28
- }
29
- myWalletInfoAction?: Function
30
- myLoginInfoAction?: Function
31
- logoutUrl?: string
32
- switchTenantUrl?: string
33
- defaultOpenKeys?: string[]
34
- isHideHeader?: boolean //是否隐藏header
35
- onCollapse?: (value: boolean) => void
36
- }
37
-
38
- export default function LiosLayout(props: LiosLayoutlProps) {
39
- const {
40
- appName,
41
- productCode,
42
- menuList,
43
- onMenuClick,
44
- selectedKeys,
45
-
46
- customAction,
47
- actions,
48
-
49
- defaultOpenKeys,
50
- myWalletInfo,
51
- MyLoginInfo,
52
- amountInfo,
53
- myWalletInfoAction,
54
- myLoginInfoAction,
55
- isHideHeader,
56
- onCollapse,
57
- } = props
58
-
59
- const { user, logo, subLogo } = (window as any)?.g_config
60
- const { name, avatar } = user || {}
61
-
62
- const [openKeys, setOpenKeys] = useState<any>(defaultOpenKeys || [])
63
-
64
- //处理搜索菜单后自动展开目录
65
- interface TreeNode {
66
- key: string
67
- children?: TreeNode[]
68
- }
69
- const findParentMenu = (menuList: any[], pathname: string) => {
70
- const result: TreeNode[] = []
71
-
72
- const findNode = (nodes: TreeNode[], path: TreeNode[]): boolean => {
73
- for (const node of nodes) {
74
- if (node.key === pathname) {
75
- result.push(...path)
76
- return true
77
- }
78
- if (node.children && findNode(node.children, [...path, node])) {
79
- return true
80
- }
81
- }
82
- return false
83
- }
84
-
85
- findNode(menuList, [])
86
- return result
87
- }
88
- useEffect(() => {
89
- //在这里找到当前菜单的上层目录
90
- const paMenu = findParentMenu(menuList, '/' + location.pathname.split('/')[2])
91
- //去重
92
- const set = new Set(paMenu.map((item) => item.key))
93
- openKeys.forEach((element: string) => {
94
- set.add(element)
95
- })
96
- setOpenKeys(Array.from(set))
97
- }, [location.pathname])
98
-
99
- const [collapsed, setCollapsed] = useState(localStorage.getItem('layout_collapsed') === 'true')
100
- const [isCopied, setIsCopied] = useState({
101
- account: false,
102
- id: false,
103
- tenantName: false,
104
- tenantId: false,
105
- })
106
-
107
- const onOpenChange: MenuProps['onOpenChange'] = (keys) => {
108
- setOpenKeys(keys)
109
- }
110
-
111
- const copyTextToClipboard = async (text: string, key: string) => {
112
- try {
113
- await navigator.clipboard.writeText(text)
114
- setIsCopied({ ...isCopied, [key]: true })
115
- } catch (err) {}
116
- }
117
-
118
- return (
119
- <Layout className="layout-warp">
120
- {Array.isArray(menuList) && menuList.length > 0 && (
121
- <Sider
122
- className="layout-side"
123
- style={{
124
- backgroundSize: collapsed ? '1800%' : '900%',
125
- }}
126
- collapsible
127
- collapsed={collapsed}
128
- width={240}
129
- onCollapse={(value) => {
130
- onCollapse && onCollapse(value)
131
- localStorage.setItem('layout_collapsed', value.toString())
132
- setCollapsed(value)
133
- }}
134
- >
135
- <div
136
- className="layout-logo"
137
- onClick={() => {
138
- window.open('/home')
139
- }}
140
- >
141
- {<img className={`logo-img ${!collapsed ? 'current-logo' : 'hide-logo'}`} src={logo || ''} />}
142
- {
143
- <img
144
- className={`logo-img sub-logo
145
- ${collapsed ? 'current-logo' : 'hide-sub-logo'}`}
146
- src={subLogo || 'https://cdn.chengfengerlai.com/logo/company-logo/chengfengerlai-white.png'}
147
- />
148
- }
149
- </div>
150
-
151
- <div className="layout-menu-container">
152
- <Menu
153
- mode="inline"
154
- openKeys={openKeys}
155
- onOpenChange={onOpenChange}
156
- items={menuList}
157
- onClick={(item): any => {
158
- onMenuClick && onMenuClick(item)
159
- }}
160
- selectedKeys={selectedKeys}
161
- theme="dark"
162
- color="red"
163
- />
164
- </div>
165
- </Sider>
166
- )}
167
-
168
- <div className="layout-main">
169
- {!isHideHeader && (
170
- <div className="layout-header">
171
- {appName && (
172
- <div className="app-name">
173
- <strong>{appName}</strong>
174
- </div>
175
- )}
176
-
177
- <div className="layout-header-fill" />
178
-
179
- <div className="layout-header-actions">
180
- {actions?.map((item, index) => {
181
- return (
182
- <div className="actions-item" key={index}>
183
- {item}
184
- </div>
185
- )
186
- })}
187
- </div>
188
-
189
- <Popover
190
- placement="bottom"
191
- content={
192
- <UserCard myWalletInfo={myWalletInfo} MyLoginInfo={MyLoginInfo} amountInfo={amountInfo} customAction={customAction} isCopied={isCopied} copyTextToClipboard={copyTextToClipboard} />
193
- }
194
- arrow={false}
195
- trigger="click"
196
- onOpenChange={(e) => {
197
- if (!e) return
198
- setIsCopied({
199
- account: false,
200
- id: false,
201
- tenantName: false,
202
- tenantId: false,
203
- })
204
- myLoginInfoAction && myLoginInfoAction()
205
- }}
206
- >
207
- <div className="layout-header-user">
208
- <img className="avatar" src={avatar} />
209
- <div className="name">{name}</div>
210
- </div>
211
- </Popover>
212
- </div>
213
- )}
214
- <div className="layout-content">{props.children}</div>
215
- </div>
216
- </Layout>
217
- )
218
- }
@@ -1,180 +0,0 @@
1
- //用户卡片
2
- .layout-user-card {
3
- min-width: 182px;
4
- max-width: 262px;
5
-
6
- .user-info {
7
- display: flex;
8
-
9
- .user-avatarBox{
10
- width: 72px;
11
- height: 72px;
12
- margin-right: 12px;
13
- position: relative;
14
- .user-avatar {
15
- width: 100%;
16
- height: 100%;
17
- border-radius: 50%;
18
- background: rgba(255, 255, 255, 0.3);
19
- }
20
- .user-mater{
21
- position: absolute;
22
- bottom: 0px;
23
- left: 0px;
24
- right: 0px;
25
- text-align: center;
26
- background-color: rgba(62, 119, 189 ,0.9);
27
- width: 50px;
28
- border-radius: 50px;
29
- color: #fff;
30
- transform: scale(0.9);
31
- margin: auto;
32
- }
33
- }
34
-
35
- .user-info-right {
36
- flex: 1;
37
- }
38
-
39
- .name {
40
- display: inline-block;
41
- margin-top: 18px;
42
- }
43
-
44
- .role-list {
45
- font-size: 12px;
46
- line-height: 16px;
47
- margin-top: 4px;
48
-
49
- .role-item {
50
- background: rgba(204, 204, 204, 0.55);
51
- padding: 2px 8px;
52
- border-radius: 8px;
53
- display: inline-block;
54
- margin-right: 4px;
55
- margin-bottom: 4px;
56
- }
57
- }
58
- }
59
-
60
- .lios-tenant {
61
- padding: 5px 0px;
62
- margin: 5px 0px;
63
- border-top: 1px solid rgba(5, 5, 5, 0.06);
64
-
65
- .tenant-label {
66
- font-size: 12px;
67
- color: rgba(0, 0, 0, 0.5);
68
- }
69
-
70
- .tenant-switch {
71
- display: flex;
72
-
73
- .tenant-value {
74
- flex: 1;
75
- font-size: 14px;
76
- color: rgba(0, 0, 0, 0.85);
77
- }
78
-
79
- .tenant-icon {
80
- width: 40px;
81
- text-align: center;
82
- color: rgba(0, 0, 0, 0.45);
83
- display: flex;
84
- justify-content: center;
85
- align-items: center;
86
- }
87
-
88
- .tenant-icon:hover {
89
- cursor: pointer;
90
- color: rgba(0, 0, 0, 0.85);
91
- }
92
- }
93
- }
94
-
95
- .lios-userInfo {
96
- padding: 5px 0px;
97
- margin: 5px 0px;
98
- border-top: 1px solid rgba(5, 5, 5, 0.06);
99
-
100
- .li-flex {
101
- display: flex;
102
- .lios-keyMare {
103
- width: 50px;
104
- }
105
- .lios-value {
106
- flex: 1;
107
- }
108
- .lios-valueMare {
109
- flex: 1;
110
- overflow: hidden;
111
- text-overflow: ellipsis;
112
- }
113
-
114
- }
115
-
116
- .lios-li {
117
- line-height: 22px;
118
-
119
- .lios-key, .lios-keyMare {
120
- font-size: 12px;
121
- color: rgba(0, 0, 0, 0.5);
122
- display: inline-block;
123
- }
124
-
125
- .lios-value, .lios-valueMare {
126
- padding-left: 8px;
127
- display: inline-block;
128
- font-size: 12px;
129
- color: rgba(0, 0, 0, 0.85);
130
-
131
- span {
132
- padding-left: 5px;
133
- }
134
- }
135
- .lios-iconDone {
136
- width: 40px;
137
- text-align: center;
138
- color: rgba(0, 0, 0, 0.45);
139
- font-size: 10px;
140
- }
141
- .lios-icon {
142
- width: 40px;
143
- text-align: center;
144
- color: rgba(0, 0, 0, 0.45);
145
- transition: all 0.3s;
146
- }
147
-
148
- .lios-icon:hover {
149
- cursor: pointer;
150
- color: rgba(0, 0, 0, 0.85);
151
- }
152
- }
153
- }
154
- .lios-logoutBox{
155
- display: flex;
156
-
157
- .lios-logout {
158
- cursor: pointer;
159
- display: flex;
160
- justify-content: center;
161
- align-items: center;
162
- color: rgba(0, 0, 0, 0.45);
163
- border-radius: 2px;
164
- transition: background 0.3s;
165
- padding: 4px;
166
- flex: 1;
167
- border: 1px solid rgba(5, 5, 5, 0.06);
168
- margin: 4px 4px;
169
- &:hover {
170
- background: rgba(0, 0, 0, 0.03);
171
- }
172
-
173
- .logout-icon {
174
- width: 16px;
175
- height: 16px;
176
- margin-right: 3px;
177
- }
178
- }
179
- }
180
- }