@blocklet/ui-react 2.9.52 → 2.9.54

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.
Files changed (104) hide show
  1. package/es/@types/index.d.ts +3 -5
  2. package/es/Dashboard/index.d.ts +5 -6
  3. package/es/Dashboard/index.js +5 -5
  4. package/es/Footer/index.js +2 -2
  5. package/es/Header/index.js +5 -5
  6. package/es/UserCenter/components/notification.js +1 -1
  7. package/es/UserCenter/components/passport.js +1 -2
  8. package/es/UserCenter/components/privacy.js +1 -1
  9. package/es/UserCenter/components/settings.js +9 -1
  10. package/es/UserCenter/components/storage/connect-to.d.ts +1 -1
  11. package/es/UserCenter/components/storage/connect-to.js +9 -3
  12. package/es/UserCenter/components/storage/delete.d.ts +1 -1
  13. package/es/UserCenter/components/storage/delete.js +4 -1
  14. package/es/UserCenter/components/storage/item.js +1 -1
  15. package/es/UserCenter/components/user-center.d.ts +2 -2
  16. package/es/UserCenter/components/user-center.js +15 -6
  17. package/es/UserCenter/libs/locales.d.ts +2 -0
  18. package/es/UserCenter/libs/locales.js +2 -0
  19. package/es/UserSessions/components/user-session-info.d.ts +6 -0
  20. package/es/UserSessions/components/user-session-info.js +58 -0
  21. package/es/UserSessions/components/user-sessions.d.ts +9 -0
  22. package/es/UserSessions/components/user-sessions.js +255 -0
  23. package/es/UserSessions/index.d.ts +1 -0
  24. package/es/UserSessions/index.js +1 -0
  25. package/es/UserSessions/libs/locales.d.ts +52 -0
  26. package/es/UserSessions/libs/locales.js +52 -0
  27. package/es/UserSessions/libs/utils.d.ts +2 -0
  28. package/es/UserSessions/libs/utils.js +73 -0
  29. package/es/blocklets.js +6 -6
  30. package/es/common/header-addons.d.ts +3 -4
  31. package/es/common/header-addons.js +4 -4
  32. package/es/contexts/config-user-space.js +2 -2
  33. package/es/index.d.ts +1 -0
  34. package/es/index.js +1 -0
  35. package/es/types.d.ts +2 -2
  36. package/es/types.js +2 -2
  37. package/lib/@types/index.d.ts +3 -5
  38. package/lib/Dashboard/index.d.ts +5 -6
  39. package/lib/Dashboard/index.js +4 -4
  40. package/lib/Footer/index.js +1 -1
  41. package/lib/Header/index.js +4 -4
  42. package/lib/UserCenter/components/notification.js +1 -1
  43. package/lib/UserCenter/components/passport.js +1 -2
  44. package/lib/UserCenter/components/privacy.js +1 -1
  45. package/lib/UserCenter/components/settings.js +10 -1
  46. package/lib/UserCenter/components/storage/connect-to.d.ts +1 -1
  47. package/lib/UserCenter/components/storage/connect-to.js +3 -3
  48. package/lib/UserCenter/components/storage/delete.d.ts +1 -1
  49. package/lib/UserCenter/components/storage/item.js +1 -1
  50. package/lib/UserCenter/components/user-center.d.ts +2 -2
  51. package/lib/UserCenter/components/user-center.js +20 -10
  52. package/lib/UserCenter/libs/locales.d.ts +2 -0
  53. package/lib/UserCenter/libs/locales.js +2 -0
  54. package/lib/UserSessions/components/user-session-info.d.ts +6 -0
  55. package/lib/UserSessions/components/user-session-info.js +68 -0
  56. package/lib/UserSessions/components/user-sessions.d.ts +9 -0
  57. package/lib/UserSessions/components/user-sessions.js +282 -0
  58. package/lib/UserSessions/index.d.ts +1 -0
  59. package/lib/UserSessions/index.js +13 -0
  60. package/lib/UserSessions/libs/locales.d.ts +52 -0
  61. package/lib/UserSessions/libs/locales.js +58 -0
  62. package/lib/UserSessions/libs/utils.d.ts +2 -0
  63. package/lib/UserSessions/libs/utils.js +80 -0
  64. package/lib/blocklets.js +6 -6
  65. package/lib/common/header-addons.d.ts +3 -4
  66. package/lib/common/header-addons.js +3 -3
  67. package/lib/contexts/config-user-space.js +1 -1
  68. package/lib/index.d.ts +1 -0
  69. package/lib/index.js +12 -0
  70. package/lib/types.d.ts +2 -2
  71. package/lib/types.js +3 -3
  72. package/package.json +14 -6
  73. package/src/@types/index.ts +3 -5
  74. package/src/Dashboard/index.jsx +7 -3
  75. package/src/Footer/index.jsx +2 -2
  76. package/src/Header/index.jsx +5 -3
  77. package/src/Icon/index.jsx +1 -0
  78. package/src/UserCenter/components/notification.tsx +2 -2
  79. package/src/UserCenter/components/passport.tsx +1 -2
  80. package/src/UserCenter/components/privacy.tsx +1 -1
  81. package/src/UserCenter/components/settings.tsx +15 -2
  82. package/src/UserCenter/components/storage/connect-to.tsx +17 -11
  83. package/src/UserCenter/components/storage/delete.tsx +8 -2
  84. package/src/UserCenter/components/storage/item.tsx +2 -3
  85. package/src/UserCenter/components/storage/preview-nft.tsx +1 -1
  86. package/src/UserCenter/components/user-center.tsx +21 -14
  87. package/src/UserCenter/components/webhook-item.tsx +1 -1
  88. package/src/UserCenter/libs/locales.ts +2 -0
  89. package/src/UserSessions/components/user-session-info.tsx +52 -0
  90. package/src/UserSessions/components/user-sessions.tsx +276 -0
  91. package/src/UserSessions/index.tsx +1 -0
  92. package/src/UserSessions/libs/locales.ts +52 -0
  93. package/src/UserSessions/libs/utils.ts +82 -0
  94. package/src/blocklets.js +6 -6
  95. package/src/common/header-addons.jsx +2 -2
  96. package/src/contexts/config-user-space.tsx +12 -11
  97. package/src/index.ts +1 -0
  98. package/src/{UserCenter/libs → libs}/client.ts +1 -0
  99. package/src/libs/spaces.tsx +2 -2
  100. package/src/types.js +2 -2
  101. /package/es/{UserCenter/libs → libs}/client.d.ts +0 -0
  102. /package/es/{UserCenter/libs → libs}/client.js +0 -0
  103. /package/lib/{UserCenter/libs → libs}/client.d.ts +0 -0
  104. /package/lib/{UserCenter/libs → libs}/client.js +0 -0
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "UserSessions", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _userSessions.default;
10
+ }
11
+ });
12
+ var _userSessions = _interopRequireDefault(require("./components/user-sessions"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,52 @@
1
+ export declare const translations: {
2
+ zh: {
3
+ confirm: string;
4
+ cancel: string;
5
+ visitorId: string;
6
+ deviceType: string;
7
+ platform: string;
8
+ walletOS: string;
9
+ role: string;
10
+ fullname: string;
11
+ email: string;
12
+ avatar: string;
13
+ user: string;
14
+ updatedAt: string;
15
+ lastLoginIp: string;
16
+ actions: string;
17
+ logoutAll: string;
18
+ logoutAllTips: string;
19
+ logout: string;
20
+ currentSession: string;
21
+ unknown: string;
22
+ logoutThisSession: string;
23
+ logoutThisSessionConfirm: string;
24
+ logoutAllSession: string;
25
+ logoutAllSessionConfirm: string;
26
+ };
27
+ en: {
28
+ confirm: string;
29
+ cancel: string;
30
+ visitorId: string;
31
+ deviceType: string;
32
+ platform: string;
33
+ walletOS: string;
34
+ role: string;
35
+ fullname: string;
36
+ email: string;
37
+ avatar: string;
38
+ user: string;
39
+ updatedAt: string;
40
+ actions: string;
41
+ lastLoginIp: string;
42
+ logoutAll: string;
43
+ logoutAllTips: string;
44
+ logout: string;
45
+ currentSession: string;
46
+ unknown: string;
47
+ logoutThisSession: string;
48
+ logoutThisSessionConfirm: string;
49
+ logoutAllSession: string;
50
+ logoutAllSessionConfirm: string;
51
+ };
52
+ };
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.translations = void 0;
7
+ const translations = exports.translations = {
8
+ zh: {
9
+ confirm: "\u786E\u8BA4",
10
+ cancel: "\u53D6\u6D88",
11
+ visitorId: "\u8BBE\u5907\u6807\u8BC6",
12
+ deviceType: "\u8BBE\u5907\u7C7B\u578B",
13
+ platform: "\u64CD\u4F5C\u7CFB\u7EDF",
14
+ walletOS: "\u94B1\u5305\u7C7B\u578B",
15
+ role: "\u89D2\u8272",
16
+ fullname: "\u59D3\u540D",
17
+ email: "\u90AE\u7BB1",
18
+ avatar: "\u5934\u50CF",
19
+ user: "\u7528\u6237",
20
+ updatedAt: "\u6700\u8FD1\u6D3B\u52A8\u65F6\u95F4",
21
+ lastLoginIp: "\u6700\u8FD1\u6D3B\u52A8\u5730\u5740",
22
+ actions: "\u64CD\u4F5C",
23
+ logoutAll: "\u6CE8\u9500\u6240\u6709\u4F1A\u8BDD",
24
+ logoutAllTips: "\u4E0D\u4F1A\u6CE8\u9500\u5F53\u524D\u4F1A\u8BDD",
25
+ logout: "\u6CE8\u9500",
26
+ currentSession: "\u5F53\u524D\u4F1A\u8BDD",
27
+ unknown: "\u672A\u77E5",
28
+ logoutThisSession: "\u6CE8\u9500\u6307\u5B9A\u4F1A\u8BDD",
29
+ logoutThisSessionConfirm: "\u786E\u5B9A\u8981\u6CE8\u9500\u6B64\u4F1A\u8BDD\u5417?",
30
+ logoutAllSession: "\u6CE8\u9500\u6240\u6709\u4F1A\u8BDD",
31
+ logoutAllSessionConfirm: "\u786E\u5B9A\u8981\u6CE8\u9500\u6240\u6709\u4F1A\u8BDD\u5417?"
32
+ },
33
+ en: {
34
+ confirm: "Confirm",
35
+ cancel: "Cancel",
36
+ visitorId: "Device ID",
37
+ deviceType: "Device Type",
38
+ platform: "Platform",
39
+ walletOS: "Wallet OS",
40
+ role: "Role",
41
+ fullname: "Fullname",
42
+ email: "Email",
43
+ avatar: "Avatar",
44
+ user: "User",
45
+ updatedAt: "Last Active Time",
46
+ actions: "Actions",
47
+ lastLoginIp: "Last Login IP",
48
+ logoutAll: "Logout all",
49
+ logoutAllTips: "Will not logout current session",
50
+ logout: "Logout",
51
+ currentSession: "Current Session",
52
+ unknown: "Unknown",
53
+ logoutThisSession: "Logout this session",
54
+ logoutThisSessionConfirm: "Are you sure to logout this session?",
55
+ logoutAllSession: "Logout all sessions",
56
+ logoutAllSessionConfirm: "Are you sure to logout all sessions?"
57
+ }
58
+ };
@@ -0,0 +1,2 @@
1
+ export declare function ip2Region(ip: string): Promise<string>;
2
+ export declare function batchIp2Region(ips: string[]): Promise<string[]>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.batchIp2Region = batchIp2Region;
7
+ exports.ip2Region = ip2Region;
8
+ const RESERVED_IP = "Reserved IP";
9
+ const IP_REGION_CACHE = "ip-region-cache";
10
+ async function getIpRegionFromIpApi(ip) {
11
+ const url = `https://ipapi.co/${ip}/json/`;
12
+ const result = await fetch(url);
13
+ const data = await result.json();
14
+ let region = "";
15
+ if (data.error) {
16
+ if (data.reserved) {
17
+ region = RESERVED_IP;
18
+ }
19
+ } else {
20
+ region = [data.country_name, data.region, data.city].filter(Boolean).join("/");
21
+ }
22
+ return region;
23
+ }
24
+ async function getIpRegionFromIpSb(ip) {
25
+ const url = `https://api.ip.sb/geoip/${ip}`;
26
+ const result = await fetch(url);
27
+ const data = await result.json();
28
+ let region = "";
29
+ if (data.error) {
30
+ if (data.reserved) {
31
+ region = RESERVED_IP;
32
+ }
33
+ } else {
34
+ region = [data.country, data.region, data.city].filter(Boolean).join("/");
35
+ }
36
+ return region;
37
+ }
38
+ async function ip2Region(ip) {
39
+ let region = "";
40
+ let ipRegionCache = {};
41
+ try {
42
+ const tmpCache = localStorage.getItem(IP_REGION_CACHE);
43
+ if (tmpCache) {
44
+ ipRegionCache = JSON.parse(tmpCache);
45
+ }
46
+ } catch {
47
+ ipRegionCache = {};
48
+ }
49
+ if (ipRegionCache[ip]) {
50
+ region = ipRegionCache[ip];
51
+ } else {
52
+ try {
53
+ region = await getIpRegionFromIpSb(ip);
54
+ } catch {
55
+ console.warn("Fail to get ip region from ip.sb");
56
+ }
57
+ if (!region) {
58
+ try {
59
+ region = await getIpRegionFromIpApi(ip);
60
+ } catch {
61
+ console.warn("Fail to get ip region from ip-api.co");
62
+ }
63
+ }
64
+ }
65
+ if (region) {
66
+ const ipList = Object.keys(ipRegionCache);
67
+ if (ipList.length > 100) {
68
+ delete ipRegionCache[ipList[0]];
69
+ }
70
+ if (ipRegionCache[ip]) {
71
+ delete ipRegionCache[ip];
72
+ }
73
+ ipRegionCache[ip] = region;
74
+ localStorage.setItem(IP_REGION_CACHE, JSON.stringify(ipRegionCache));
75
+ }
76
+ return region;
77
+ }
78
+ async function batchIp2Region(ips) {
79
+ return Promise.all(ips.map(ip => ip2Region(ip)));
80
+ }
package/lib/blocklets.js CHANGED
@@ -40,30 +40,30 @@ const getLocalizedNavigation = (navigation, locale = 'en') => {
40
40
  return navigation;
41
41
  }
42
42
  // eslint-disable-next-line no-shadow
43
- const getTitle = (title, locale) => {
43
+ const getTitle = (title, _locale) => {
44
44
  if (typeof title === 'string') {
45
45
  return title;
46
46
  }
47
47
  if (typeof title === 'object') {
48
- return title[locale] || title?.en || title?.zh;
48
+ return title[_locale] || title?.en || title?.zh;
49
49
  }
50
50
  return title;
51
51
  };
52
52
  // eslint-disable-next-line no-shadow
53
- const getLink = (link, locale) => {
53
+ const getLink = (link, _locale) => {
54
54
  if (typeof link === 'string') {
55
55
  // http[s] 开头的 url
56
56
  if ((0, _utils.isUrl)(link)) {
57
57
  const url = new URL(link);
58
- url.searchParams.set('locale', locale);
58
+ url.searchParams.set('locale', _locale);
59
59
  return url.href;
60
60
  }
61
61
  const url = new URL(link, window.location.origin);
62
- url.searchParams.set('locale', locale);
62
+ url.searchParams.set('locale', _locale);
63
63
  return url.pathname + url.search;
64
64
  }
65
65
  if (typeof link === 'object') {
66
- return link[locale] || link?.en || link?.zh;
66
+ return link[_locale] || link?.en || link?.zh;
67
67
  }
68
68
  return link;
69
69
  };
@@ -7,16 +7,15 @@ declare namespace HeaderAddons {
7
7
  namespace propTypes {
8
8
  export let formattedBlocklet: any;
9
9
  export let addons: any;
10
- export { sessionManagerProps };
10
+ export { SessionManagerProps as sessionManagerProps };
11
11
  }
12
12
  namespace defaultProps {
13
13
  let addons_1: null;
14
14
  export { addons_1 as addons };
15
- export namespace sessionManagerProps_1 {
15
+ export namespace sessionManagerProps {
16
16
  let showRole: boolean;
17
17
  }
18
- export { sessionManagerProps_1 as sessionManagerProps };
19
18
  }
20
19
  }
21
20
  export default HeaderAddons;
22
- import { sessionManagerProps } from '../types';
21
+ import { SessionManagerProps } from '../types';
@@ -19,7 +19,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
19
19
  function HeaderAddons({
20
20
  formattedBlocklet,
21
21
  addons,
22
- sessionManagerProps: sessionManagerProps2
22
+ sessionManagerProps
23
23
  }) {
24
24
  const sessionCtx = (0, _react.useContext)(_Session.SessionContext);
25
25
  const {
@@ -71,7 +71,7 @@ function HeaderAddons({
71
71
  locale,
72
72
  menu,
73
73
  showRole: true,
74
- ...sessionManagerProps2
74
+ ...sessionManagerProps
75
75
  }, "session-user"));
76
76
  }
77
77
  if (typeof addons === "function") {
@@ -89,7 +89,7 @@ HeaderAddons.propTypes = {
89
89
  // - PropTypes.func: 可以把自定义 addons 插在 session-manager 或 locale-selector (如果存在的话) 前/中/后
90
90
  // - PropTypes.node: 将 addons 原样传给 UX Header 组件
91
91
  addons: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.node]),
92
- sessionManagerProps: _types.sessionManagerProps
92
+ sessionManagerProps: _types.SessionManagerProps
93
93
  };
94
94
  HeaderAddons.defaultProps = {
95
95
  addons: null,
@@ -35,12 +35,12 @@ function ConfigUserSpaceProvider({
35
35
  const deleteSpaceGateway = async () => {
36
36
  setSpaceGateway(void 0);
37
37
  };
38
+ const settingStorageEndpoint = endpoint => {};
38
39
  const updateSpaceGateway = async x => {
39
40
  setSpaceGateway(x);
40
41
  session.refresh();
41
42
  await settingStorageEndpoint(x.endpoint);
42
43
  };
43
- const settingStorageEndpoint = endpoint => {};
44
44
  const hasStorageEndpoint = Boolean(storageEndpoint && spaceGateway);
45
45
  return /* @__PURE__ */(0, _jsxRuntime.jsx)(Provider, {
46
46
  value: {
package/lib/index.d.ts CHANGED
@@ -5,3 +5,4 @@ export { default as Icon } from './Icon';
5
5
  export { default as ComponentInstaller } from './ComponentInstaller';
6
6
  export { default as useComponentInstaller } from './ComponentInstaller/use-component-installed';
7
7
  export * from './UserCenter';
8
+ export * from './UserSessions';
package/lib/index.js CHANGED
@@ -65,4 +65,16 @@ Object.keys(_UserCenter).forEach(function (key) {
65
65
  }
66
66
  });
67
67
  });
68
+ var _UserSessions = require("./UserSessions");
69
+ Object.keys(_UserSessions).forEach(function (key) {
70
+ if (key === "default" || key === "__esModule") return;
71
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
72
+ if (key in exports && exports[key] === _UserSessions[key]) return;
73
+ Object.defineProperty(exports, key, {
74
+ enumerable: true,
75
+ get: function () {
76
+ return _UserSessions[key];
77
+ }
78
+ });
79
+ });
68
80
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
package/lib/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const blockletMetaProps: any;
2
- export const sessionManagerProps: any;
1
+ export const BlockletMetaProps: any;
2
+ export const SessionManagerProps: any;
package/lib/types.js CHANGED
@@ -3,12 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.sessionManagerProps = exports.blockletMetaProps = void 0;
6
+ exports.SessionManagerProps = exports.BlockletMetaProps = void 0;
7
7
  var _propTypes = _interopRequireDefault(require("prop-types"));
8
8
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
9
  /* eslint-disable import/prefer-default-export */
10
10
 
11
- const blockletMetaProps = exports.blockletMetaProps = _propTypes.default.shape({
11
+ const BlockletMetaProps = exports.BlockletMetaProps = _propTypes.default.shape({
12
12
  appLogo: _propTypes.default.node,
13
13
  appName: _propTypes.default.string,
14
14
  theme: _propTypes.default.shape({
@@ -26,7 +26,7 @@ const blockletMetaProps = exports.blockletMetaProps = _propTypes.default.shape({
26
26
  }))
27
27
  }))
28
28
  });
29
- const sessionManagerProps = exports.sessionManagerProps = _propTypes.default.shape({
29
+ const SessionManagerProps = exports.SessionManagerProps = _propTypes.default.shape({
30
30
  showText: _propTypes.default.bool,
31
31
  showRole: _propTypes.default.bool,
32
32
  switchDid: _propTypes.default.bool,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/ui-react",
3
- "version": "2.9.52",
3
+ "version": "2.9.54",
4
4
  "description": "Some useful front-end web components that can be used in Blocklets.",
5
5
  "keywords": [
6
6
  "react",
@@ -18,9 +18,9 @@
18
18
  "url": "git+https://github.com/ArcBlock/ux.git"
19
19
  },
20
20
  "scripts": {
21
- "lint": "eslint src tests --ext js --ext jsx",
21
+ "lint": "eslint src tests --ext js --ext jsx --ext tsx --ext ts",
22
22
  "lint:fix": "npm run lint -- --fix",
23
- "build": "unbuild && node tools/auto-exports.js",
23
+ "build": "unbuild",
24
24
  "watch": "CONSOLA_LEVEL=1 nodemon -e .jsx,.js,.ts,.tsx -w src -x 'yalc publish --push'",
25
25
  "precommit": "CI=1 npm run lint",
26
26
  "prepush": "CI=1 npm run lint",
@@ -63,8 +63,9 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "@abtnode/constant": "^1.16.24",
66
- "@arcblock/did-connect": "^2.9.52",
67
- "@arcblock/ux": "^2.9.52",
66
+ "@arcblock/did-connect": "^2.9.54",
67
+ "@arcblock/react-hooks": "^2.9.54",
68
+ "@arcblock/ux": "^2.9.54",
68
69
  "@blocklet/js-sdk": "^1.16.24",
69
70
  "@emotion/react": "^11.10.4",
70
71
  "@emotion/styled": "^11.10.4",
@@ -72,14 +73,20 @@
72
73
  "@iconify/react": "^4.1.1",
73
74
  "ahooks": "^3.7.10",
74
75
  "axios": "^0.27.2",
76
+ "clsx": "^2.1.0",
75
77
  "core-js": "^3.25.5",
78
+ "dsbridge": "^3.1.4",
76
79
  "iconify-icon": "^1.0.8",
77
80
  "iconify-icons-material-symbols-400": "^0.0.1",
78
81
  "is-url": "^1.2.4",
79
82
  "lodash": "^4.17.21",
83
+ "p-all": "^5.0.0",
80
84
  "p-wait-for": "^5.0.2",
85
+ "prop-types": "^15.8.1",
81
86
  "react-error-boundary": "^3.1.4",
82
87
  "react-placeholder": "^4.1.0",
88
+ "react-router-dom": "^6.22.3",
89
+ "ua-parser-js": "^1.0.37",
83
90
  "ufo": "^1.3.2",
84
91
  "url-join": "^4.0.1"
85
92
  },
@@ -96,10 +103,11 @@
96
103
  "@babel/core": "^7.19.3",
97
104
  "@babel/preset-env": "^7.19.3",
98
105
  "@babel/preset-react": "^7.18.6",
106
+ "@types/ua-parser-js": "^0.7.39",
99
107
  "eslint-plugin-react-hooks": "^4.6.0",
100
108
  "glob": "^10.3.3",
101
109
  "jest": "^28.1.3",
102
110
  "unbuild": "^2.0.0"
103
111
  },
104
- "gitHead": "362391bd55f3b943e59f16dfaaded615c64ecb93"
112
+ "gitHead": "497c6bb83ad04937b3ba6a182e79383889a4562e"
105
113
  }
@@ -1,15 +1,13 @@
1
1
  import type { Axios } from 'axios';
2
+ import type { UserPublicInfo } from '@blocklet/js-sdk';
2
3
 
3
4
  export type SessionContext = {
4
5
  session: Session;
5
6
  api: Axios;
6
7
  };
7
8
 
8
- export type User = {
9
- did: string;
10
- fullName: string;
9
+ export type User = UserPublicInfo & {
11
10
  role: string;
12
- avatar: string;
13
11
  email?: string;
14
12
  phone?: string;
15
13
  sourceProvider?: string;
@@ -17,7 +15,7 @@ export type User = {
17
15
  lastLoginIp?: string;
18
16
  createdAt?: string;
19
17
  passports?: any[];
20
- didSpace: Record<string, any>;
18
+ didSpace?: Record<string, any>;
21
19
  };
22
20
 
23
21
  export type UserCenterTab = {
@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
6
6
  import { SessionContext } from '@arcblock/did-connect/lib/Session';
7
7
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
8
8
  import UxDashboard from '@arcblock/ux/lib/Layout/dashboard';
9
- import { blockletMetaProps, sessionManagerProps } from '../types';
9
+ import { BlockletMetaProps, SessionManagerProps } from '../types';
10
10
  import { mapRecursive, flatRecursive, matchPaths } from '../utils';
11
11
  import { publicPath, formatBlockletInfo, getLocalizedNavigation, filterNavByRole } from '../blocklets';
12
12
  import HeaderAddons from '../common/header-addons';
@@ -32,6 +32,7 @@ function Dashboard({ meta, fallbackUrl, invalidPathFallback, headerAddons, sessi
32
32
  }
33
33
  }, [meta]);
34
34
  const { localizedNav, flattened, matchedIndex } = useMemo(() => {
35
+ // eslint-disable-next-line @typescript-eslint/no-shadow
35
36
  let localizedNav = getLocalizedNavigation(formattedBlocklet?.navigation?.dashboard, locale) || [];
36
37
  // 根据 role 筛选 nav 数据
37
38
  localizedNav = filterNavByRole(localizedNav, userRole);
@@ -49,7 +50,9 @@ function Dashboard({ meta, fallbackUrl, invalidPathFallback, headerAddons, sessi
49
50
  'items'
50
51
  );
51
52
  // 展平后使用 matchPaths 检测 link#active 状态
53
+ // eslint-disable-next-line @typescript-eslint/no-shadow
52
54
  const flattened = flatRecursive(localizedNav).filter((item) => !!item.url);
55
+ // eslint-disable-next-line @typescript-eslint/no-shadow
53
56
  const matchedIndex = matchPaths(flattened.map((item) => item.url));
54
57
  if (matchedIndex !== -1) {
55
58
  flattened[matchedIndex].active = true;
@@ -84,6 +87,7 @@ function Dashboard({ meta, fallbackUrl, invalidPathFallback, headerAddons, sessi
84
87
  return null;
85
88
  }
86
89
  const { appLogo, appLogoRect, appName } = formattedBlocklet;
90
+ // eslint-disable-next-line @typescript-eslint/naming-convention
87
91
  const _headerAddons = (
88
92
  <HeaderAddons
89
93
  formattedBlocklet={formattedBlocklet}
@@ -111,13 +115,13 @@ function Dashboard({ meta, fallbackUrl, invalidPathFallback, headerAddons, sessi
111
115
  }
112
116
 
113
117
  Dashboard.propTypes = {
114
- meta: blockletMetaProps,
118
+ meta: BlockletMetaProps,
115
119
  // 如果当前用户没有权限访问任何导航菜单, 则自动跳转到 fallbackUrl, 默认值为 publicPath, 设置为 null 表示禁用自动跳转
116
120
  fallbackUrl: PropTypes.string,
117
121
  // 当前路径未匹配任何 nav links 时的 fallback, 默认行为跳转到首个可用的 nav link
118
122
  invalidPathFallback: PropTypes.func,
119
123
  headerAddons: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
120
- sessionManagerProps,
124
+ sessionManagerProps: SessionManagerProps,
121
125
  links: PropTypes.oneOfType([PropTypes.array, PropTypes.func]),
122
126
  };
123
127
 
@@ -11,7 +11,7 @@ import OverridableThemeProvider from '../common/overridable-theme-provider';
11
11
  import InternalFooter from './internal-footer';
12
12
  import { mapRecursive } from '../utils';
13
13
  import { formatBlockletInfo, getLocalizedNavigation } from '../blocklets';
14
- import { blockletMetaProps } from '../types';
14
+ import { BlockletMetaProps } from '../types';
15
15
 
16
16
  /**
17
17
  * 专门用于 (composable) blocklet 的 Footer 组件, 基于 blocklet meta 中的数据渲染
@@ -72,7 +72,7 @@ function Footer({ meta, theme: themeOverrides, ...rest }) {
72
72
  }
73
73
 
74
74
  Footer.propTypes = {
75
- meta: blockletMetaProps,
75
+ meta: BlockletMetaProps,
76
76
  // 允许覆盖 footer 内置的 theme
77
77
  theme: PropTypes.object,
78
78
  };
@@ -11,7 +11,7 @@ import omit from 'lodash/omit';
11
11
 
12
12
  import Icon from '../Icon';
13
13
  import OverridableThemeProvider from '../common/overridable-theme-provider';
14
- import { blockletMetaProps, sessionManagerProps } from '../types';
14
+ import { BlockletMetaProps, SessionManagerProps } from '../types';
15
15
  import { mapRecursive, flatRecursive, matchPaths } from '../utils';
16
16
  import { publicPath, formatBlockletInfo, getLocalizedNavigation } from '../blocklets';
17
17
  import HeaderAddons from '../common/header-addons';
@@ -61,6 +61,7 @@ const parseNavigation = (navigation) => {
61
61
  * 专门用于 (composable) blocklet 的 Header 组件, 解析 blocklet meta 中的数据, 通过组合 UX 中的 Header & NavMenu 组件来渲染
62
62
  */
63
63
  // eslint-disable-next-line no-shadow
64
+
64
65
  function Header({ meta, addons, sessionManagerProps, homeLink, theme: themeOverrides, hideNavMenu, ...rest }) {
65
66
  useWalletHiddenTopbar();
66
67
  const { locale } = useLocaleContext() || {};
@@ -82,6 +83,7 @@ function Header({ meta, addons, sessionManagerProps, homeLink, theme: themeOverr
82
83
  const parsedNavigation = parseNavigation(navigation);
83
84
  const { navItems, activeId } = parsedNavigation;
84
85
 
86
+ // eslint-disable-next-line @typescript-eslint/naming-convention
85
87
  const _addons =
86
88
  typeof addons === 'function' ? (builtInAddons) => addons(builtInAddons, { navigation: parsedNavigation }) : addons;
87
89
  const headerAddons = (
@@ -116,14 +118,14 @@ function Header({ meta, addons, sessionManagerProps, homeLink, theme: themeOverr
116
118
  }
117
119
 
118
120
  Header.propTypes = {
119
- meta: blockletMetaProps,
121
+ meta: BlockletMetaProps,
120
122
 
121
123
  // 需要考虑 定制的 addons 与内置的 连接钱包/选择语言 addons 共存的情况
122
124
  // - PropTypes.func: 可以把自定义 addons 插在 session-manager 或 locale-selector (如果存在的话) 前/中/后
123
125
  // - PropTypes.node: 将 addons 原样传给 UX Header 组件
124
126
  addons: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
125
127
 
126
- sessionManagerProps,
128
+ sessionManagerProps: SessionManagerProps,
127
129
  homeLink: PropTypes.string,
128
130
  // 允许覆盖 header 内置的 theme
129
131
  theme: PropTypes.object,
@@ -8,6 +8,7 @@ import { isUrl, isIconifyString } from '../utils';
8
8
  * Icon 组件, 基于 mui Avatar 组件扩展对 iconify 的支持
9
9
  */
10
10
  export default function Icon({ icon, size, sx, ...rest }) {
11
+ // eslint-disable-next-line @typescript-eslint/naming-convention
11
12
  const _sx = [...(Array.isArray(sx) ? sx : [sx])];
12
13
  if (size) {
13
14
  _sx.push({ width: size, height: size });
@@ -10,13 +10,13 @@ import Toast from '@arcblock/ux/lib/Toast';
10
10
  import { getWalletDid } from '@arcblock/ux/lib/SessionUser/libs/utils';
11
11
  import { translate } from '@arcblock/ux/lib/Locale/util';
12
12
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
13
+ import { AxiosError } from 'axios';
13
14
 
14
15
  import { translations } from '../libs/locales';
15
16
  import WebhookItem from './webhook-item';
16
17
  import { User, WebhookItemData } from '../../@types';
17
18
  import { formatAxiosError } from '../libs/utils';
18
- import { client } from '../libs/client';
19
- import { AxiosError } from 'axios';
19
+ import { client } from '../../libs/client';
20
20
 
21
21
  export default function Notification({ user }: { user: User }) {
22
22
  const { locale } = useLocaleContext();
@@ -31,9 +31,8 @@ export default function Passport({ user, ...rest }: { user: User } & BoxProps) {
31
31
  }
32
32
  if (a.revoked) {
33
33
  return 1;
34
- } else {
35
- return -1;
36
34
  }
35
+ return -1;
37
36
  });
38
37
 
39
38
  return uniqBy(passportList, 'role');
@@ -8,7 +8,7 @@ import Toast from '@arcblock/ux/lib/Toast';
8
8
  import type { AxiosError } from 'axios';
9
9
 
10
10
  import { translations } from '../libs/locales';
11
- import { client } from '../libs/client';
11
+ import { client } from '../../libs/client';
12
12
  import { formatAxiosError } from '../libs/utils';
13
13
 
14
14
  type PrivacyConfig = {
@@ -4,12 +4,14 @@ import type { BoxProps } from '@mui/material';
4
4
  import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
5
5
  import { translate } from '@arcblock/ux/lib/Locale/util';
6
6
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
7
+
7
8
  import { ConfigUserSpaceProvider } from '../../contexts/config-user-space';
8
9
  import { translations } from '../libs/locales';
9
10
  import Notification from './notification';
10
11
  import Privacy from './privacy';
11
12
  import { User, UserCenterTab } from '../../@types';
12
13
  import DidSpace from './storage';
14
+ import { UserSessions } from '../../UserSessions';
13
15
 
14
16
  export default function Settings({
15
17
  user,
@@ -52,7 +54,16 @@ export default function Settings({
52
54
  user?.didSpace?.endpoint && {
53
55
  label: t('storageManagement'),
54
56
  value: 'storage',
55
- content: <ConfigUserSpaceProvider><DidSpace /></ConfigUserSpaceProvider>,
57
+ content: (
58
+ <ConfigUserSpaceProvider>
59
+ <DidSpace />
60
+ </ConfigUserSpaceProvider>
61
+ ),
62
+ },
63
+ {
64
+ label: t('sessionManagement'),
65
+ value: 'session',
66
+ content: <UserSessions user={user} />,
56
67
  },
57
68
  ].filter(Boolean);
58
69
  }, [user, privacyConfigList]);
@@ -73,7 +84,9 @@ export default function Settings({
73
84
  {...rest}
74
85
  sx={{
75
86
  ...rest?.sx,
76
- width: 520,
87
+ minWidth: {
88
+ md: 500,
89
+ },
77
90
  maxWidth: '100%',
78
91
  }}>
79
92
  <Tabs variant="card" tabs={tabs} current={currentTab.value} onChange={handleChangeTab} />