@abtnode/ux 1.16.14-beta-c308dc3b → 1.16.14-beta-963cb583

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 (213) hide show
  1. package/es/actions.js +97 -0
  2. package/es/analytics/card.js +92 -0
  3. package/es/analytics/chart.js +96 -0
  4. package/es/analytics/cpu.js +36 -0
  5. package/es/analytics/disk.js +111 -0
  6. package/es/analytics/memory.js +72 -0
  7. package/es/analytics/runtime.js +173 -0
  8. package/es/analytics/traffic.js +259 -0
  9. package/es/blocklet/access/config-access.js +307 -0
  10. package/es/blocklet/access/index.js +216 -0
  11. package/es/blocklet/actions.js +474 -0
  12. package/es/blocklet/add-cert.js +177 -0
  13. package/es/blocklet/agreement-app.js +21 -0
  14. package/es/blocklet/agreement.js +127 -0
  15. package/es/blocklet/app-avatar.js +57 -0
  16. package/es/blocklet/audit-logs.js +259 -0
  17. package/es/blocklet/blocklet-source.js +48 -0
  18. package/es/blocklet/bundle-avatar.js +64 -0
  19. package/es/blocklet/component/add.js +1313 -0
  20. package/es/blocklet/component/configuration.js +122 -0
  21. package/es/blocklet/component/delete.js +134 -0
  22. package/es/blocklet/component/environment.js +370 -0
  23. package/es/blocklet/component/index.js +975 -0
  24. package/es/blocklet/component/line.js +20 -0
  25. package/es/blocklet/component/navigation/locale-tabs.js +225 -0
  26. package/es/blocklet/component/navigation/navigation-actions.js +112 -0
  27. package/es/blocklet/component/navigation/navigation-dialog.js +607 -0
  28. package/es/blocklet/component/navigation/navigation-preview.js +101 -0
  29. package/es/blocklet/component/navigation/simple-select.js +124 -0
  30. package/es/blocklet/component/select-store.js +155 -0
  31. package/es/blocklet/component/selected/index.js +94 -0
  32. package/es/blocklet/component/setting.js +109 -0
  33. package/es/blocklet/component/sortable-tree.js +126 -0
  34. package/es/blocklet/component/space-connector.js +199 -0
  35. package/es/blocklet/component/space-selector.js +178 -0
  36. package/es/blocklet/component/start.js +101 -0
  37. package/es/blocklet/component/store-blocklet-list.js +200 -0
  38. package/es/blocklet/component/switch-control.js +57 -0
  39. package/es/blocklet/config-navigation.js +331 -0
  40. package/es/blocklet/configuration.js +603 -0
  41. package/es/blocklet/disk-info.js +75 -0
  42. package/es/blocklet/icons.js +18 -0
  43. package/es/blocklet/install-from-url.js +337 -0
  44. package/es/blocklet/log.js +90 -0
  45. package/es/blocklet/migration.js +149 -0
  46. package/es/blocklet/mode.js +19 -0
  47. package/es/blocklet/notification/email.js +257 -0
  48. package/es/blocklet/notification/index.js +49 -0
  49. package/es/blocklet/oauth/auth0.js +145 -0
  50. package/es/blocklet/oauth/common-settings.js +133 -0
  51. package/es/blocklet/oauth/federated-detail-dialog.js +175 -0
  52. package/es/blocklet/oauth/federated-invite-dialog.js +83 -0
  53. package/es/blocklet/oauth/federated-join-dialog.js +111 -0
  54. package/es/blocklet/oauth/federated-site-list.js +338 -0
  55. package/es/blocklet/oauth/federated.js +81 -0
  56. package/es/blocklet/oauth/index.js +69 -0
  57. package/es/blocklet/overview.js +293 -0
  58. package/es/blocklet/page-group.js +19 -0
  59. package/es/blocklet/preferences/app-sk.js +142 -0
  60. package/es/blocklet/preferences/index.js +305 -0
  61. package/es/blocklet/purchase/common.js +95 -0
  62. package/es/blocklet/purchase/component-purchase.js +237 -0
  63. package/es/blocklet/purchase/index.js +4 -0
  64. package/es/blocklet/router/action/add-domain-alias.js +167 -0
  65. package/es/blocklet/router/action/add-rule.js +211 -0
  66. package/es/blocklet/router/action/config-routing-rule.js +232 -0
  67. package/es/blocklet/router/action/delete-domain-alias.js +99 -0
  68. package/es/blocklet/router/action/delete-rule.js +108 -0
  69. package/es/blocklet/router/action/update-rule.js +209 -0
  70. package/es/blocklet/router/domain-actions.js +64 -0
  71. package/es/blocklet/router/domain-status.js +88 -0
  72. package/es/blocklet/router/rule-actions.js +66 -0
  73. package/es/blocklet/router/rule-list.js +190 -0
  74. package/es/blocklet/router/util.js +131 -0
  75. package/es/blocklet/runtime-info.js +68 -0
  76. package/es/blocklet/status.js +91 -0
  77. package/es/blocklet/storage/action.js +134 -0
  78. package/es/blocklet/storage/backups.js +241 -0
  79. package/es/blocklet/storage/connect-to.js +372 -0
  80. package/es/blocklet/storage/connected.js +198 -0
  81. package/es/blocklet/storage/delete.js +113 -0
  82. package/es/blocklet/storage/disconnect.js +243 -0
  83. package/es/blocklet/storage/index.js +19 -0
  84. package/es/blocklet/storage/item.js +558 -0
  85. package/es/blocklet/storage/preview-nft.js +286 -0
  86. package/es/blocklet/transfer-owner.js +198 -0
  87. package/es/blocklet/types.js +18 -0
  88. package/es/blocklet/util.js +145 -0
  89. package/es/blocklet/version.js +141 -0
  90. package/es/card-selector.js +134 -0
  91. package/es/certificate.js +105 -0
  92. package/es/chain.js +13 -0
  93. package/es/click-to-copy.js +22 -0
  94. package/es/confirm.js +149 -0
  95. package/es/contexts/audit-log.js +152 -0
  96. package/es/contexts/blocklet.js +10 -0
  97. package/es/contexts/deleting-blocklets.js +70 -0
  98. package/es/contexts/node.js +17 -0
  99. package/es/contexts/session.js +8 -0
  100. package/es/contexts/team.js +10 -0
  101. package/es/delete-confirm.js +121 -0
  102. package/es/did-address.js +46 -0
  103. package/es/dot.js +14 -0
  104. package/es/exchange-passport.js +102 -0
  105. package/es/form/form-select-input.js +184 -0
  106. package/es/form/form-text-input.js +178 -0
  107. package/es/form/form-wrapper.js +88 -0
  108. package/es/form/input-triggers.js +98 -0
  109. package/es/form/required.js +8 -0
  110. package/es/hooks/blocklet.js +229 -0
  111. package/es/hooks/confirm.js +90 -0
  112. package/es/hooks/mobile-width.js +11 -0
  113. package/es/hooks/url-evaluation.js +155 -0
  114. package/es/hooks/use-app-logo.js +16 -0
  115. package/es/hooks/use-backup-progress.js +31 -0
  116. package/es/hooks/use-blocklet-info-for-connect-did-spaces.js +50 -0
  117. package/es/hooks/use-bundle-logo.js +27 -0
  118. package/es/hooks/use-navigation.js +347 -0
  119. package/es/hooks/use-passport-id.js +14 -0
  120. package/es/hooks/use-subscription.js +22 -0
  121. package/es/icons/empty-space-nft.svg +59 -0
  122. package/es/icons/empty-spaces-nft.svg +58 -0
  123. package/es/icons/long-arrow.svg +5 -0
  124. package/es/icons/space-connected.svg +3 -0
  125. package/es/icons/space-disconnect.svg +3 -0
  126. package/es/index.js +3 -0
  127. package/es/invitation/invitation-app.js +58 -0
  128. package/es/invitation/invitation-login.js +68 -0
  129. package/es/invitation/invitation-passport.js +146 -0
  130. package/es/invitation/invitation-receive.js +138 -0
  131. package/es/invitation/invitation-success.js +93 -0
  132. package/es/invitation/invitation-user.js +90 -0
  133. package/es/invitation/invitation.js +90 -0
  134. package/es/issue-passport.js +142 -0
  135. package/es/launch-blocklet/content-layout.js +58 -0
  136. package/es/launch-blocklet/page-header.js +43 -0
  137. package/es/layout/addon.js +114 -0
  138. package/es/layout/feedback.js +55 -0
  139. package/es/locales/en.js +1541 -0
  140. package/es/locales/index.js +9 -0
  141. package/es/locales/zh.js +1544 -0
  142. package/es/logs/clock.js +11 -0
  143. package/es/logs/download.js +132 -0
  144. package/es/logs/log-terminal.js +253 -0
  145. package/es/lost-passport.js +452 -0
  146. package/es/nav-logo.js +219 -0
  147. package/es/passport-tag.js +43 -0
  148. package/es/permission.js +57 -0
  149. package/es/relative-time.js +53 -0
  150. package/es/result-message.js +11 -0
  151. package/es/schema-form/color-input.js +98 -0
  152. package/es/schema-form/common-prop-types.js +13 -0
  153. package/es/schema-form/index.js +215 -0
  154. package/es/schema-form/passport-input.js +55 -0
  155. package/es/schema-form/text-input.js +57 -0
  156. package/es/store/add.js +179 -0
  157. package/es/store/delete.js +96 -0
  158. package/es/store/item.js +76 -0
  159. package/es/subscription.js +144 -0
  160. package/es/table-icons.js +34 -0
  161. package/es/table.js +52 -0
  162. package/es/tag.js +21 -0
  163. package/es/team/members/actions.js +89 -0
  164. package/es/team/members/index.js +636 -0
  165. package/es/team/members/invitations.js +188 -0
  166. package/es/team/members/invite-member.js +208 -0
  167. package/es/team/members/issue-passport.js +152 -0
  168. package/es/team/members/member.js +408 -0
  169. package/es/team/members/passport-issuances.js +155 -0
  170. package/es/team/members/passports.js +364 -0
  171. package/es/team/members/toggle-user-approval.js +122 -0
  172. package/es/team/members/transfer-node.js +256 -0
  173. package/es/team/members/util.js +14 -0
  174. package/es/team/passports/color.js +127 -0
  175. package/es/team/passports/detail.js +312 -0
  176. package/es/team/passports/index.js +282 -0
  177. package/es/team/passports/mutate-role.js +198 -0
  178. package/es/team/passports/trusted-factories.js +221 -0
  179. package/es/team/passports/trusted-factory.js +343 -0
  180. package/es/team/passports/trusted-issuer.js +296 -0
  181. package/es/team/passports/trusted-issuers.js +226 -0
  182. package/es/team/search-input.js +46 -0
  183. package/es/team/styles/dialog.js +72 -0
  184. package/es/team/styles/list-header.js +31 -0
  185. package/es/util/api.js +6 -0
  186. package/es/util/constants.js +2 -0
  187. package/es/util/index.js +598 -0
  188. package/es/util/mode.js +4 -0
  189. package/es/util/space-gateway.js +51 -0
  190. package/es/util/spaces.js +160 -0
  191. package/es/who-can-access/config.js +38 -0
  192. package/es/wrap-locale.js +15 -0
  193. package/lib/blocklet/component/add.js +5 -0
  194. package/lib/blocklet/component/selected/index.js +47 -0
  195. package/lib/blocklet/component/space-connector.js +1 -1
  196. package/lib/blocklet/component/space-selector.js +1 -1
  197. package/lib/blocklet/storage/backups.js +1 -1
  198. package/lib/blocklet/storage/connect-to.js +6 -7
  199. package/lib/blocklet/storage/connected.js +1 -1
  200. package/lib/blocklet/storage/disconnect.js +1 -1
  201. package/lib/blocklet/storage/index.js +1 -1
  202. package/lib/blocklet/storage/item.js +1 -1
  203. package/lib/card-selector.js +14 -14
  204. package/lib/invitation/invitation-passport.js +7 -6
  205. package/lib/invitation/invitation-receive.js +1 -1
  206. package/lib/locales/en.js +12 -5
  207. package/lib/locales/zh.js +10 -3
  208. package/lib/lost-passport.js +2 -2
  209. package/lib/schema-form/passport-input.js +12 -11
  210. package/lib/team/passports/color.js +14 -14
  211. package/lib/team/passports/trusted-factory.js +1 -1
  212. package/lib/util/spaces.js +13 -1
  213. package/package.json +88 -21
@@ -0,0 +1,199 @@
1
+ import React, { useContext, useState, useEffect, useImperativeHandle, forwardRef, useMemo } from 'react';
2
+ import DidConnect from '@arcblock/did-connect/lib/Connect';
3
+ import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
4
+ import { BLOCKLET_CONFIGURABLE_KEY } from '@blocklet/constant';
5
+ import axios from 'axios';
6
+ import PropTypes from 'prop-types';
7
+ import joinUrl from 'url-join';
8
+ import { isEmpty } from 'lodash';
9
+ import Typography from '@mui/material/Typography';
10
+ import Toast from '@arcblock/ux/lib/Toast';
11
+ import { getAppName, getAppDescription } from '@blocklet/meta/lib/util';
12
+ import { useBlockletContext } from '../../contexts/blocklet';
13
+ import { useNodeContext } from '../../contexts/node';
14
+ import SpaceSelector from './space-selector';
15
+
16
+ /**
17
+ *
18
+ *
19
+ * @param {import('@abtnode/client').BlockletState} blocklet
20
+ * @return {*}
21
+ */
22
+ import { jsx as _jsx } from "react/jsx-runtime";
23
+ import { Fragment as _Fragment } from "react/jsx-runtime";
24
+ import { jsxs as _jsxs } from "react/jsx-runtime";
25
+ function useAppUrl(blocklet) {
26
+ const appUrls = blocklet?.site?.domainAliases?.sort((a, b) => {
27
+ if (a.accessibility.accessible && b.accessibility.accessible) {
28
+ return +a.isProtected - +b.isProtected;
29
+ }
30
+ return +b.accessibility.accessible - +a.accessibility.accessible;
31
+ })?.map(domainAlias => {
32
+ const protocol = domainAlias?.domainStatus?.isHttps ? 'https://' : 'http://';
33
+ const value = domainAlias?.value;
34
+ return `${protocol}${value}`;
35
+ }).filter(Boolean);
36
+ const appUrl = appUrls?.[0];
37
+
38
+ // 授权的时候提供 appUrl, 因为 appUrl 可能很久都拿不到值,所以加一个 loading 效果过渡一下
39
+ return {
40
+ appUrl,
41
+ isReady: Boolean(appUrl)
42
+ };
43
+ }
44
+ const SpaceConnector = /*#__PURE__*/forwardRef(({
45
+ onConnect,
46
+ ...restProps
47
+ }, ref) => {
48
+ /** @type {{ api: import('@abtnode/client').ABTNodeClient, info: import('@abtnode/client').NodeState }} */
49
+ const {
50
+ api,
51
+ info
52
+ } = useNodeContext();
53
+ const nodeDid = info.did;
54
+ const {
55
+ t,
56
+ locale
57
+ } = useContext(LocaleContext);
58
+ /** @type {{ blocklet: import('@abtnode/client').BlockletState }} */
59
+ const {
60
+ blocklet,
61
+ actions: {
62
+ refreshBlocklet
63
+ }
64
+ } = useBlockletContext();
65
+ const [gatewayUrl, setGatewayUrl] = useState('');
66
+ const spaceProps = useMemo(() => {
67
+ return {
68
+ endpoint: blocklet?.environments?.find(e => e.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SPACE_ENDPOINT)?.value || '',
69
+ gatewayUrl: blocklet?.environments?.find(e => e.key === BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SPACES_URL)?.value || ''
70
+ };
71
+ }, [blocklet]);
72
+ const appName = getAppName(blocklet);
73
+ const appDescription = getAppDescription(blocklet);
74
+ const {
75
+ appUrl,
76
+ isReady
77
+ } = useAppUrl(blocklet);
78
+ async function saveSpaceConnectorEndpoint(did, storageEndpoint) {
79
+ await api.configBlocklet({
80
+ input: {
81
+ did: [did],
82
+ configs: [{
83
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SPACES_URL,
84
+ value: gatewayUrl
85
+ }, {
86
+ key: BLOCKLET_CONFIGURABLE_KEY.BLOCKLET_APP_SPACE_ENDPOINT,
87
+ value: storageEndpoint
88
+ }]
89
+ }
90
+ }).then(() => {
91
+ Toast.success(t('storage.spaces.connect.succeeded', locale));
92
+ }).catch(error => {
93
+ console.error(error);
94
+ Toast.error(error.message);
95
+ });
96
+ }
97
+ const onAuthorizeConnectSuccess = async (response, decrypt) => {
98
+ await saveSpaceConnectorEndpoint(blocklet.meta.did, decrypt(response.endpoint));
99
+ setTimeout(() => {
100
+ setAuthorizeConnect(preValue => ({
101
+ ...preValue,
102
+ open: false
103
+ }));
104
+ onConnect?.();
105
+ refreshBlocklet();
106
+ }, 3000);
107
+ };
108
+ const [authorizeConnect, setAuthorizeConnect] = useState({
109
+ open: false
110
+ });
111
+
112
+ // eslint-disable-next-line no-shadow
113
+ const handleOnClickAuthorize = gatewayUrl => {
114
+ if (isEmpty(gatewayUrl)) {
115
+ Toast.error(t('storage.spaces.addressCannotEmpty', locale));
116
+ return;
117
+ }
118
+ setGatewayUrl(gatewayUrl);
119
+ setAuthorizeConnect(preValue => ({
120
+ ...preValue,
121
+ action: 'one-click-authorization',
122
+ checkTimeout: 1000 * 300,
123
+ prefix: joinUrl(gatewayUrl, 'space/api/did'),
124
+ baseUrl: new URL(gatewayUrl).origin,
125
+ checkFn: axios.create({
126
+ baseURL: joinUrl(gatewayUrl, 'space')
127
+ }).get,
128
+ extraParams: {
129
+ appDid: blocklet.appDid,
130
+ appName,
131
+ appDescription,
132
+ scopes: 'list:object read:object write:object',
133
+ appUrl,
134
+ referrer: window.location.href,
135
+ nodeDid
136
+ },
137
+ onClose: () => {
138
+ // eslint-disable-next-line no-shadow
139
+ setAuthorizeConnect(preValue => ({
140
+ ...preValue,
141
+ open: false
142
+ }));
143
+ },
144
+ open: true
145
+ }));
146
+ };
147
+ useEffect(() => {
148
+ setAuthorizeConnect(preValue => ({
149
+ ...preValue,
150
+ messages: {
151
+ title: t('storage.spaces.authorize.title', {
152
+ appName
153
+ }),
154
+ scan: t('storage.spaces.authorize.scan', {
155
+ appName
156
+ }),
157
+ confirm: '',
158
+ success: /*#__PURE__*/_jsx(Typography, {
159
+ gutterBottom: true,
160
+ children: t('storage.spaces.authorize.success')
161
+ })
162
+ }
163
+ }));
164
+ }, [appName, locale, t]);
165
+ useImperativeHandle(ref, () => ({
166
+ getEndpoint: () => spaceProps.endpoint,
167
+ getGatewayUrl: () => spaceProps.gatewayUrl
168
+ }));
169
+ return /*#__PURE__*/_jsxs(_Fragment, {
170
+ children: [/*#__PURE__*/_jsx(SpaceSelector, {
171
+ ...restProps,
172
+ ...spaceProps,
173
+ onSelect: handleOnClickAuthorize,
174
+ loading: !isReady
175
+ }), /*#__PURE__*/_jsx(DidConnect, {
176
+ forceConnected: false,
177
+ saveConnect: false,
178
+ prefix: authorizeConnect.prefix,
179
+ open: authorizeConnect.open,
180
+ popup: true,
181
+ action: authorizeConnect.action,
182
+ baseUrl: authorizeConnect.baseUrl,
183
+ checkFn: authorizeConnect.checkFn,
184
+ onSuccess: onAuthorizeConnectSuccess,
185
+ onClose: authorizeConnect.onClose,
186
+ checkTimeout: authorizeConnect.checkTimeout,
187
+ extraParams: authorizeConnect.extraParams,
188
+ messages: authorizeConnect.messages,
189
+ locale: locale
190
+ })]
191
+ });
192
+ });
193
+ SpaceConnector.propTypes = {
194
+ onConnect: PropTypes.func
195
+ };
196
+ SpaceConnector.defaultProps = {
197
+ onConnect: () => {}
198
+ };
199
+ export default SpaceConnector;
@@ -0,0 +1,178 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import styled from '@emotion/styled';
4
+ import joinUrl from 'url-join';
5
+ import isUrl from 'is-url';
6
+ import useLocalStorage from 'react-use/lib/useLocalStorage';
7
+ import Button from '@arcblock/ux/lib/Button';
8
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
9
+ import { TextField, ListItem, ListItemText, ListItemAvatar, Avatar } from '@mui/material';
10
+ import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
11
+ import Toast from '@arcblock/ux/lib/Toast';
12
+ import { useSessionContext } from '../../contexts/session';
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { jsxs as _jsxs } from "react/jsx-runtime";
15
+ const DEFAULT_GATEWAY_LIST = [{
16
+ value: 'https://www.didspaces.com/app',
17
+ label: 'Prod DID Spaces',
18
+ avatar: 'P'
19
+ }, {
20
+ value: 'https://storage.staging.abtnet.io/app',
21
+ label: 'Staging DID Spaces',
22
+ avatar: 'S'
23
+ }];
24
+ const filter = createFilterOptions();
25
+ function SpaceSelector({
26
+ onSelect,
27
+ endpoint,
28
+ gatewayUrl: defaultGatewayUrl,
29
+ loading,
30
+ size,
31
+ helperText,
32
+ ...rest
33
+ }) {
34
+ const [gatewayList, setGatewayList] = useLocalStorage('did-space-gateway-list', DEFAULT_GATEWAY_LIST);
35
+ const [gatewayUrl, setGatewayUrl] = useState(defaultGatewayUrl || DEFAULT_GATEWAY_LIST[0].value);
36
+ const {
37
+ t
38
+ } = useLocaleContext();
39
+ const {
40
+ api
41
+ } = useSessionContext();
42
+ useEffect(() => {
43
+ if (gatewayUrl && !gatewayList.find(x => x.value === gatewayUrl)) {
44
+ api.get(joinUrl(gatewayUrl, '/__blocklet__.js?type=json')).then(res => {
45
+ // FIXME: @wangshijun handle mountPoint
46
+ setGatewayList([...gatewayList, {
47
+ value: gatewayUrl,
48
+ label: res.data.appName
49
+ }]);
50
+ }).catch(err => {
51
+ console.error(err);
52
+ Toast.error('Can not add this gateway, please check the url and try again');
53
+ });
54
+ }
55
+ }, [gatewayUrl]); // eslint-disable-line
56
+
57
+ return /*#__PURE__*/_jsx(Container, {
58
+ ...rest,
59
+ freeSolo: true,
60
+ selectOnFocus: true,
61
+ clearOnBlur: true,
62
+ handleHomeEndKeys: true,
63
+ value: gatewayUrl,
64
+ options: gatewayList,
65
+ onChange: (e, v) => {
66
+ if (!v) {
67
+ return;
68
+ }
69
+ if (typeof v === 'string') {
70
+ const x = gatewayList.find(o => o.label === v);
71
+ if (x) {
72
+ setGatewayUrl(x.value);
73
+ }
74
+ } else if (v.inputValue) {
75
+ // Create a new value from the user input
76
+ setGatewayUrl(v.inputValue);
77
+ } else if (v.value) {
78
+ setGatewayUrl(v.value);
79
+ }
80
+ },
81
+ getOptionLabel: x => {
82
+ // Value selected with enter, right from the input
83
+ if (typeof x === 'string') {
84
+ return x;
85
+ }
86
+
87
+ // Add "xxx" x created dynamically
88
+ if (x.inputValue) {
89
+ return x.inputValue;
90
+ }
91
+ return x.label;
92
+ },
93
+ renderOption: (props, x) => {
94
+ return /*#__PURE__*/_jsxs(ListItem, {
95
+ ...props,
96
+ children: [/*#__PURE__*/_jsx(ListItemAvatar, {
97
+ children: /*#__PURE__*/_jsx(Avatar, {
98
+ children: x.avatar
99
+ })
100
+ }), /*#__PURE__*/_jsx(ListItemText, {
101
+ primary: x.label,
102
+ secondary: x.value
103
+ })]
104
+ }, x.value);
105
+ },
106
+ filterOptions: (options, params) => {
107
+ const filtered = filter(options, params);
108
+
109
+ // Suggest the creation of a new value if its a valid url
110
+ if (params.inputValue && isUrl(params.inputValue)) {
111
+ const isExisting = options.some(x => params.inputValue === x.value);
112
+ if (!isExisting) {
113
+ filtered.push({
114
+ value: params.inputValue,
115
+ label: 'Add new gateway'
116
+ });
117
+ }
118
+ }
119
+ return filtered;
120
+ },
121
+ renderInput: params => {
122
+ return /*#__PURE__*/_jsx(TextField, {
123
+ ...params,
124
+ helperText: helperText,
125
+ label: t('storage.spaces.label'),
126
+ size: size,
127
+ InputProps: {
128
+ ...params.InputProps,
129
+ type: 'search',
130
+ endAdornment: /*#__PURE__*/_jsx(Button, {
131
+ variant: "contained",
132
+ onClick: () => onSelect(gatewayUrl),
133
+ size: "small",
134
+ loading: loading,
135
+ disable: loading,
136
+ sx: {
137
+ position: 'absolute',
138
+ right: 0,
139
+ display: 'flex',
140
+ justifyContent: 'center',
141
+ alignItems: 'center',
142
+ width: '100px',
143
+ height: '100%'
144
+ },
145
+ children: endpoint ? t('storage.spaces.reconnect') : t('storage.spaces.connect.now')
146
+ })
147
+ }
148
+ });
149
+ }
150
+ });
151
+ }
152
+ const Container = styled(Autocomplete)`
153
+ height: 40px;
154
+ width: 100%;
155
+ max-width: 720px;
156
+ ${props => props.theme.breakpoints.down('md')} {
157
+ width: 75%;
158
+ }
159
+ input.MuiInputBase-input {
160
+ max-width: calc(100% - 80px);
161
+ }
162
+ `;
163
+ SpaceSelector.propTypes = {
164
+ onSelect: PropTypes.func.isRequired,
165
+ endpoint: PropTypes.string,
166
+ loading: PropTypes.bool,
167
+ size: PropTypes.string,
168
+ helperText: PropTypes.string,
169
+ gatewayUrl: PropTypes.string
170
+ };
171
+ SpaceSelector.defaultProps = {
172
+ endpoint: undefined,
173
+ loading: false,
174
+ size: 'small',
175
+ helperText: '',
176
+ gatewayUrl: ''
177
+ };
178
+ export default SpaceSelector;
@@ -0,0 +1,101 @@
1
+ import { useState, useContext } from 'react';
2
+ import styled from '@emotion/styled';
3
+ import PropTypes from 'prop-types';
4
+ import Toast from '@arcblock/ux/lib/Toast';
5
+ import StartIcon from '@mui/icons-material/PlayArrow';
6
+ import StopIcon from '@mui/icons-material/Stop';
7
+ import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
8
+ import IconButton from '@mui/material/IconButton';
9
+ import Tooltip from '@mui/material/Tooltip';
10
+ import Confirm from '../../confirm';
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ export default function StartComponent({
13
+ component,
14
+ onStart,
15
+ onStop,
16
+ disabled,
17
+ tip
18
+ }) {
19
+ const {
20
+ t
21
+ } = useContext(LocaleContext);
22
+ const [loading, setLoading] = useState(false);
23
+ const [confirmSetting, setConfirmSetting] = useState();
24
+ const startComponent = async () => {
25
+ setLoading(true);
26
+ try {
27
+ await onStart(component);
28
+ } catch (error) {
29
+ Toast.error(error.message);
30
+ }
31
+ setLoading(false);
32
+ };
33
+ const stopComponent = async () => {
34
+ setLoading(true);
35
+ try {
36
+ await onStop(component);
37
+ } catch (error) {
38
+ Toast.error(error.message);
39
+ }
40
+ setLoading(false);
41
+ };
42
+ const componentDisabled = disabled || loading;
43
+ const isStop = ['starting', 'running'].includes(component.status);
44
+ const Icon = isStop ? StopIcon : StartIcon;
45
+ const btn = /*#__PURE__*/_jsx(StyledButton, {
46
+ disabled: componentDisabled,
47
+ onClick: () => {
48
+ if (isStop) {
49
+ setConfirmSetting({
50
+ title: `${t('common.stop')} ${component?.meta?.title}`,
51
+ description: t('blocklet.action.stopComponentDescription'),
52
+ confirm: t('blocklet.action.confirmStop'),
53
+ cancel: t('common.cancel'),
54
+ onConfirm: () => {
55
+ setConfirmSetting(null);
56
+ return stopComponent();
57
+ },
58
+ onCancel: () => setConfirmSetting(null)
59
+ });
60
+ } else {
61
+ startComponent();
62
+ }
63
+ },
64
+ "data-cy": `${isStop ? 'stop' : 'start'}-component-btn`,
65
+ children: /*#__PURE__*/_jsx(Icon, {
66
+ disabled: componentDisabled
67
+ })
68
+ });
69
+ return [/*#__PURE__*/_jsx(Tooltip, {
70
+ title: tip || t(`common.${isStop ? 'stop' : 'start'}`),
71
+ children: /*#__PURE__*/_jsx("span", {
72
+ children: btn
73
+ })
74
+ }, "btn"), confirmSetting && /*#__PURE__*/_jsx(Confirm, {
75
+ title: confirmSetting.title,
76
+ description: confirmSetting.description,
77
+ confirm: confirmSetting.confirm,
78
+ cancel: confirmSetting.cancel,
79
+ params: confirmSetting.params,
80
+ onConfirm: confirmSetting.onConfirm,
81
+ onCancel: confirmSetting.onCancel
82
+ }, "connect")];
83
+ }
84
+ StartComponent.propTypes = {
85
+ component: PropTypes.object.isRequired,
86
+ onStart: PropTypes.func,
87
+ onStop: PropTypes.func,
88
+ disabled: PropTypes.bool,
89
+ tip: PropTypes.string
90
+ };
91
+ StartComponent.defaultProps = {
92
+ onStart: async () => {},
93
+ onStop: async () => {},
94
+ disabled: false,
95
+ tip: ''
96
+ };
97
+ const StyledButton = styled(IconButton)`
98
+ &.Mui-disabled {
99
+ opacity: 0.5;
100
+ }
101
+ `;
@@ -0,0 +1,200 @@
1
+ /* eslint-disable react/no-unstable-nested-components */
2
+ /* eslint-disable react/jsx-wrap-multilines */
3
+ import { useEffect, useState } from 'react';
4
+ import styled from '@emotion/styled';
5
+ import PropTypes from 'prop-types';
6
+ import joinUrl from 'url-join';
7
+ import Link from '@mui/material/Link';
8
+ import { ErrorFallback } from '@arcblock/ux/lib/ErrorBoundary';
9
+ import { ErrorBoundary } from 'react-error-boundary';
10
+ import InnerList from '@blocklet/list';
11
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
12
+ import Blocklet, { ActionButton } from '@arcblock/ux/lib/Blocklet';
13
+ import Spinner from '@mui/material/CircularProgress';
14
+ import Button from '@arcblock/ux/lib/Button';
15
+ import { isFreeBlocklet } from '@blocklet/meta/lib/util';
16
+ import Toast from '@arcblock/ux/lib/Toast';
17
+ import { formatRegistryLogoPath } from '../../util';
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ import { Fragment as _Fragment } from "react/jsx-runtime";
20
+ import { jsxs as _jsxs } from "react/jsx-runtime";
21
+ const getStoreDetail = (meta, endpoint) => {
22
+ return joinUrl(endpoint, `/blocklets/${meta.did}`);
23
+ };
24
+ const displayAttributes = ({
25
+ blocklet,
26
+ attribute,
27
+ value
28
+ }) => {
29
+ if (blocklet._formatted) {
30
+ return blocklet._formatted[attribute];
31
+ }
32
+ return value;
33
+ };
34
+ const requirePurchase = meta => meta.inStore && isFreeBlocklet(meta) === false;
35
+ function BlockletItem({
36
+ blocklet,
37
+ blocklets,
38
+ handleButtonClick,
39
+ endpoint
40
+ }) {
41
+ const {
42
+ t
43
+ } = useLocaleContext();
44
+ const logoUrl = joinUrl(endpoint, formatRegistryLogoPath(blocklet.did, blocklet.logo || ''));
45
+ const [loading, setLoading] = useState(false);
46
+ const onClickLink = e => {
47
+ if (!e.currentTarget.contains(e.target)) {
48
+ e.preventDefault();
49
+ return false;
50
+ }
51
+ return true;
52
+ };
53
+ const btnTxt = requirePurchase(blocklet) ? t('common.purchase') : t('blocklet.component.choose');
54
+ const onAction = async e => {
55
+ e.preventDefault();
56
+ e.stopPropagation();
57
+ try {
58
+ setLoading(true);
59
+ await handleButtonClick({
60
+ meta: blocklet,
61
+ registryUrl: endpoint,
62
+ blocklets
63
+ });
64
+ } catch (err) {
65
+ Toast.error(err.message);
66
+ } finally {
67
+ setLoading(false);
68
+ }
69
+ };
70
+ return /*#__PURE__*/_jsx(Link, {
71
+ href: getStoreDetail(blocklet, endpoint),
72
+ style: {
73
+ color: 'initial',
74
+ textDecoration: 'none'
75
+ },
76
+ onClick: onClickLink,
77
+ target: "_blank",
78
+ children: /*#__PURE__*/_jsx(StyledBlocklet, {
79
+ title: displayAttributes({
80
+ blocklet,
81
+ attribute: 'title',
82
+ value: blocklet.title || blocklet.name
83
+ }),
84
+ did: blocklet.did,
85
+ description: displayAttributes({
86
+ blocklet,
87
+ attribute: 'description',
88
+ value: blocklet.description
89
+ }),
90
+ cover: blocklet.logo ? logoUrl : '',
91
+ version: blocklet.version,
92
+ button: /*#__PURE__*/_jsx("div", {
93
+ style: {
94
+ display: 'flex',
95
+ alignItems: 'center'
96
+ },
97
+ children: /*#__PURE__*/_jsx(ActionButton, {
98
+ children: /*#__PURE__*/_jsx(Button, {
99
+ onClick: onAction,
100
+ size: "small",
101
+ disabled: loading,
102
+ variant: "outlined",
103
+ color: "primary",
104
+ "data-cy": "install-blocklet",
105
+ children: loading ? /*#__PURE__*/_jsxs(_Fragment, {
106
+ children: [/*#__PURE__*/_jsx(Spinner, {
107
+ size: 16,
108
+ style: {
109
+ marginRight: 3
110
+ }
111
+ }), btnTxt]
112
+ }) : btnTxt
113
+ }, blocklet.did)
114
+ })
115
+ })
116
+ })
117
+ });
118
+ }
119
+ BlockletItem.propTypes = {
120
+ blocklet: PropTypes.object.isRequired,
121
+ blocklets: PropTypes.array,
122
+ handleButtonClick: PropTypes.func,
123
+ endpoint: PropTypes.string
124
+ };
125
+ BlockletItem.defaultProps = {
126
+ handleButtonClick: null,
127
+ endpoint: '',
128
+ blocklets: []
129
+ };
130
+ export default function BlockletList({
131
+ handleButtonClick,
132
+ handleSearchSelect,
133
+ storeUrl,
134
+ handleBlockletRender,
135
+ extraFilter,
136
+ serverVersion,
137
+ ...rest
138
+ }) {
139
+ const {
140
+ locale
141
+ } = useLocaleContext();
142
+ const [filters, setFilters] = useState({});
143
+ const handleChange = changeData => {
144
+ setFilters(changeData);
145
+ };
146
+ const endpoint = storeUrl;
147
+ useEffect(() => {
148
+ setFilters({});
149
+ }, [endpoint]);
150
+ return /*#__PURE__*/_jsx(ErrorBoundary, {
151
+ FallbackComponent: ErrorFallback,
152
+ resetKeys: [endpoint],
153
+ children: /*#__PURE__*/_jsx("div", {
154
+ ...rest,
155
+ children: /*#__PURE__*/_jsx(InnerList, {
156
+ blockletRender: blockletRenderProps => {
157
+ const defaultProps = {
158
+ ...blockletRenderProps,
159
+ handleButtonClick,
160
+ endpoint
161
+ };
162
+ return handleBlockletRender({
163
+ ...blockletRenderProps,
164
+ defaultRender: /*#__PURE__*/_jsx(BlockletItem, {
165
+ ...defaultProps
166
+ })
167
+ });
168
+ },
169
+ baseSearch: true,
170
+ endpoint: endpoint,
171
+ locale: locale,
172
+ onFilterChange: handleChange,
173
+ onSearchSelect: handleSearchSelect,
174
+ filters: filters,
175
+ extraFilter: extraFilter,
176
+ serverVersion: serverVersion
177
+ })
178
+ })
179
+ });
180
+ }
181
+ BlockletList.propTypes = {
182
+ storeUrl: PropTypes.string.isRequired,
183
+ handleButtonClick: PropTypes.func,
184
+ handleSearchSelect: PropTypes.func,
185
+ handleBlockletRender: PropTypes.func,
186
+ extraFilter: PropTypes.func,
187
+ serverVersion: PropTypes.string
188
+ };
189
+ BlockletList.defaultProps = {
190
+ handleButtonClick: null,
191
+ handleSearchSelect: null,
192
+ handleBlockletRender: null,
193
+ extraFilter: undefined,
194
+ serverVersion: ''
195
+ };
196
+ const StyledBlocklet = styled(Blocklet)`
197
+ .ms-highlight {
198
+ color: ${props => props.theme.palette.primary.main};
199
+ }
200
+ `;