@abtnode/ux 1.16.27-beta-74c4e335 → 1.16.27-beta-4022dde0

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 (42) hide show
  1. package/lib/blocklet/component/add-component/add-component-core.js +4 -5
  2. package/lib/blocklet/component/add-component/step-connect.js +8 -0
  3. package/lib/blocklet/publish/{select-components.js → create-release/blocklets.js} +41 -20
  4. package/lib/blocklet/publish/create-release/branding.js +390 -0
  5. package/lib/blocklet/publish/{connect-store-list.js → create-release/connect-store-list.js} +2 -2
  6. package/lib/blocklet/publish/create-release/header.js +407 -0
  7. package/lib/blocklet/publish/create-release/index.js +575 -0
  8. package/lib/blocklet/publish/create-release/introduction-preview.js +28 -0
  9. package/lib/blocklet/publish/create-release/introduction.js +109 -0
  10. package/lib/blocklet/publish/create-release/release-stepper.js +161 -0
  11. package/lib/blocklet/publish/{resource.js → create-release/resources.js} +37 -21
  12. package/lib/blocklet/publish/create-release/step-icon.js +63 -0
  13. package/lib/blocklet/publish/{stop-box.js → create-release/stop-box.js} +13 -6
  14. package/lib/blocklet/publish/{tree.js → create-release/tree.js} +1 -1
  15. package/lib/blocklet/publish/create-release/version.js +93 -0
  16. package/lib/blocklet/publish/index.js +1 -1
  17. package/lib/blocklet/publish/project-list.js +3 -3
  18. package/lib/blocklet/publish/release-list.js +2 -2
  19. package/lib/blocklet/publish/utils/validate-params.js +92 -0
  20. package/lib/blocklet/router/add-domain.js +3 -2
  21. package/lib/hooks/use-bundle-logo.js +3 -2
  22. package/lib/layout/addon.js +3 -17
  23. package/lib/locales/ar.js +16 -2
  24. package/lib/locales/de.js +16 -2
  25. package/lib/locales/en.js +13 -0
  26. package/lib/locales/es.js +16 -2
  27. package/lib/locales/fr.js +16 -2
  28. package/lib/locales/hi.js +16 -2
  29. package/lib/locales/i18n.db +0 -0
  30. package/lib/locales/id.js +16 -2
  31. package/lib/locales/ja.js +16 -2
  32. package/lib/locales/ko.js +16 -2
  33. package/lib/locales/pt.js +16 -2
  34. package/lib/locales/ru.js +16 -2
  35. package/lib/locales/th.js +16 -2
  36. package/lib/locales/vi.js +16 -2
  37. package/lib/locales/zh-tw.js +16 -2
  38. package/lib/locales/zh.js +16 -2
  39. package/lib/util/index.js +7 -5
  40. package/package.json +18 -18
  41. package/lib/blocklet/publish/create-release.js +0 -1207
  42. /package/lib/blocklet/publish/{connect-store-button.js → create-release/connect-store-button.js} +0 -0
@@ -1050,12 +1050,11 @@ export default function AddComponentCore({
1050
1050
  return null;
1051
1051
  }
1052
1052
  return /*#__PURE__*/_jsxs(Wrapper, {
1053
- sx: isMobile ? {
1053
+ sx: {
1054
1054
  width: '100%',
1055
- height: window.innerHeight
1056
- } : {
1057
- width: '100%',
1058
- height: inDialog ? '72vh' : '100vh'
1055
+ // FIXME: @zhanghan 在移动端中,会产生一个纵向的滚动条,需要整体修改来实现高度自适应
1056
+ // eslint-disable-next-line no-nested-ternary
1057
+ height: isMobile ? window.innerHeight : inDialog ? '72vh' : '100vh'
1059
1058
  },
1060
1059
  children: [/*#__PURE__*/_jsx(StepProvider, {
1061
1060
  steps: steps,
@@ -53,6 +53,7 @@ const StepContent = /*#__PURE__*/forwardRef(({
53
53
  pcHeight: "100%",
54
54
  logoUrl: meta && meta.logo && meta.registryUrl ? getBlockletLogoUrl({
55
55
  did: meta.did,
56
+ version: meta.version,
56
57
  baseUrl: meta.registryUrl,
57
58
  logoPath: meta.logo
58
59
  }) : null,
@@ -136,6 +137,9 @@ const ContentWrapper = styled(Box)`
136
137
  max-width: 100% !important;
137
138
  }
138
139
  }
140
+ .app-content {
141
+ padding: 0!important;
142
+ }
139
143
  `;
140
144
  }
141
145
  return `
@@ -191,6 +195,10 @@ const ContentWrapper = styled(Box)`
191
195
  `;
192
196
  }}
193
197
 
198
+ & .app-overview {
199
+ margin-left: 0 !important;
200
+ }
201
+
194
202
  & .flex-justify-center {
195
203
  display: flex;
196
204
  justify-content: center;
@@ -7,14 +7,18 @@ import Checkbox from '@mui/material/Checkbox';
7
7
  import Box from '@mui/material/Box';
8
8
  import Datatable from '@arcblock/ux/lib/Datatable';
9
9
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
10
- import BlockletBundleAvatar from '../bundle-avatar';
11
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
- export default function SelectComponents({
10
+ import { Alert } from '@mui/material';
11
+ import { EmptyIcon } from '@arcblock/icons';
12
+ import BlockletBundleAvatar from '../../bundle-avatar';
13
+ import StopBox from './stop-box';
14
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
15
+ export default function Blocklets({
13
16
  value,
14
17
  app,
15
18
  onChange,
16
19
  disabled,
17
20
  resourceRelateComponents,
21
+ projectType,
18
22
  dependentComponentsMode
19
23
  }) {
20
24
  const {
@@ -135,24 +139,40 @@ export default function SelectComponents({
135
139
  }
136
140
  }];
137
141
  return /*#__PURE__*/_jsx(Root, {
138
- children: /*#__PURE__*/_jsx(Datatable, {
139
- className: "main-table",
140
- verticalKeyWidth: 100,
141
- locale: locale,
142
- data: components,
143
- columns: columns,
144
- options: {
145
- sort: false,
146
- download: false,
147
- filter: false,
148
- print: false,
149
- search: false,
150
- rowsPerPage: 100
151
- }
142
+ children: components?.length ? /*#__PURE__*/_jsxs(_Fragment, {
143
+ children: [/*#__PURE__*/_jsx(Datatable, {
144
+ className: "main-table",
145
+ verticalKeyWidth: 100,
146
+ locale: locale,
147
+ data: components,
148
+ columns: columns,
149
+ options: {
150
+ sort: false,
151
+ download: false,
152
+ filter: false,
153
+ print: false,
154
+ search: false,
155
+ rowsPerPage: 50
156
+ }
157
+ }), /*#__PURE__*/_jsx(Alert, {
158
+ type: "info",
159
+ style: {
160
+ width: '100%'
161
+ },
162
+ children: /*#__PURE__*/_jsx(Box, {
163
+ display: "flex",
164
+ alignItems: "center",
165
+ rel: "noreferrer",
166
+ children: projectType === 'pack' ? t('blocklet.publish.packTip') : t('blocklet.publish.resourceTip')
167
+ })
168
+ })]
169
+ }) : /*#__PURE__*/_jsx(StopBox, {
170
+ Icon: EmptyIcon,
171
+ children: t('blocklet.publish.blockletEmptyTip')
152
172
  })
153
173
  });
154
174
  }
155
- SelectComponents.propTypes = {
175
+ Blocklets.propTypes = {
156
176
  app: PropTypes.object.isRequired,
157
177
  value: PropTypes.arrayOf(PropTypes.shape({
158
178
  did: PropTypes.string.isRequired,
@@ -162,9 +182,10 @@ SelectComponents.propTypes = {
162
182
  onChange: PropTypes.func,
163
183
  disabled: PropTypes.bool,
164
184
  dependentComponentsMode: PropTypes.string,
165
- resourceRelateComponents: PropTypes.object
185
+ resourceRelateComponents: PropTypes.object,
186
+ projectType: PropTypes.string.isRequired
166
187
  };
167
- SelectComponents.defaultProps = {
188
+ Blocklets.defaultProps = {
168
189
  value: [],
169
190
  onChange: () => {},
170
191
  disabled: false,
@@ -0,0 +1,390 @@
1
+ import { UNOWNED_DID, WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
2
+ import { Box, InputAdornment, TextField, Typography, Avatar, IconButton } from '@mui/material';
3
+ import PropTypes from 'prop-types';
4
+ import styled from '@emotion/styled';
5
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
+ import Toast from '@arcblock/ux/lib/Toast/index';
7
+ import { useNavigate } from 'react-router-dom';
8
+ import { Suspense, lazy, useRef } from 'react';
9
+ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
10
+ import ConnectStoreButton from './connect-store-button';
11
+ import { createMessageId, waitGetConnectedByStudio } from '../utils/wait-connect';
12
+ import usePromiseWindowOpen from '../../../hooks/use-promise-window-open';
13
+ import { formatError } from '../../../util';
14
+ import { useNodeContext } from '../../../contexts/node';
15
+ import useWantToConnectStore from '../hooks/use-want-to-connect-store';
16
+ import EmptySpinner from '../../../empty-spinner';
17
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
18
+ const allowedFileTypes = ['image/*', '.jpg', '.jpeg', '.png', '.gif', '.svg'];
19
+ const maxFileSize = 1024 * 1024 * 10; // 10 MB
20
+
21
+ // eslint-disable-next-line import/no-unresolved
22
+ const UploaderComponent = /*#__PURE__*/lazy(() => import('@blocklet/uploader/react').then(res => ({
23
+ default: res.Uploader
24
+ })));
25
+ function Branding({
26
+ projectId,
27
+ readOnly,
28
+ loading,
29
+ blocklet,
30
+ params,
31
+ setParams,
32
+ paramsErrTip,
33
+ setParamsErrTip,
34
+ setLoading,
35
+ initUrl,
36
+ initLogoUrl,
37
+ setInitLogoUrl,
38
+ componentDid
39
+ }) {
40
+ const {
41
+ t
42
+ } = useLocaleContext();
43
+ const {
44
+ api
45
+ } = useNodeContext();
46
+ const navigate = useNavigate();
47
+ const uploaderLogoRef = useRef(null);
48
+ const uploaderScreenshotRef = useRef(null);
49
+ const [wantToConnectStore, setWantToConnectStore] = useWantToConnectStore(blocklet);
50
+ const openWindow = usePromiseWindowOpen({
51
+ onOpen: () => setLoading(true),
52
+ onClose: () => setLoading(false)
53
+ });
54
+ const onOpenConnectByStudio = async param => {
55
+ const timer = setTimeout(() => {
56
+ setLoading(false);
57
+ }, 20000);
58
+ const nextBlockletDid = await waitGetConnectedByStudio(api, param);
59
+ setLoading(false);
60
+ clearTimeout(timer);
61
+ window.parent.postMessage({
62
+ event: 'studioDialog.connected',
63
+ componentDid
64
+ }, '*');
65
+ navigate(window.location.pathname.replace(`${UNOWNED_DID}/create`, `${nextBlockletDid}/create`), {
66
+ replace: true
67
+ });
68
+ };
69
+ const handleConnectByStudio = () => {
70
+ if (!params.blockletTitle) {
71
+ Toast.error(t('blocklet.publish.errorTip.noTitle'));
72
+ return;
73
+ }
74
+ if (!wantToConnectStore) {
75
+ Toast.error('No store found');
76
+ return;
77
+ }
78
+ const messageId = createMessageId();
79
+ openWindow(async (newWindow, open) => {
80
+ try {
81
+ const res = await api.connectByStudio({
82
+ input: {
83
+ did: blocklet?.meta?.did,
84
+ blockletTitle: params?.blockletTitle,
85
+ storeUrl: wantToConnectStore.url,
86
+ storeId: wantToConnectStore.id,
87
+ storeName: wantToConnectStore.name,
88
+ type: params?.blockletComponents?.length > 0 ? 'pack' : 'resource',
89
+ componentDid,
90
+ messageId,
91
+ tenantScope: initUrl?.searchParams.get('tenantScope') || ''
92
+ }
93
+ });
94
+ if (!res?.url) {
95
+ Toast.error('failed to connect to store');
96
+ return;
97
+ }
98
+ open(res.url);
99
+ onOpenConnectByStudio({
100
+ did: blocklet?.meta?.did,
101
+ projectId: '',
102
+ messageId
103
+ });
104
+ } catch (err) {
105
+ const error = formatError(err);
106
+ Toast.error(error);
107
+ newWindow.document.write(error);
108
+ setLoading(false);
109
+ }
110
+ });
111
+ };
112
+ const uploadLogoPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/logo/upload`;
113
+ const uploadScreenshotPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/screenshot/upload`;
114
+ const logoUrl = params?.blockletLogo ? `${uploadLogoPrefix}/${params.blockletLogo}` : `${WELLKNOWN_SERVICE_PATH_PREFIX}/static/images/logo.png`;
115
+ const screenshotUrls = (params?.blockletScreenshots || []).filter(Boolean).map(x => `${uploadScreenshotPrefix}/${x}`);
116
+ return /*#__PURE__*/_jsxs(Content, {
117
+ children: [/*#__PURE__*/_jsxs(Box, {
118
+ display: "flex",
119
+ mt: 3,
120
+ className: "section full-width",
121
+ children: [/*#__PURE__*/_jsxs(Box, {
122
+ sx: {
123
+ flex: 1
124
+ },
125
+ children: [/*#__PURE__*/_jsxs(Box, {
126
+ display: "flex",
127
+ children: [/*#__PURE__*/_jsx(Typography, {
128
+ variant: "subtitle1",
129
+ sx: {
130
+ mr: 2
131
+ },
132
+ children: t('common.logo')
133
+ }), /*#__PURE__*/_jsx(Box, {
134
+ sx: {
135
+ flex: 1,
136
+ cursor: readOnly ? 'default' : 'pointer'
137
+ },
138
+ children: /*#__PURE__*/_jsx(Avatar, {
139
+ variant: "square",
140
+ sx: {
141
+ width: 80,
142
+ height: 80
143
+ },
144
+ alt: "Blocklet Logo",
145
+ src: initLogoUrl || logoUrl,
146
+ onClick: () => !readOnly && uploaderLogoRef.current.open()
147
+ })
148
+ })]
149
+ }), /*#__PURE__*/_jsxs(Box, {
150
+ display: "flex",
151
+ mt: 3,
152
+ children: [/*#__PURE__*/_jsx(Typography, {
153
+ variant: "subtitle1",
154
+ sx: {
155
+ mr: 2
156
+ },
157
+ children: t('common.screenshot')
158
+ }), /*#__PURE__*/_jsxs(Box, {
159
+ display: "flex",
160
+ alignItems: "center",
161
+ sx: {
162
+ flex: 1,
163
+ flexWrap: 'wrap'
164
+ },
165
+ children: [screenshotUrls.map((x, index) => /*#__PURE__*/_jsxs(Box, {
166
+ className: "screenshot",
167
+ children: [/*#__PURE__*/_jsx("img", {
168
+ alt: "screenshot",
169
+ src: x
170
+ }), !readOnly && /*#__PURE__*/_jsx(IconButton, {
171
+ className: "action",
172
+ onClick: () => {
173
+ const arr = [...params.blockletScreenshots];
174
+ arr.splice(index, 1);
175
+ setParams({
176
+ blockletScreenshots: arr
177
+ });
178
+ },
179
+ children: /*#__PURE__*/_jsx(DeleteOutlineIcon, {})
180
+ })]
181
+ })), screenshotUrls.length < 5 && /*#__PURE__*/_jsx(Box, {
182
+ sx: {
183
+ width: 200,
184
+ height: 140,
185
+ background: '#eee',
186
+ cursor: readOnly ? 'default' : 'pointer',
187
+ color: '#999',
188
+ mb: 2
189
+ },
190
+ display: "flex",
191
+ justifyContent: "center",
192
+ alignItems: "center",
193
+ fontSize: 40,
194
+ onClick: () => !readOnly && uploaderScreenshotRef.current.open(),
195
+ children: "+"
196
+ })]
197
+ })]
198
+ })]
199
+ }), /*#__PURE__*/_jsx(Suspense, {
200
+ fallback: /*#__PURE__*/_jsx(EmptySpinner, {}),
201
+ children: /*#__PURE__*/_jsx(UploaderComponent, {
202
+ ref: uploaderLogoRef,
203
+ popup: true,
204
+ onUploadFinish: result => {
205
+ setParams({
206
+ blockletLogo: result.data.filename
207
+ });
208
+ setInitLogoUrl('');
209
+ uploaderLogoRef.current.close();
210
+ },
211
+ plugins: ['ImageEditor'],
212
+ installerProps: {
213
+ disabled: true
214
+ },
215
+ apiPathProps: {
216
+ uploader: uploadLogoPrefix,
217
+ disableMediaKitPrefix: true
218
+ },
219
+ coreProps: {
220
+ restrictions: {
221
+ allowedFileTypes,
222
+ maxFileSize,
223
+ maxNumberOfFiles: 1
224
+ }
225
+ }
226
+ }, "uploader-logo")
227
+ }), /*#__PURE__*/_jsx(Suspense, {
228
+ fallback: /*#__PURE__*/_jsx(EmptySpinner, {}),
229
+ children: /*#__PURE__*/_jsx(UploaderComponent, {
230
+ ref: uploaderScreenshotRef,
231
+ popup: true,
232
+ onUploadFinish: result => {
233
+ const blockletScreenshots = params.blockletScreenshots || [];
234
+ blockletScreenshots.push(result.data?.filename);
235
+ setParams({
236
+ blockletScreenshots
237
+ });
238
+ uploaderScreenshotRef.current.close();
239
+ },
240
+ plugins: ['ImageEditor'],
241
+ apiPathProps: {
242
+ uploader: uploadScreenshotPrefix,
243
+ disableMediaKitPrefix: true
244
+ },
245
+ coreProps: {
246
+ restrictions: {
247
+ allowedFileTypes,
248
+ maxFileSize,
249
+ maxNumberOfFiles: 5 - screenshotUrls.length
250
+ }
251
+ }
252
+ }, "uploader-screenshot")
253
+ })]
254
+ }), /*#__PURE__*/_jsx(Box, {
255
+ display: "flex",
256
+ className: "section",
257
+ children: /*#__PURE__*/_jsxs(Box, {
258
+ sx: {
259
+ flex: 1
260
+ },
261
+ children: [/*#__PURE__*/_jsx(TextField, {
262
+ disabled: loading || readOnly,
263
+ label: `Blocklet ${t('common.title')}`,
264
+ placeholder: `Blocklet ${t('common.title')}`,
265
+ InputProps: {
266
+ 'data-cy': 'blocklet-title',
267
+ readOnly
268
+ },
269
+ autoComplete: "off",
270
+ variant: "outlined",
271
+ fullWidth: true,
272
+ required: true,
273
+ value: params.blockletTitle || '',
274
+ onChange: e => {
275
+ setParamsErrTip({
276
+ blockletTitle: ''
277
+ });
278
+ setParams({
279
+ blockletTitle: e.target.value
280
+ });
281
+ },
282
+ error: !!paramsErrTip.blockletTitle,
283
+ helperText: paramsErrTip.blockletTitle || ''
284
+ }), /*#__PURE__*/_jsx(TextField, {
285
+ required: true,
286
+ label: "Blocklet DID",
287
+ fullWidth: true,
288
+ readonly: true,
289
+ disabled: true,
290
+ autoComplete: "off",
291
+ variant: "outlined",
292
+ InputProps: {
293
+ 'data-cy': 'export-blocklet-did',
294
+ endAdornment: projectId === UNOWNED_DID && /*#__PURE__*/_jsx(InputAdornment, {
295
+ position: "end",
296
+ children: /*#__PURE__*/_jsx(ConnectStoreButton, {
297
+ blocklet: blocklet,
298
+ store: wantToConnectStore,
299
+ onChangeStore: setWantToConnectStore,
300
+ disabled: !params.blockletTitle || readOnly || loading,
301
+ loading: loading,
302
+ onClick: handleConnectByStudio
303
+ })
304
+ })
305
+ },
306
+ error: !!paramsErrTip.projectId,
307
+ helperText: paramsErrTip.projectId || '',
308
+ value: projectId === UNOWNED_DID ? '' : projectId,
309
+ sx: {
310
+ mt: 3
311
+ }
312
+ }), /*#__PURE__*/_jsx(TextField, {
313
+ disabled: loading || readOnly,
314
+ label: `Blocklet ${t('common.description')}`,
315
+ placeholder: `Blocklet ${t('common.description')}`,
316
+ InputProps: {
317
+ 'data-cy': 'blocklet-description',
318
+ readOnly
319
+ },
320
+ required: true,
321
+ autoComplete: "off",
322
+ variant: "outlined",
323
+ fullWidth: true,
324
+ value: params.blockletDescription || '',
325
+ onChange: e => {
326
+ setParamsErrTip({
327
+ blockletDescription: ''
328
+ });
329
+ setParams({
330
+ blockletDescription: e.target.value
331
+ });
332
+ },
333
+ error: !!paramsErrTip.blockletDescription,
334
+ helperText: paramsErrTip.blockletDescription || '',
335
+ sx: {
336
+ mt: 3
337
+ }
338
+ })]
339
+ })
340
+ })]
341
+ });
342
+ }
343
+ Branding.propTypes = {
344
+ projectId: PropTypes.string.isRequired,
345
+ readOnly: PropTypes.bool.isRequired,
346
+ params: PropTypes.object.isRequired,
347
+ setParams: PropTypes.func.isRequired,
348
+ paramsErrTip: PropTypes.object.isRequired,
349
+ setParamsErrTip: PropTypes.func.isRequired,
350
+ loading: PropTypes.bool.isRequired,
351
+ blocklet: PropTypes.object.isRequired,
352
+ setLoading: PropTypes.func.isRequired,
353
+ initUrl: PropTypes.object.isRequired,
354
+ componentDid: PropTypes.isRequired,
355
+ initLogoUrl: PropTypes.string.isRequired,
356
+ setInitLogoUrl: PropTypes.func.isRequired
357
+ };
358
+ const Content = styled.div`
359
+ margin-top: 24px;
360
+ .screenshot {
361
+ margin-bottom: 16px;
362
+ max-width: 200px;
363
+ max-height: 140px;
364
+ width: 200px;
365
+ height: 140px;
366
+ overflow: hidden;
367
+ display: flex;
368
+ align-items: center;
369
+ justify-content: center;
370
+ background-color: #eee;
371
+ margin-right: 16px;
372
+ position: relative;
373
+ .action {
374
+ visibility: hidden;
375
+ position: absolute;
376
+ top: 0px;
377
+ right: 0px;
378
+ background-color: rgba(0, 0, 0, 0.2);
379
+ color: rgba(255, 255, 255, 0.8);
380
+ }
381
+ &:hover .action {
382
+ visibility: visible;
383
+ }
384
+ }
385
+ .screenshot img {
386
+ width: 100%; /* 图像宽度填充容器 */
387
+ height: auto; /* 图像高度自适应 */
388
+ }
389
+ `;
390
+ export default Branding;
@@ -6,8 +6,8 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
6
  import LaunchIcon from '@mui/icons-material/Launch';
7
7
  import { blueGrey } from '@mui/material/colors';
8
8
  import { BLOCKLET_TENANT_MODES } from '@blocklet/constant';
9
- import AddStore from '../../store/add';
10
- import StoreItem from '../../store/item';
9
+ import AddStore from '../../../store/add';
10
+ import StoreItem from '../../../store/item';
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
12
  function ConnectStoreList({
13
13
  blocklet,