@gm-pc/react 1.13.2 → 1.13.3-alpha.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gm-pc/react",
3
- "version": "1.13.2",
3
+ "version": "1.13.3-alpha.2",
4
4
  "description": "观麦前端基础组件库",
5
5
  "author": "liyatang <liyatang@qq.com>",
6
6
  "homepage": "https://github.com/gmfe/gm-pc#readme",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "@gm-common/hooks": "^2.10.0",
26
26
  "@gm-common/tool": "^2.10.0",
27
- "@gm-pc/locales": "^1.13.2",
27
+ "@gm-pc/locales": "^1.13.3-alpha.2",
28
28
  "big.js": "^6.0.1",
29
29
  "classnames": "^2.2.5",
30
30
  "lodash": "^4.17.19",
@@ -48,5 +48,5 @@
48
48
  "react-router-dom": "^5.2.0",
49
49
  "react-window": "^1.8.5"
50
50
  },
51
- "gitHead": "eed0722555286fb4c48d77c9fe1082db7c6ffb7f"
51
+ "gitHead": "bdd278fe8bf983b735b760af20581ab580972632"
52
52
  }
@@ -1,7 +1,7 @@
1
1
  import { createContext } from 'react'
2
2
  import { VBrowserWindow } from '../types'
3
3
 
4
- const BrowserWindowContext = createContext<VBrowserWindow>(undefined as any)
4
+ const BrowserWindowContext = createContext<string>(undefined as any)
5
5
  BrowserWindowContext.displayName = 'VBrowserWindowContext'
6
6
 
7
7
  export default BrowserWindowContext
@@ -12,8 +12,8 @@ type Noop = () => void
12
12
  */
13
13
  export default function useWindowEffect(fn: () => Noop | void, deps: Array<any>) {
14
14
  const browser = useContext(BrowserContext)
15
- /** hook所在窗口 */
16
- const browserWindow = useContext(BrowserWindowContext)
15
+ const path = useContext(BrowserWindowContext)
16
+ const browserWindow = browser.windows.find((w) => w.path === path)!
17
17
  const cb = useRef<Noop | void>()
18
18
 
19
19
  useEffect(() => {
@@ -37,21 +37,15 @@ export default function useWindowEffect(fn: () => Noop | void, deps: Array<any>)
37
37
  const deactivate = pre?.path === browserWindow.path
38
38
  if (activate) {
39
39
  cb.current = fn()
40
- console.log('activate', browserWindow.path)
40
+ // console.log('activate', browserWindow.path)
41
41
  }
42
42
  if (deactivate) {
43
43
  cb.current && cb.current()
44
- console.log('deactivate', browserWindow.path)
44
+ // console.log('deactivate', browserWindow.path)
45
45
  }
46
46
  }
47
- // { fireImmediately: true }
48
47
  )
49
48
  cb.current = fn()
50
- console.log('effect', browserWindow.path, deps)
51
- return () => {
52
- console.log('dispose', browserWindow.path)
53
- dispose()
54
- cb.current && cb.current()
55
- }
49
+ return dispose
56
50
  }, deps)
57
51
  }
@@ -14,7 +14,7 @@ export interface VBrowserWindow {
14
14
  export interface VBrowserProps {
15
15
  /** 窗口数量限制 */
16
16
  maxLength?: number
17
- /** 准备就绪 */
17
+ /** 准备就绪 (读取Storage) */
18
18
  onReady?: Function
19
19
  /** 重新打开vBrowser时恢复已打开窗口, 默认为true */
20
20
  restore?: boolean
@@ -28,7 +28,13 @@ export interface VBrowserProps {
28
28
  auth?: (from?: VBrowserWindow, to?: VBrowserWindow) => Promise<boolean> | boolean
29
29
  /**
30
30
  * 错误码参考
31
+ *
31
32
  * code: 0, message: '超过最大允许的窗口数量'
33
+ *
34
+ * code: 1, message: '鉴权失败'
35
+ *
36
+ * code: 2, message: '路由不存在‘
37
+ *
32
38
  */
33
39
  onError?: (error: { code: number; message: string }) => void
34
40
  /** 打开窗口如果没有传入标题,则使用此方法取标题 */
@@ -64,7 +64,7 @@ const VBrowserContainer: FC<{ className?: string }> = observer(
64
64
  createPortal(
65
65
  pages.map((page, i) => {
66
66
  return (
67
- <BrowserWindowContext.Provider key={i} value={page}>
67
+ <BrowserWindowContext.Provider key={i} value={page.path}>
68
68
  <WindowWrapper key={i} path={page.path} />
69
69
  </BrowserWindowContext.Provider>
70
70
  )
@@ -1,9 +1,11 @@
1
1
  /* eslint-disable dot-notation */
2
2
  import { get } from 'lodash'
3
3
  import { observer } from 'mobx-react'
4
- import React, { createRef, FC, useContext, useEffect } from 'react'
4
+ import React, { createRef, FC, lazy, Suspense, useContext, useEffect } from 'react'
5
+ import { Loading } from '../../loading'
5
6
  import { NProgress } from '../../n_progress'
6
7
  import BrowserContext from '../context/browser'
8
+ import BrowserWindowContext from '../context/browserWindow'
7
9
  import { CacheItem } from '../types'
8
10
  import { pages } from '../v_browser'
9
11
 
@@ -34,27 +36,25 @@ const WindowWrapper: FC<WindowWrapperProps> = ({ path }) => {
34
36
  const page = pages.find((p) => p.path === path)
35
37
  if (!page) throw new Error('[VBrowser] page not found: ' + path)
36
38
 
37
- NProgress.start()
38
- page
39
- .loader()
40
- .then((module) => {
41
- const Component = module.default
42
- const vNode = (
43
- <div
44
- className='v-browser-window-content'
45
- data-vbrowser-window={path}
46
- ref={createRef()}
47
- >
48
- <Component />
49
- </div>
50
- ) as CacheItem['vNode']
51
- browser['_setCache'](path, { vNode })
52
- browser['_fire']('show', w!)
53
- return null
54
- })
55
- .finally(() => {
56
- NProgress.done()
57
- })
39
+ const loading = (
40
+ <div className='tw-w-full tw-h-full tw-flex tw-items-center tw-justify-center'>
41
+ <Loading size='24' />
42
+ </div>
43
+ )
44
+ const Component = lazy(page.loader)
45
+ const vNode = (
46
+ <div
47
+ className='v-browser-window-content'
48
+ data-vbrowser-window={path}
49
+ ref={createRef()}
50
+ >
51
+ <Suspense fallback={loading}>
52
+ <Component />
53
+ </Suspense>
54
+ </div>
55
+ ) as CacheItem['vNode']
56
+ browser['_setCache'](path, { vNode })
57
+ browser['_fire']('show', w!)
58
58
  return
59
59
  }
60
60
 
@@ -89,6 +89,10 @@ vbrowser 暴露了以下属性和方法,详细信息见类型声明/代码提
89
89
 
90
90
  隐藏窗口管理栏,可以用于进入全屏模式的场景;
91
91
 
92
+ - `clearSession`
93
+
94
+ 清除会话缓存,使重新进入不恢复vbrowser窗口标签栏
95
+
92
96
  - `on`
93
97
 
94
98
  事件监听, `'error' | 'change' | 'close' | 'show'`,分别对应错误、窗口切换、窗口关闭、窗口激活事件;
@@ -15,7 +15,7 @@ export const pages = req.keys().map((key) => {
15
15
  }
16
16
  })
17
17
 
18
- const STORAGE_KEY = 'vbrowser-cache'
18
+ export const VBROWSER_STORAGE_KEY = 'gm_vbrowser-cache'
19
19
 
20
20
  type EventName = 'error' | 'change' | 'close' | 'show'
21
21
 
@@ -36,7 +36,7 @@ class VBrowser implements VBrowser {
36
36
  </BrowserContext.Provider>
37
37
  )
38
38
  // this.open = debounce(this.open).bind(this) as typeof this.open
39
- this._loadStash().then(async () => {
39
+ this._restoreSession().then(async () => {
40
40
  await when(() => this.mounted)
41
41
  this.props.onReady && this.props.onReady()
42
42
  return null
@@ -65,7 +65,7 @@ class VBrowser implements VBrowser {
65
65
  if (ignored) {
66
66
  const i = this.windows.indexOf(oldWindow!)
67
67
  this.windows.splice(i, 1)
68
- delete this._cache[i]
68
+ delete this._cache[oldWindow?.path!]
69
69
  }
70
70
 
71
71
  if (typeof w === 'number') {
@@ -81,7 +81,7 @@ class VBrowser implements VBrowser {
81
81
 
82
82
  this.props.onChange &&
83
83
  this.props.onChange(oldWindow, this.windows[this.activeIndex], this.windows)
84
- this._stash()
84
+ this._stashSession()
85
85
  }
86
86
 
87
87
  /** 打开新子窗口, 子窗口已存在则判断query是否相等,相等则切换,不相等则隐性销毁重新加载;子窗口不存在则新建子窗口;
@@ -110,9 +110,16 @@ class VBrowser implements VBrowser {
110
110
  } else {
111
111
  pass = (auth(this.activeWindow, w as VBrowserWindow) as boolean) ?? false
112
112
  }
113
- if (!pass) return this._fire('error', new Error('鉴权失败'))
113
+ if (!pass) {
114
+ this._fire('error', { code: 1, message: '鉴权失败' })
115
+ return
116
+ }
114
117
  if (!pages.find((p) => p.path === (w as VBrowserWindow).path)) {
115
- console.error(w.path, '页面不存在')
118
+ this._fire('error', {
119
+ code: 2,
120
+ message: `无法找到页面 ${w.path}, 可用路径:${pages.map((p) => p.path)}`,
121
+ })
122
+ return
116
123
  }
117
124
  // #endregion
118
125
 
@@ -123,8 +130,7 @@ class VBrowser implements VBrowser {
123
130
  )
124
131
  if (index === -1) {
125
132
  if (this.props.maxLength && this.windows.length >= this.props.maxLength) {
126
- this.props.onError &&
127
- this.props.onError({ code: 0, message: '超过最大允许的窗口数量' })
133
+ this._fire('error', { code: 0, message: '超过最大允许的窗口数量' })
128
134
  return
129
135
  }
130
136
 
@@ -151,16 +157,18 @@ class VBrowser implements VBrowser {
151
157
  // #region 打开新浏览器窗口
152
158
  if (target === '_blank') {
153
159
  // 避免继承
154
- const currentCache = JSON.parse(sessionStorage.getItem(STORAGE_KEY) || '{}')
160
+ const currentCache = JSON.parse(
161
+ sessionStorage.getItem(VBROWSER_STORAGE_KEY) || '{}'
162
+ )
155
163
  const newCache = { windows: [] as VBrowserWindow[], activeIndex: 0 }
156
164
  newCache.windows.push(...this.windows.filter((w) => !w.closeable))
157
165
  newCache.windows.push(w)
158
166
  newCache.activeIndex = newCache.windows.findIndex(
159
167
  (item) => item.path === (w as VBrowserWindow).path
160
168
  )
161
- sessionStorage.setItem(STORAGE_KEY, JSON.stringify(newCache))
169
+ sessionStorage.setItem(VBROWSER_STORAGE_KEY, JSON.stringify(newCache))
162
170
  window.open(`#${w.path}?${stringify(w.query || {})}`, '_blank')
163
- sessionStorage.setItem(STORAGE_KEY, JSON.stringify(currentCache))
171
+ sessionStorage.setItem(VBROWSER_STORAGE_KEY, JSON.stringify(currentCache))
164
172
  }
165
173
  // #endregion
166
174
  }
@@ -213,26 +221,31 @@ class VBrowser implements VBrowser {
213
221
  }
214
222
 
215
223
  // 保存已开窗口
216
- private async _stash() {
224
+ private async _stashSession() {
217
225
  const windows = this.windows.slice().map((item) => ({ ...item }))
218
226
  const string = JSON.stringify({
219
227
  windows,
220
228
  activeIndex: this.activeIndex,
221
229
  })
222
- sessionStorage.setItem(STORAGE_KEY, string)
230
+ sessionStorage.setItem(VBROWSER_STORAGE_KEY, string)
223
231
  }
224
232
 
225
233
  // 恢复已开窗口
226
- private async _loadStash() {
234
+ private async _restoreSession() {
227
235
  await new Promise((resolve) => setTimeout(resolve, 100))
228
236
  const { windows = [], activeIndex = 0 } = JSON.parse(
229
- sessionStorage.getItem(STORAGE_KEY) || '{}'
237
+ sessionStorage.getItem(VBROWSER_STORAGE_KEY) || '{}'
230
238
  )
231
239
  if (windows.length === 0) return
232
240
  this.windows = windows
233
241
  this.open(windows[activeIndex])
234
242
  }
235
243
 
244
+ /** 清除会话缓存,使重新进入不恢复vbrowser窗口标签栏 */
245
+ clearSession() {
246
+ sessionStorage.removeItem(VBROWSER_STORAGE_KEY)
247
+ }
248
+
236
249
  /** 隐藏标签栏 */
237
250
  hideTabs() {
238
251
  this._hidingTabs = true
@@ -264,6 +277,9 @@ class VBrowser implements VBrowser {
264
277
  private _fire(eventName: EventName, ...args: any[]) {
265
278
  const events = this._events[eventName] || []
266
279
  events.forEach((item) => item.event(...args))
280
+ if (eventName === 'error') {
281
+ this.props.onError && this.props.onError(args?.[0])
282
+ }
267
283
  }
268
284
  }
269
285