@blocklet/ui-react 3.4.15 → 3.5.0

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 (255) hide show
  1. package/lib/common/org-switch/use-org.d.ts +4 -4
  2. package/package.json +9 -6
  3. package/.aigne/doc-smith/.local/afs-storage.sqlite3 +0 -0
  4. package/.aigne/doc-smith/config.yaml +0 -78
  5. package/.aigne/doc-smith/history.yaml +0 -14
  6. package/.aigne/doc-smith/media-description.yaml +0 -11
  7. package/.aigne/doc-smith/output/structure-plan.json +0 -255
  8. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  9. package/.aigne/doc-smith/upload-cache.yaml +0 -528
  10. package/build.config.ts +0 -24
  11. package/docs/_sidebar.md +0 -19
  12. package/docs/assets/diagram/component-installer-diagram-0.ja.jpg +0 -0
  13. package/docs/assets/diagram/component-installer-diagram-0.jpg +0 -0
  14. package/docs/assets/diagram/component-installer-diagram-0.zh-TW.jpg +0 -0
  15. package/docs/assets/diagram/component-installer-diagram-0.zh.jpg +0 -0
  16. package/docs/assets/diagram/component-management-diagram-0.ja.jpg +0 -0
  17. package/docs/assets/diagram/component-management-diagram-0.jpg +0 -0
  18. package/docs/assets/diagram/component-management-diagram-0.zh-TW.jpg +0 -0
  19. package/docs/assets/diagram/component-management-diagram-0.zh.jpg +0 -0
  20. package/docs/assets/diagram/core-concepts-diagram-0.ja.jpg +0 -0
  21. package/docs/assets/diagram/core-concepts-diagram-0.jpg +0 -0
  22. package/docs/assets/diagram/core-concepts-diagram-0.zh-TW.jpg +0 -0
  23. package/docs/assets/diagram/core-concepts-diagram-0.zh.jpg +0 -0
  24. package/docs/assets/diagram/dashboard-diagram-0.ja.jpg +0 -0
  25. package/docs/assets/diagram/dashboard-diagram-0.jpg +0 -0
  26. package/docs/assets/diagram/dashboard-diagram-0.zh-TW.jpg +0 -0
  27. package/docs/assets/diagram/dashboard-diagram-0.zh.jpg +0 -0
  28. package/docs/assets/diagram/header-diagram-0.ja.jpg +0 -0
  29. package/docs/assets/diagram/header-diagram-0.jpg +0 -0
  30. package/docs/assets/diagram/header-diagram-0.zh-TW.jpg +0 -0
  31. package/docs/assets/diagram/header-diagram-0.zh.jpg +0 -0
  32. package/docs/assets/diagram/layout-diagram-0.ja.jpg +0 -0
  33. package/docs/assets/diagram/layout-diagram-0.jpg +0 -0
  34. package/docs/assets/diagram/layout-diagram-0.zh-TW.jpg +0 -0
  35. package/docs/assets/diagram/layout-diagram-0.zh.jpg +0 -0
  36. package/docs/assets/diagram/notifications-diagram-0.ja.jpg +0 -0
  37. package/docs/assets/diagram/notifications-diagram-0.jpg +0 -0
  38. package/docs/assets/diagram/notifications-diagram-0.zh-TW.jpg +0 -0
  39. package/docs/assets/diagram/notifications-diagram-0.zh.jpg +0 -0
  40. package/docs/assets/diagram/overview-diagram-0.ja.jpg +0 -0
  41. package/docs/assets/diagram/overview-diagram-0.jpg +0 -0
  42. package/docs/assets/diagram/overview-diagram-0.zh-TW.jpg +0 -0
  43. package/docs/assets/diagram/overview-diagram-0.zh.jpg +0 -0
  44. package/docs/assets/diagram/user-center-diagram-0.ja.jpg +0 -0
  45. package/docs/assets/diagram/user-center-diagram-0.jpg +0 -0
  46. package/docs/assets/diagram/user-center-diagram-0.zh-TW.jpg +0 -0
  47. package/docs/assets/diagram/user-center-diagram-0.zh.jpg +0 -0
  48. package/docs/assets/diagram/user-management-diagram-0.ja.jpg +0 -0
  49. package/docs/assets/diagram/user-management-diagram-0.jpg +0 -0
  50. package/docs/assets/diagram/user-management-diagram-0.zh-TW.jpg +0 -0
  51. package/docs/assets/diagram/user-management-diagram-0.zh.jpg +0 -0
  52. package/docs/assets/diagram/user-sessions-diagram-0.ja.jpg +0 -0
  53. package/docs/assets/diagram/user-sessions-diagram-0.jpg +0 -0
  54. package/docs/assets/diagram/user-sessions-diagram-0.zh-TW.jpg +0 -0
  55. package/docs/assets/diagram/user-sessions-diagram-0.zh.jpg +0 -0
  56. package/docs/components-component-management-blocklet-studio.ja.md +0 -194
  57. package/docs/components-component-management-blocklet-studio.md +0 -194
  58. package/docs/components-component-management-blocklet-studio.zh-TW.md +0 -194
  59. package/docs/components-component-management-blocklet-studio.zh.md +0 -194
  60. package/docs/components-component-management-component-installer.ja.md +0 -182
  61. package/docs/components-component-management-component-installer.md +0 -182
  62. package/docs/components-component-management-component-installer.zh-TW.md +0 -182
  63. package/docs/components-component-management-component-installer.zh.md +0 -182
  64. package/docs/components-component-management.ja.md +0 -30
  65. package/docs/components-component-management.md +0 -30
  66. package/docs/components-component-management.zh-TW.md +0 -30
  67. package/docs/components-component-management.zh.md +0 -30
  68. package/docs/components-layout-dashboard.ja.md +0 -185
  69. package/docs/components-layout-dashboard.md +0 -187
  70. package/docs/components-layout-dashboard.zh-TW.md +0 -185
  71. package/docs/components-layout-dashboard.zh.md +0 -185
  72. package/docs/components-layout-footer.ja.md +0 -165
  73. package/docs/components-layout-footer.md +0 -165
  74. package/docs/components-layout-footer.zh-TW.md +0 -165
  75. package/docs/components-layout-footer.zh.md +0 -165
  76. package/docs/components-layout-header.ja.md +0 -183
  77. package/docs/components-layout-header.md +0 -183
  78. package/docs/components-layout-header.zh-TW.md +0 -183
  79. package/docs/components-layout-header.zh.md +0 -183
  80. package/docs/components-layout.ja.md +0 -31
  81. package/docs/components-layout.md +0 -31
  82. package/docs/components-layout.zh-TW.md +0 -31
  83. package/docs/components-layout.zh.md +0 -31
  84. package/docs/components-notifications.ja.md +0 -125
  85. package/docs/components-notifications.md +0 -125
  86. package/docs/components-notifications.zh-TW.md +0 -125
  87. package/docs/components-notifications.zh.md +0 -125
  88. package/docs/components-user-management-user-center.ja.md +0 -148
  89. package/docs/components-user-management-user-center.md +0 -147
  90. package/docs/components-user-management-user-center.zh-TW.md +0 -148
  91. package/docs/components-user-management-user-center.zh.md +0 -148
  92. package/docs/components-user-management-user-sessions.ja.md +0 -121
  93. package/docs/components-user-management-user-sessions.md +0 -123
  94. package/docs/components-user-management-user-sessions.zh-TW.md +0 -121
  95. package/docs/components-user-management-user-sessions.zh.md +0 -121
  96. package/docs/components-user-management.ja.md +0 -49
  97. package/docs/components-user-management.md +0 -51
  98. package/docs/components-user-management.zh-TW.md +0 -49
  99. package/docs/components-user-management.zh.md +0 -49
  100. package/docs/components-utilities-icon.ja.md +0 -106
  101. package/docs/components-utilities-icon.md +0 -106
  102. package/docs/components-utilities-icon.zh-TW.md +0 -106
  103. package/docs/components-utilities-icon.zh.md +0 -106
  104. package/docs/components-utilities.ja.md +0 -136
  105. package/docs/components-utilities.md +0 -136
  106. package/docs/components-utilities.zh-TW.md +0 -136
  107. package/docs/components-utilities.zh.md +0 -136
  108. package/docs/components.ja.md +0 -27
  109. package/docs/components.md +0 -27
  110. package/docs/components.zh-TW.md +0 -27
  111. package/docs/components.zh.md +0 -27
  112. package/docs/core-concepts.ja.md +0 -134
  113. package/docs/core-concepts.md +0 -135
  114. package/docs/core-concepts.zh-TW.md +0 -134
  115. package/docs/core-concepts.zh.md +0 -134
  116. package/docs/getting-started.ja.md +0 -132
  117. package/docs/getting-started.md +0 -132
  118. package/docs/getting-started.zh-TW.md +0 -132
  119. package/docs/getting-started.zh.md +0 -132
  120. package/docs/hooks-api.ja.md +0 -214
  121. package/docs/hooks-api.md +0 -214
  122. package/docs/hooks-api.zh-TW.md +0 -214
  123. package/docs/hooks-api.zh.md +0 -214
  124. package/docs/how-to-guides.ja.md +0 -413
  125. package/docs/how-to-guides.md +0 -413
  126. package/docs/how-to-guides.zh-TW.md +0 -413
  127. package/docs/how-to-guides.zh.md +0 -413
  128. package/docs/overview.ja.md +0 -51
  129. package/docs/overview.md +0 -51
  130. package/docs/overview.zh-TW.md +0 -51
  131. package/docs/overview.zh.md +0 -51
  132. package/glossary.md +0 -12
  133. package/src/@types/index.ts +0 -230
  134. package/src/@types/shims.d.ts +0 -18
  135. package/src/BlockletStudio/README.md +0 -116
  136. package/src/BlockletStudio/index.tsx +0 -145
  137. package/src/ComponentInstaller/ComponentInstaller.stories.jsx +0 -16
  138. package/src/ComponentInstaller/index.jsx +0 -207
  139. package/src/ComponentInstaller/installer-item.jsx +0 -129
  140. package/src/ComponentInstaller/locales.js +0 -22
  141. package/src/ComponentInstaller/use-component-installed.js +0 -88
  142. package/src/ComponentManager/components/add-component.tsx +0 -136
  143. package/src/ComponentManager/components/check-component.tsx +0 -3
  144. package/src/ComponentManager/components/publish-component.tsx +0 -90
  145. package/src/ComponentManager/components/resource-dialog.tsx +0 -91
  146. package/src/ComponentManager/index.tsx +0 -3
  147. package/src/ComponentManager/libs/locales.ts +0 -15
  148. package/src/Dashboard/Dashboard.stories.jsx +0 -20
  149. package/src/Dashboard/app-shell/app-badge.stories.tsx +0 -64
  150. package/src/Dashboard/app-shell/app-badge.tsx +0 -94
  151. package/src/Dashboard/app-shell/app-header.tsx +0 -104
  152. package/src/Dashboard/app-shell/app-info-context.tsx +0 -182
  153. package/src/Dashboard/app-shell/badges/app-badge-default.tsx +0 -130
  154. package/src/Dashboard/app-shell/badges/app-badge-did.tsx +0 -28
  155. package/src/Dashboard/app-shell/badges/app-badge-state.tsx +0 -40
  156. package/src/Dashboard/app-shell/badges/app-badge-switch.tsx +0 -72
  157. package/src/Dashboard/app-shell/badges/app-badge-version.tsx +0 -60
  158. package/src/Dashboard/app-shell/index.ts +0 -5
  159. package/src/Dashboard/index.jsx +0 -184
  160. package/src/Footer/Footer.stories.jsx +0 -33
  161. package/src/Footer/brand.jsx +0 -81
  162. package/src/Footer/copyright.jsx +0 -22
  163. package/src/Footer/index.jsx +0 -111
  164. package/src/Footer/internal-footer.jsx +0 -139
  165. package/src/Footer/layout/plain.jsx +0 -55
  166. package/src/Footer/layout/row.jsx +0 -43
  167. package/src/Footer/layout/standard.jsx +0 -114
  168. package/src/Footer/links.jsx +0 -321
  169. package/src/Footer/social-media.jsx +0 -55
  170. package/src/Header/Header.stories.jsx +0 -30
  171. package/src/Header/index.tsx +0 -259
  172. package/src/Icon/Icon.stories.jsx +0 -12
  173. package/src/Icon/index.tsx +0 -87
  174. package/src/Notifications/Snackbar.tsx +0 -261
  175. package/src/Notifications/hooks/use-title.tsx +0 -254
  176. package/src/Notifications/hooks/use-width.tsx +0 -16
  177. package/src/Notifications/utils.ts +0 -246
  178. package/src/UserCenter/assets/banner.png +0 -0
  179. package/src/UserCenter/components/config-inviter.tsx +0 -48
  180. package/src/UserCenter/components/config-profile.tsx +0 -99
  181. package/src/UserCenter/components/danger-zone.tsx +0 -82
  182. package/src/UserCenter/components/editable-field.tsx +0 -273
  183. package/src/UserCenter/components/fallback.tsx +0 -57
  184. package/src/UserCenter/components/nft-preview.tsx +0 -84
  185. package/src/UserCenter/components/nft.tsx +0 -279
  186. package/src/UserCenter/components/notification.tsx +0 -319
  187. package/src/UserCenter/components/passport.tsx +0 -107
  188. package/src/UserCenter/components/privacy.tsx +0 -120
  189. package/src/UserCenter/components/settings.tsx +0 -170
  190. package/src/UserCenter/components/status-dialog/date-picker.tsx +0 -77
  191. package/src/UserCenter/components/status-dialog/index.tsx +0 -293
  192. package/src/UserCenter/components/status-selector/duration-menu.tsx +0 -90
  193. package/src/UserCenter/components/status-selector/index.tsx +0 -58
  194. package/src/UserCenter/components/status-selector/menu-item.tsx +0 -56
  195. package/src/UserCenter/components/storage/action.tsx +0 -49
  196. package/src/UserCenter/components/storage/connected.tsx +0 -61
  197. package/src/UserCenter/components/storage/delete.tsx +0 -72
  198. package/src/UserCenter/components/storage/disconnect.tsx +0 -40
  199. package/src/UserCenter/components/storage/icons/empty-spaces-nft.svg +0 -1
  200. package/src/UserCenter/components/storage/icons/long-arrow.svg +0 -5
  201. package/src/UserCenter/components/storage/icons/space-connected.svg +0 -3
  202. package/src/UserCenter/components/storage/icons/space-disconnect.svg +0 -3
  203. package/src/UserCenter/components/storage/index.tsx +0 -41
  204. package/src/UserCenter/components/storage/preview-nft.tsx +0 -72
  205. package/src/UserCenter/components/third-party-login/index.tsx +0 -199
  206. package/src/UserCenter/components/third-party-login/third-party-item.tsx +0 -296
  207. package/src/UserCenter/components/user-center.tsx +0 -787
  208. package/src/UserCenter/components/user-info/address.tsx +0 -143
  209. package/src/UserCenter/components/user-info/index.tsx +0 -4
  210. package/src/UserCenter/components/user-info/link-preview-input.tsx +0 -274
  211. package/src/UserCenter/components/user-info/metadata.tsx +0 -658
  212. package/src/UserCenter/components/user-info/social-actions/chat.tsx +0 -43
  213. package/src/UserCenter/components/user-info/social-actions/follow.tsx +0 -23
  214. package/src/UserCenter/components/user-info/social-actions/index.tsx +0 -17
  215. package/src/UserCenter/components/user-info/switch-role.tsx +0 -42
  216. package/src/UserCenter/components/user-info/timezone-select.tsx +0 -119
  217. package/src/UserCenter/components/user-info/user-basic-info.tsx +0 -292
  218. package/src/UserCenter/components/user-info/user-info-item.tsx +0 -54
  219. package/src/UserCenter/components/user-info/user-info.tsx +0 -91
  220. package/src/UserCenter/components/user-info/user-status.tsx +0 -234
  221. package/src/UserCenter/components/user-info/utils.ts +0 -320
  222. package/src/UserCenter/components/webhook-item.tsx +0 -248
  223. package/src/UserCenter/index.tsx +0 -1
  224. package/src/UserCenter/libs/locales.ts +0 -378
  225. package/src/UserCenter/libs/utils.ts +0 -30
  226. package/src/UserSessions/components/user-session-info.tsx +0 -78
  227. package/src/UserSessions/components/user-sessions.tsx +0 -545
  228. package/src/UserSessions/index.tsx +0 -1
  229. package/src/UserSessions/libs/locales.ts +0 -60
  230. package/src/UserSessions/libs/utils.ts +0 -82
  231. package/src/blocklets.js +0 -195
  232. package/src/common/domain-warning.jsx +0 -178
  233. package/src/common/header-addons.jsx +0 -119
  234. package/src/common/link-blocker.jsx +0 -20
  235. package/src/common/notification-addon.jsx +0 -135
  236. package/src/common/org-switch/avatar-uploader.jsx +0 -271
  237. package/src/common/org-switch/create.jsx +0 -267
  238. package/src/common/org-switch/index.jsx +0 -407
  239. package/src/common/org-switch/locales.js +0 -52
  240. package/src/common/org-switch/use-org.jsx +0 -79
  241. package/src/common/overridable-theme-provider.jsx +0 -17
  242. package/src/common/wallet-hidden-topbar.js +0 -14
  243. package/src/common/wizard-modal.jsx +0 -200
  244. package/src/common/ws.js +0 -68
  245. package/src/contexts/config-user-space.tsx +0 -88
  246. package/src/contexts/user-followers.tsx +0 -54
  247. package/src/hooks/use-follow.tsx +0 -75
  248. package/src/hooks/use-mobile.tsx +0 -6
  249. package/src/index.ts +0 -16
  250. package/src/libs/constant.ts +0 -1
  251. package/src/libs/spaces.tsx +0 -18
  252. package/src/libs/with-hide-when-embed.tsx +0 -24
  253. package/src/types.js +0 -45
  254. package/src/utils.js +0 -161
  255. package/vite.config.mjs +0 -34
@@ -1,407 +0,0 @@
1
- /**
2
- * orgs switch
3
- */
4
- import PropTypes from 'prop-types';
5
- import { useState, useRef, useMemo, useEffect } from 'react';
6
- import { useDebounce, useInfiniteScroll, useMemoizedFn, useRequest } from 'ahooks';
7
- import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
8
- import {
9
- Box,
10
- Button,
11
- Typography,
12
- Menu,
13
- MenuItem,
14
- TextField,
15
- Divider,
16
- Avatar,
17
- ListItemAvatar,
18
- ListItemText,
19
- InputAdornment,
20
- } from '@mui/material';
21
- import { joinURL, withQuery } from 'ufo';
22
- import { KeyboardArrowDown, Search, Add, OpenInNew } from '@mui/icons-material';
23
- import { translate } from '@arcblock/ux/lib/Locale/util';
24
-
25
- import useOrg from './use-org';
26
- import { CreateOrgDialog } from './create';
27
- import translations from './locales';
28
-
29
- const PAGE_SIZE = 20;
30
-
31
- export default function OrgsSwitch({ session, locale = 'en' }) {
32
- const [anchorEl, setAnchorEl] = useState(null);
33
- const [searchText, setSearchText] = useState('');
34
- const [visible, setVisible] = useState(false);
35
- const buttonRef = useRef(null);
36
-
37
- const t = useMemoizedFn((key, data = {}) => {
38
- return translate(translations, key, locale, 'en', data);
39
- });
40
-
41
- const { getOrgs, getCurrentOrg } = useOrg(session);
42
-
43
- const role = useMemo(() => {
44
- return session?.user?.role || '';
45
- }, [session?.user?.role]);
46
-
47
- // 根据登录用户的 role 找到对应的 org
48
- const { data: loggedOrg = {} } = useRequest(
49
- () => {
50
- return getCurrentOrg(role);
51
- },
52
- {
53
- ready: !!role,
54
- refreshDeps: [role],
55
- onError: (error) => {
56
- console.error('Failed to get organization role', error);
57
- },
58
- }
59
- );
60
-
61
- const currentOrg = useMemo(() => {
62
- if (loggedOrg) {
63
- return loggedOrg;
64
- }
65
- const passport = session?.user?.passports?.find((p) => p.name === role);
66
- return {
67
- name: passport?.title || role || '-',
68
- };
69
- }, [loggedOrg, role, session?.user?.passports]);
70
-
71
- const debouncedSearchText = useDebounce(searchText, { wait: 500 });
72
-
73
- const { data, loadMore, loadingMore, reload } = useInfiniteScroll(
74
- async (d) => {
75
- const page = d ? Math.ceil(d.list.length / PAGE_SIZE) + 1 : 1;
76
- const params = { page, pageSize: PAGE_SIZE, search: searchText };
77
- const response = await getOrgs(params);
78
-
79
- const { orgs: resultOrgs = [], paging } = response || {};
80
- return { list: resultOrgs, total: paging?.total || 0 };
81
- },
82
- {
83
- ready: !!role,
84
- reloadDeps: [debouncedSearchText],
85
- isNoMore: (d) => {
86
- if (!d?.list.length) return true;
87
- return d.list.length >= d?.total;
88
- },
89
- onError: (error) => {
90
- console.error('Failed to fetch organizations list', error);
91
- },
92
- }
93
- );
94
-
95
- const { list: allOrgs = [], total = 0 } = data || {};
96
-
97
- const hasMore = allOrgs.length < total;
98
-
99
- // 处理滚动事件
100
- const handleListboxScroll = useMemoizedFn((event) => {
101
- const listbox = event.target;
102
- const { scrollTop, scrollHeight, clientHeight } = listbox;
103
- // 当滚动到距离底部50px时开始加载
104
- if (scrollHeight - scrollTop - clientHeight < 50 && !loadingMore && hasMore) {
105
- loadMore();
106
- }
107
- });
108
-
109
- const open = Boolean(anchorEl);
110
-
111
- useEffect(() => {
112
- if (open) {
113
- reload();
114
- }
115
- }, [open, reload]);
116
-
117
- const handleClick = (event) => {
118
- setAnchorEl(event.currentTarget);
119
- };
120
-
121
- const handleClose = () => {
122
- setAnchorEl(null);
123
- setVisible(false);
124
- setSearchText('');
125
- };
126
-
127
- const handleOrgSelect = (org) => {
128
- session.switchPassport(
129
- () => {
130
- window.location.reload();
131
- },
132
- { orgId: org.id }
133
- );
134
- handleClose();
135
- };
136
-
137
- const handleCreateNew = () => {
138
- setVisible(true);
139
- };
140
-
141
- const handleViewAll = () => {
142
- const targetUrl = withQuery(joinURL(WELLKNOWN_SERVICE_PATH_PREFIX, 'user/orgs'), { locale });
143
- window.location.href = targetUrl;
144
- handleClose();
145
- };
146
-
147
- // 渲染组织项目
148
- const renderOrgItem = (org) => (
149
- <MenuItem
150
- key={org.id}
151
- onClick={() => handleOrgSelect(org)}
152
- selected={org.id === currentOrg.id}
153
- sx={{
154
- py: 1.5,
155
- px: 2,
156
- '&.Mui-selected': {
157
- backgroundColor: 'action.selected',
158
- '&:hover': {
159
- backgroundColor: 'action.hover',
160
- },
161
- },
162
- }}>
163
- <ListItemAvatar sx={{ minWidth: 40 }}>
164
- <Avatar
165
- sx={{
166
- width: 28,
167
- height: 28,
168
- fontSize: 14,
169
- bgcolor: org.isOwner ? 'primary.main' : 'grey.400',
170
- }}>
171
- {org.name?.[0]}
172
- </Avatar>
173
- </ListItemAvatar>
174
- <Box sx={{ display: 'flex', alignItems: 'center', flex: 1 }}>
175
- <ListItemText
176
- sx={{
177
- '& .MuiListItemText-primary': {
178
- mb: 0,
179
- },
180
- '& .MuiListItemText-secondary': {
181
- mt: '-2px',
182
- },
183
- }}
184
- primary={
185
- <Typography variant="body2" sx={{ fontWeight: 500, lineHeight: 1.2 }}>
186
- {org.name}
187
- </Typography>
188
- }
189
- secondary={
190
- <Typography variant="caption" color="text.secondary" sx={{ lineHeight: 1.1 }}>
191
- {org.passports?.[0]?.title}
192
- </Typography>
193
- }
194
- />
195
- {org.id === currentOrg.id && (
196
- <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', ml: 1 }}>
197
- <Typography variant="caption" color="primary" sx={{ fontSize: 10 }}>
198
-
199
- </Typography>
200
- </Box>
201
- )}
202
- </Box>
203
- </MenuItem>
204
- );
205
-
206
- return (
207
- <Box>
208
- <Button
209
- ref={buttonRef}
210
- onClick={handleClick}
211
- endIcon={<KeyboardArrowDown />}
212
- sx={{
213
- display: 'flex',
214
- alignItems: 'center',
215
- gap: 1,
216
- px: 2,
217
- py: 1,
218
- borderRadius: 1,
219
- textTransform: 'none',
220
- color: 'text.primary',
221
- '&:hover': {
222
- backgroundColor: 'action.hover',
223
- },
224
- }}
225
- data-testid="org-switch-button">
226
- <Avatar
227
- sx={{
228
- width: 24,
229
- height: 24,
230
- fontSize: 12,
231
- bgcolor: 'primary.main',
232
- }}>
233
- {currentOrg.name?.[0]}
234
- </Avatar>
235
- <Typography variant="body2" sx={{ fontWeight: 500 }}>
236
- {currentOrg.name}
237
- </Typography>
238
- </Button>
239
-
240
- <Menu
241
- anchorEl={anchorEl}
242
- open={open}
243
- onClose={handleClose}
244
- anchorOrigin={{
245
- vertical: 'bottom',
246
- horizontal: 'left',
247
- }}
248
- transformOrigin={{
249
- vertical: 'top',
250
- horizontal: 'left',
251
- }}
252
- PaperProps={{
253
- sx: {
254
- width: 340,
255
- maxHeight: 480,
256
- overflow: 'visible',
257
- mt: 0.5,
258
- borderRadius: 2,
259
- boxShadow: '0px 4px 20px rgba(0, 0, 0, 0.08)',
260
- border: (theme) => `1px solid ${theme.palette.divider}`,
261
- },
262
- }}
263
- MenuListProps={{
264
- sx: { py: 0 },
265
- }}>
266
- {/* 搜索框 */}
267
- <Box sx={{ p: 1.5, pb: 1 }}>
268
- <TextField
269
- fullWidth
270
- size="small"
271
- placeholder={t('search')}
272
- value={searchText}
273
- onChange={(e) => setSearchText(e.target.value)}
274
- InputProps={{
275
- startAdornment: (
276
- <InputAdornment position="start">
277
- <Search fontSize="small" color="action" />
278
- </InputAdornment>
279
- ),
280
- }}
281
- onClick={(e) => e.stopPropagation()}
282
- onKeyDown={(e) => e.stopPropagation()}
283
- sx={{
284
- '& .MuiOutlinedInput-root': {
285
- borderRadius: 1,
286
- },
287
- }}
288
- />
289
- </Box>
290
-
291
- {/* 组织标题 */}
292
- <Box sx={{ px: 2, pb: 1 }}>
293
- <Typography
294
- variant="subtitle2"
295
- color="text.secondary"
296
- sx={{
297
- fontSize: 11,
298
- fontWeight: 600,
299
- textTransform: 'uppercase',
300
- letterSpacing: 0.5,
301
- }}>
302
- {t('orgs')}
303
- </Typography>
304
- </Box>
305
-
306
- {/* 组织列表 */}
307
- <Box sx={{ maxHeight: 240, overflow: 'auto' }} onScroll={handleListboxScroll}>
308
- {allOrgs.length > 0 ? (
309
- <>
310
- {allOrgs.map((org, index) => {
311
- const isLast = index === allOrgs.length - 1;
312
- return (
313
- <Box key={org.id}>
314
- {renderOrgItem(org)}
315
- {/* 加载更多指示器 */}
316
- {isLast && hasMore && (
317
- <Box
318
- sx={{
319
- display: 'flex',
320
- justifyContent: 'center',
321
- py: 1,
322
- color: 'text.secondary',
323
- fontSize: '0.875rem',
324
- }}>
325
- {loadingMore ? t('loadingMore') : ''}
326
- </Box>
327
- )}
328
- </Box>
329
- );
330
- })}
331
- </>
332
- ) : (
333
- <Box sx={{ px: 2, py: 3, textAlign: 'center' }}>
334
- <Typography variant="body2" color="text.secondary">
335
- {t('myJoinedEmpty')}
336
- </Typography>
337
- </Box>
338
- )}
339
- </Box>
340
-
341
- <Divider />
342
-
343
- {/* 创建新组织 */}
344
- <MenuItem
345
- onClick={handleCreateNew}
346
- sx={{
347
- py: 1.5,
348
- px: 2,
349
- '&:hover': {
350
- backgroundColor: 'action.hover',
351
- },
352
- }}>
353
- <ListItemAvatar sx={{ minWidth: 40 }}>
354
- <Avatar
355
- sx={{
356
- width: 28,
357
- height: 28,
358
- bgcolor: 'success.main',
359
- color: 'success.contrastText',
360
- }}>
361
- <Add fontSize="small" />
362
- </Avatar>
363
- </ListItemAvatar>
364
- <ListItemText
365
- primary={
366
- <Typography variant="body2" sx={{ fontWeight: 500 }}>
367
- {t('createNew')}
368
- </Typography>
369
- }
370
- />
371
- </MenuItem>
372
-
373
- <Divider />
374
-
375
- {/* 查看所有组织链接 */}
376
- <Box sx={{ p: 1.5 }}>
377
- <Button
378
- onClick={handleViewAll}
379
- variant="text"
380
- component="a"
381
- size="small"
382
- endIcon={<OpenInNew fontSize="small" />}
383
- sx={{
384
- color: 'primary.main',
385
- fontWeight: 500,
386
- p: 0,
387
- fontSize: 14,
388
- minWidth: 'auto',
389
- '&:hover': {
390
- backgroundColor: 'transparent',
391
- textDecoration: 'underline',
392
- },
393
- }}>
394
- {t('viewAll')}
395
- </Button>
396
- </Box>
397
- </Menu>
398
-
399
- {visible && <CreateOrgDialog onSuccess={handleViewAll} onCancel={() => setVisible(false)} locale={locale} />}
400
- </Box>
401
- );
402
- }
403
-
404
- OrgsSwitch.propTypes = {
405
- session: PropTypes.object.isRequired,
406
- locale: PropTypes.string,
407
- };
@@ -1,52 +0,0 @@
1
- const translations = {
2
- en: {
3
- search: 'Search',
4
- orgs: 'Organizations',
5
- loadingMore: 'Loading more',
6
- myJoinedEmpty: 'You have not joined any organizations yet',
7
- createNew: 'Create New Organization',
8
- viewAll: 'View All Organizations',
9
- nameEmpty: 'Name cannot be empty',
10
- nameTooLong: 'Name must be less than {length} characters',
11
- descriptionTooLong: 'Description must be less than {length} characters',
12
- avatarEmpty: 'Avatar cannot be empty',
13
- cancel: 'Cancel',
14
- create: 'Create',
15
- upload: 'Upload',
16
- avatar: 'Avatar',
17
- mutate: {
18
- title: '{mode} Organization',
19
- name: 'Name',
20
- description: 'Description',
21
- avatarRequired: 'Avatar is required',
22
- uploadAvatarTitle: 'Upload Avatar',
23
- uploadAvatarTip: 'Click to upload an avatar for your organization',
24
- },
25
- },
26
- zh: {
27
- search: '搜索',
28
- orgs: '组织',
29
- loadingMore: '加载更多',
30
- myJoinedEmpty: '您还没有加入任何组织',
31
- createNew: '创建新组织',
32
- viewAll: '查看所有组织',
33
- nameEmpty: '名称不能为空',
34
- nameTooLong: '名称不能超过{length}个字符',
35
- descriptionTooLong: '描述不能超过{length}个字符',
36
- avatarEmpty: '头像不能为空',
37
- upload: '上传',
38
- cancel: '取消',
39
- create: '创建',
40
- avatar: '头像',
41
- mutate: {
42
- title: '{mode}组织',
43
- name: '组织名称',
44
- description: '组织描述',
45
- avatarRequired: '头像为必填项',
46
- uploadAvatarTitle: '上传头像',
47
- uploadAvatarTip: '点击上传组织头像',
48
- },
49
- },
50
- };
51
-
52
- export default translations;
@@ -1,79 +0,0 @@
1
- import { useMemoizedFn } from 'ahooks';
2
- import Toast from '@arcblock/ux/lib/Toast';
3
- import { getBlockletSDK } from '@blocklet/js-sdk';
4
-
5
- import { formatAxiosError } from '../../UserCenter/libs/utils';
6
-
7
- export default function useOrg(session) {
8
- const client = getBlockletSDK();
9
- const getOrgs = useMemoizedFn(async ({ search, page = 1, pageSize = 20 }) => {
10
- try {
11
- const response = await client.user.getOrgs({ search, page, pageSize });
12
- return response;
13
- } catch (error) {
14
- console.error(error);
15
- return {
16
- orgs: [],
17
- paging: {
18
- page,
19
- pageSize,
20
- total: 0,
21
- },
22
- };
23
- }
24
- });
25
-
26
- const createOrg = useMemoizedFn(async ({ name, description, avatar }) => {
27
- try {
28
- const response = await client.user.createOrg({ name, description, avatar });
29
- return response.data;
30
- } catch (error) {
31
- console.error(error);
32
- Toast.error(formatAxiosError(error));
33
- return null;
34
- }
35
- });
36
-
37
- const updateOrg = useMemoizedFn(async (orgId, { name, description, avatar }) => {
38
- try {
39
- const response = await client.user.updateOrg(orgId, { name, description, avatar });
40
- return response.data;
41
- } catch (error) {
42
- console.error(error);
43
- Toast.error(formatAxiosError(error));
44
- return null;
45
- }
46
- });
47
-
48
- const getOrg = useMemoizedFn(async (orgId) => {
49
- try {
50
- const data = await client.user.getOrg(orgId);
51
- return data;
52
- } catch (error) {
53
- session.logout();
54
- console.error(error);
55
- return null;
56
- }
57
- });
58
-
59
- const getCurrentOrg = useMemoizedFn(async (roleName) => {
60
- try {
61
- const response = await client.user.getRole(roleName);
62
- if (response.orgId) {
63
- const org = await getOrg(response.orgId);
64
- return org;
65
- }
66
- return null;
67
- } catch (error) {
68
- console.error(error);
69
- return null;
70
- }
71
- });
72
-
73
- return {
74
- getOrgs,
75
- createOrg,
76
- updateOrg,
77
- getCurrentOrg,
78
- };
79
- }
@@ -1,17 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import { createTheme, ThemeProvider } from '@arcblock/ux/lib/Theme';
3
-
4
- const defaultTheme = createTheme();
5
-
6
- /**
7
- * 允许 theme 被覆盖的 ThemeProvider 组件, 默认使用 ux default theme, 可以传入 theme 进行覆盖
8
- */
9
- export default function OverridableThemeProvider({ theme: themeOverrides = null, children }) {
10
- const theme = themeOverrides ? createTheme(themeOverrides) : defaultTheme;
11
- return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
12
- }
13
-
14
- OverridableThemeProvider.propTypes = {
15
- children: PropTypes.any.isRequired,
16
- theme: PropTypes.object,
17
- };
@@ -1,14 +0,0 @@
1
- import { useEffect } from 'react';
2
- import useBrowser from '@arcblock/react-hooks/lib/useBrowser';
3
- import bridge from '@arcblock/bridge';
4
-
5
- // 在 wallet webview 环境中, 隐藏 wallet topbar
6
- // eslint-disable-next-line import/prefer-default-export
7
- export const useWalletHiddenTopbar = () => {
8
- const browser = useBrowser();
9
- useEffect(() => {
10
- if (browser.wallet || browser.arcSphere) {
11
- bridge.call('arcHideTopBar', '{}');
12
- }
13
- }, [browser]);
14
- };