@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.
- package/lib/blocklet/component/add-component/add-component-core.js +4 -5
- package/lib/blocklet/component/add-component/step-connect.js +8 -0
- package/lib/blocklet/publish/{select-components.js → create-release/blocklets.js} +41 -20
- package/lib/blocklet/publish/create-release/branding.js +390 -0
- package/lib/blocklet/publish/{connect-store-list.js → create-release/connect-store-list.js} +2 -2
- package/lib/blocklet/publish/create-release/header.js +407 -0
- package/lib/blocklet/publish/create-release/index.js +575 -0
- package/lib/blocklet/publish/create-release/introduction-preview.js +28 -0
- package/lib/blocklet/publish/create-release/introduction.js +109 -0
- package/lib/blocklet/publish/create-release/release-stepper.js +161 -0
- package/lib/blocklet/publish/{resource.js → create-release/resources.js} +37 -21
- package/lib/blocklet/publish/create-release/step-icon.js +63 -0
- package/lib/blocklet/publish/{stop-box.js → create-release/stop-box.js} +13 -6
- package/lib/blocklet/publish/{tree.js → create-release/tree.js} +1 -1
- package/lib/blocklet/publish/create-release/version.js +93 -0
- package/lib/blocklet/publish/index.js +1 -1
- package/lib/blocklet/publish/project-list.js +3 -3
- package/lib/blocklet/publish/release-list.js +2 -2
- package/lib/blocklet/publish/utils/validate-params.js +92 -0
- package/lib/blocklet/router/add-domain.js +3 -2
- package/lib/hooks/use-bundle-logo.js +3 -2
- package/lib/layout/addon.js +3 -17
- package/lib/locales/ar.js +16 -2
- package/lib/locales/de.js +16 -2
- package/lib/locales/en.js +13 -0
- package/lib/locales/es.js +16 -2
- package/lib/locales/fr.js +16 -2
- package/lib/locales/hi.js +16 -2
- package/lib/locales/i18n.db +0 -0
- package/lib/locales/id.js +16 -2
- package/lib/locales/ja.js +16 -2
- package/lib/locales/ko.js +16 -2
- package/lib/locales/pt.js +16 -2
- package/lib/locales/ru.js +16 -2
- package/lib/locales/th.js +16 -2
- package/lib/locales/vi.js +16 -2
- package/lib/locales/zh-tw.js +16 -2
- package/lib/locales/zh.js +16 -2
- package/lib/util/index.js +7 -5
- package/package.json +18 -18
- package/lib/blocklet/publish/create-release.js +0 -1207
- /package/lib/blocklet/publish/{connect-store-button.js → create-release/connect-store-button.js} +0 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
import { UNOWNED_DID, WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
|
|
2
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
3
|
+
import { Box, Breadcrumbs, Button, Typography, Dialog as MaterialDialog } from '@mui/material';
|
|
4
|
+
import styled from '@emotion/styled';
|
|
5
|
+
import { Link, useNavigate } from 'react-router-dom';
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import { joinURL } from 'ufo';
|
|
8
|
+
import { PROJECT } from '@blocklet/constant';
|
|
9
|
+
import Spinner from '@mui/material/CircularProgress';
|
|
10
|
+
import CloudUploadRoundedIcon from '@mui/icons-material/CloudUploadRounded';
|
|
11
|
+
import semver from 'semver';
|
|
12
|
+
import { useState } from 'react';
|
|
13
|
+
import Toast from '@arcblock/ux/lib/Toast/index';
|
|
14
|
+
import pAll from 'p-all';
|
|
15
|
+
import Dialog from '@arcblock/ux/lib/Dialog';
|
|
16
|
+
import pick from 'lodash/pick';
|
|
17
|
+
import ConnectStoreList from './connect-store-list';
|
|
18
|
+
import { validateParams } from '../utils/validate-params';
|
|
19
|
+
import { waitGetConnectedStore } from '../utils/wait-connect';
|
|
20
|
+
import uploadImageToProject from '../utils/upload-image-to-project';
|
|
21
|
+
import { uploadResource } from './resources';
|
|
22
|
+
import ClickToCopy from '../../../click-to-copy';
|
|
23
|
+
import { formatError } from '../../../util';
|
|
24
|
+
import { useNodeContext } from '../../../contexts/node';
|
|
25
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
26
|
+
const serverEndpoint = window.env?.serverEndpoint;
|
|
27
|
+
function Header({
|
|
28
|
+
projectId,
|
|
29
|
+
params,
|
|
30
|
+
setParamsErrTip,
|
|
31
|
+
initUrl,
|
|
32
|
+
setParams,
|
|
33
|
+
mode,
|
|
34
|
+
loading,
|
|
35
|
+
blocklet,
|
|
36
|
+
release,
|
|
37
|
+
isPublished,
|
|
38
|
+
releaseId,
|
|
39
|
+
getData,
|
|
40
|
+
getRelease,
|
|
41
|
+
componentDid,
|
|
42
|
+
resourceRelateComponents,
|
|
43
|
+
disabledSelectComponents,
|
|
44
|
+
saveSelectedEventsRef,
|
|
45
|
+
isSelectedResources,
|
|
46
|
+
initLogoUrl,
|
|
47
|
+
setLoading,
|
|
48
|
+
releaseUsedLast,
|
|
49
|
+
setReleaseUsedLast,
|
|
50
|
+
projectType
|
|
51
|
+
}) {
|
|
52
|
+
const {
|
|
53
|
+
t,
|
|
54
|
+
locale
|
|
55
|
+
} = useLocaleContext();
|
|
56
|
+
const {
|
|
57
|
+
api
|
|
58
|
+
} = useNodeContext();
|
|
59
|
+
const navigate = useNavigate();
|
|
60
|
+
const [showStoreDialog, setShowStoreDialog] = useState(false);
|
|
61
|
+
const [installResourceTip, setInstallResourceTip] = useState();
|
|
62
|
+
const onPublish = () => {
|
|
63
|
+
window.parent.postMessage({
|
|
64
|
+
event: 'studioDialog.uploaded',
|
|
65
|
+
componentDid
|
|
66
|
+
}, '*');
|
|
67
|
+
getRelease();
|
|
68
|
+
};
|
|
69
|
+
const onRelease = async status => {
|
|
70
|
+
const errors = validateParams({
|
|
71
|
+
params,
|
|
72
|
+
isSelectedResources,
|
|
73
|
+
projectId,
|
|
74
|
+
status,
|
|
75
|
+
t
|
|
76
|
+
});
|
|
77
|
+
if (errors) {
|
|
78
|
+
Toast.error(errors.map(x => x.message).join('; '));
|
|
79
|
+
setParamsErrTip(errors.reduce((acc, x) => ({
|
|
80
|
+
...acc,
|
|
81
|
+
[x.param]: x.message
|
|
82
|
+
}), {}));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const _params = {
|
|
86
|
+
...params
|
|
87
|
+
};
|
|
88
|
+
const componentMaps = (blocklet?.children || []).reduce((acc, curr) => {
|
|
89
|
+
acc[curr.meta.did] = true;
|
|
90
|
+
return acc;
|
|
91
|
+
}, {});
|
|
92
|
+
Object.keys(resourceRelateComponents).forEach(blockletDid => {
|
|
93
|
+
if (!componentMaps[blockletDid]) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
let included = false;
|
|
97
|
+
if (!disabledSelectComponents) {
|
|
98
|
+
_params.blockletComponents.forEach(item => {
|
|
99
|
+
if (item.did === blockletDid) {
|
|
100
|
+
item.included = true;
|
|
101
|
+
item.required = true;
|
|
102
|
+
included = true;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (!included) {
|
|
107
|
+
_params.blockletComponents.push({
|
|
108
|
+
did: blockletDid,
|
|
109
|
+
included: true,
|
|
110
|
+
required: true
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
_params.blockletVersion = semver.valid(_params.blockletVersion);
|
|
115
|
+
if (!_params.blockletVersion) {
|
|
116
|
+
Toast.error('Invalid Blocklet Version');
|
|
117
|
+
setParamsErrTip({
|
|
118
|
+
blockletVersion: 'Invalid Blocklet Version'
|
|
119
|
+
});
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (initLogoUrl) {
|
|
123
|
+
try {
|
|
124
|
+
const filename = await uploadImageToProject({
|
|
125
|
+
did: blocklet.meta.did,
|
|
126
|
+
projectId,
|
|
127
|
+
imageUrl: initLogoUrl
|
|
128
|
+
});
|
|
129
|
+
_params.blockletLogo = filename;
|
|
130
|
+
setParams({
|
|
131
|
+
blockletLogo: filename
|
|
132
|
+
});
|
|
133
|
+
} catch (err) {
|
|
134
|
+
Toast.error(err.message);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
setLoading(true);
|
|
139
|
+
const saveKeys = Object.keys(saveSelectedEventsRef.current);
|
|
140
|
+
try {
|
|
141
|
+
await pAll(saveKeys.map(x => {
|
|
142
|
+
return () => {
|
|
143
|
+
const item = saveSelectedEventsRef.current[x];
|
|
144
|
+
return uploadResource({
|
|
145
|
+
api,
|
|
146
|
+
locale,
|
|
147
|
+
projectId,
|
|
148
|
+
releaseId: releaseUsedLast ? '' : releaseId,
|
|
149
|
+
appDid: blocklet.meta.did,
|
|
150
|
+
component: item.component,
|
|
151
|
+
resources: item.resources,
|
|
152
|
+
initUrl
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
}), {
|
|
156
|
+
concurrency: 2
|
|
157
|
+
});
|
|
158
|
+
} catch (err) {
|
|
159
|
+
Toast.error(err.message);
|
|
160
|
+
setLoading(false);
|
|
161
|
+
setParamsErrTip({
|
|
162
|
+
resources: 'Invalid save the resource'
|
|
163
|
+
});
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
_params.blockletTitle = (_params.blockletTitle || '').trim();
|
|
167
|
+
_params.blockletDescription = (_params.blockletDescription || '').trim();
|
|
168
|
+
_params.blockletIntroduction = (_params.blockletIntroduction || '').trim();
|
|
169
|
+
_params.note = (_params.note || '').trim();
|
|
170
|
+
_params.blockletComponents = (_params?.blockletComponents || []).filter(x => x.included).map(x => pick(x, ['did', 'required'])).map(JSON.stringify);
|
|
171
|
+
setLoading(true);
|
|
172
|
+
api.createRelease({
|
|
173
|
+
input: {
|
|
174
|
+
..._params,
|
|
175
|
+
did: blocklet.meta.did,
|
|
176
|
+
projectId,
|
|
177
|
+
releaseId: releaseUsedLast ? '' : releaseId,
|
|
178
|
+
status
|
|
179
|
+
}
|
|
180
|
+
}).then(res => {
|
|
181
|
+
if (status === 'draft') {
|
|
182
|
+
Toast.success(t('blocklet.publish.saveDraftSuccess'));
|
|
183
|
+
} else {
|
|
184
|
+
setReleaseUsedLast(false);
|
|
185
|
+
Toast.success(t('blocklet.publish.createReleaseSuccess'));
|
|
186
|
+
window.parent.postMessage({
|
|
187
|
+
event: 'studioDialog.released',
|
|
188
|
+
componentDid
|
|
189
|
+
}, '*');
|
|
190
|
+
}
|
|
191
|
+
if (mode === 'create') {
|
|
192
|
+
const id = res?.release?.id;
|
|
193
|
+
navigate(`../${projectId}/view/${id}`, {
|
|
194
|
+
replace: true
|
|
195
|
+
});
|
|
196
|
+
} else {
|
|
197
|
+
getRelease();
|
|
198
|
+
}
|
|
199
|
+
}).catch(err => {
|
|
200
|
+
const msg = formatError(err);
|
|
201
|
+
Toast.error(msg);
|
|
202
|
+
if (/resource.*empty/.test(msg)) {
|
|
203
|
+
setParamsErrTip({
|
|
204
|
+
blockletResource: msg
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}).finally(() => {
|
|
208
|
+
setLoading(false);
|
|
209
|
+
});
|
|
210
|
+
};
|
|
211
|
+
const onOpenConnectStore = async param => {
|
|
212
|
+
await waitGetConnectedStore(api, param);
|
|
213
|
+
getData();
|
|
214
|
+
};
|
|
215
|
+
let installButton = null;
|
|
216
|
+
if (isPublished && serverEndpoint) {
|
|
217
|
+
const blockletMetaUrl = joinURL(serverEndpoint, `/api/project/${blocklet.meta.did}/${projectId}/${releaseId}/release/blocklet.json`);
|
|
218
|
+
if (projectType === 'pack') {
|
|
219
|
+
const url = new URL(serverEndpoint);
|
|
220
|
+
url.pathname = joinURL(url.pathname, '/launch-blocklet/agreement');
|
|
221
|
+
url.searchParams.set('blocklet_meta_url', blockletMetaUrl);
|
|
222
|
+
installButton = /*#__PURE__*/_jsx("a", {
|
|
223
|
+
href: url.href,
|
|
224
|
+
target: "_blank",
|
|
225
|
+
rel: "noreferrer",
|
|
226
|
+
children: /*#__PURE__*/_jsx(Button, {
|
|
227
|
+
variant: "outlined",
|
|
228
|
+
style: {
|
|
229
|
+
marginRight: 8
|
|
230
|
+
},
|
|
231
|
+
children: t('common.install')
|
|
232
|
+
})
|
|
233
|
+
});
|
|
234
|
+
} else {
|
|
235
|
+
installButton = /*#__PURE__*/_jsxs(_Fragment, {
|
|
236
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
237
|
+
variant: "outlined",
|
|
238
|
+
style: {
|
|
239
|
+
marginRight: 8
|
|
240
|
+
},
|
|
241
|
+
onClick: () => setInstallResourceTip(blockletMetaUrl),
|
|
242
|
+
children: t('blocklet.publish.copyInstallUrl')
|
|
243
|
+
}), /*#__PURE__*/_jsx(MaterialDialog, {
|
|
244
|
+
fullWidth: true,
|
|
245
|
+
maxWidth: "sm",
|
|
246
|
+
open: installResourceTip,
|
|
247
|
+
onClose: () => setInstallResourceTip(''),
|
|
248
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
249
|
+
sx: {
|
|
250
|
+
py: 5,
|
|
251
|
+
px: 4,
|
|
252
|
+
wordBreak: 'break-all'
|
|
253
|
+
},
|
|
254
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
255
|
+
variant: "h6",
|
|
256
|
+
sx: {
|
|
257
|
+
mb: 2
|
|
258
|
+
},
|
|
259
|
+
children: t('blocklet.publish.installResourceTip')
|
|
260
|
+
}), /*#__PURE__*/_jsx(ClickToCopy, {
|
|
261
|
+
children: installResourceTip
|
|
262
|
+
}), /*#__PURE__*/_jsxs(Typography, {
|
|
263
|
+
sx: {
|
|
264
|
+
mt: 2
|
|
265
|
+
},
|
|
266
|
+
children: [t('blocklet.publish.installResourceTip2'), /*#__PURE__*/_jsx("a", {
|
|
267
|
+
style: {
|
|
268
|
+
marginLeft: 4
|
|
269
|
+
},
|
|
270
|
+
href: "https://www.arcblock.io/docs/blocklet-developer/R3weqCy7WPI8ggudt0C2alWv",
|
|
271
|
+
target: "_blank",
|
|
272
|
+
rel: "noreferrer",
|
|
273
|
+
children: t('blocklet.publish.installResourceHelp')
|
|
274
|
+
})]
|
|
275
|
+
})]
|
|
276
|
+
})
|
|
277
|
+
})]
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
282
|
+
children: [/*#__PURE__*/_jsx(Content, {
|
|
283
|
+
className: "sticky-header",
|
|
284
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
285
|
+
display: "flex",
|
|
286
|
+
alignItems: "center",
|
|
287
|
+
flexDirection: "row",
|
|
288
|
+
children: [/*#__PURE__*/_jsxs(Breadcrumbs, {
|
|
289
|
+
className: "breadcrumbs",
|
|
290
|
+
"aria-label": "breadcrumb",
|
|
291
|
+
children: [/*#__PURE__*/_jsx(Link, {
|
|
292
|
+
to: "../",
|
|
293
|
+
children: t('common.blockletStudio')
|
|
294
|
+
}), projectId === UNOWNED_DID ? /*#__PURE__*/_jsx(Typography, {
|
|
295
|
+
color: "text.primary",
|
|
296
|
+
children: params?.blockletTitle || 'Blocklet'
|
|
297
|
+
}) : /*#__PURE__*/_jsx(Link, {
|
|
298
|
+
to: `../${projectId}`,
|
|
299
|
+
children: params?.blockletTitle
|
|
300
|
+
}), /*#__PURE__*/_jsx(Typography, {
|
|
301
|
+
color: "text.primary",
|
|
302
|
+
children: mode === 'create' ? t('common.create') : params?.blockletVersion || t('common.edit')
|
|
303
|
+
})]
|
|
304
|
+
}), /*#__PURE__*/_jsx(Box, {
|
|
305
|
+
flex: "1"
|
|
306
|
+
}), !isPublished && /*#__PURE__*/_jsxs(Button, {
|
|
307
|
+
variant: "contained",
|
|
308
|
+
disabled: loading,
|
|
309
|
+
style: {
|
|
310
|
+
marginRight: 12
|
|
311
|
+
},
|
|
312
|
+
onClick: () => onRelease(PROJECT.RELEASE_STATUS.published),
|
|
313
|
+
children: [loading && /*#__PURE__*/_jsx(Spinner, {
|
|
314
|
+
size: 14,
|
|
315
|
+
sx: {
|
|
316
|
+
mr: 0.5
|
|
317
|
+
},
|
|
318
|
+
color: "inherit"
|
|
319
|
+
}), t('common.release')]
|
|
320
|
+
}), isPublished && /*#__PURE__*/_jsxs(_Fragment, {
|
|
321
|
+
children: [installButton, /*#__PURE__*/_jsx("a", {
|
|
322
|
+
href: joinURL(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/${releaseId}/download/${(release.files || [])[0]}`),
|
|
323
|
+
children: /*#__PURE__*/_jsx(Button, {
|
|
324
|
+
variant: "outlined",
|
|
325
|
+
style: {
|
|
326
|
+
marginRight: 12
|
|
327
|
+
},
|
|
328
|
+
children: t('common.download')
|
|
329
|
+
})
|
|
330
|
+
}), /*#__PURE__*/_jsxs(Button, {
|
|
331
|
+
variant: "contained",
|
|
332
|
+
onClick: () => setShowStoreDialog(true),
|
|
333
|
+
children: [/*#__PURE__*/_jsx(CloudUploadRoundedIcon, {
|
|
334
|
+
style: {
|
|
335
|
+
fontSize: '1.3em',
|
|
336
|
+
marginRight: 4
|
|
337
|
+
}
|
|
338
|
+
}), t('common.uploadToStore')]
|
|
339
|
+
})]
|
|
340
|
+
})]
|
|
341
|
+
})
|
|
342
|
+
}), /*#__PURE__*/_jsx(Dialog, {
|
|
343
|
+
title: t('common.connectToStore'),
|
|
344
|
+
disableEscapeKeyDown: true,
|
|
345
|
+
disablePortal: false,
|
|
346
|
+
fullWidth: true,
|
|
347
|
+
open: showStoreDialog,
|
|
348
|
+
onClose: () => setShowStoreDialog(false),
|
|
349
|
+
children: /*#__PURE__*/_jsx(ConnectStoreList, {
|
|
350
|
+
projectType: projectType,
|
|
351
|
+
blocklet: blocklet,
|
|
352
|
+
releaseType: params?.blockletComponents?.length > 0 ? 'pack' : 'resource',
|
|
353
|
+
projectId: projectId,
|
|
354
|
+
releaseId: releaseId,
|
|
355
|
+
componentDid: componentDid,
|
|
356
|
+
onPublish: onPublish,
|
|
357
|
+
onOpenConnectStore: onOpenConnectStore,
|
|
358
|
+
onDelete: getData,
|
|
359
|
+
connectedStores: params.connectedStores || [],
|
|
360
|
+
publishedStoreIds: release?.publishedStoreIds
|
|
361
|
+
})
|
|
362
|
+
})]
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
Header.propTypes = {
|
|
366
|
+
projectId: PropTypes.string.isRequired,
|
|
367
|
+
params: PropTypes.object.isRequired,
|
|
368
|
+
mode: PropTypes.string.isRequired,
|
|
369
|
+
loading: PropTypes.bool.isRequired,
|
|
370
|
+
blocklet: PropTypes.object.isRequired,
|
|
371
|
+
release: PropTypes.object.isRequired,
|
|
372
|
+
isPublished: PropTypes.bool.isRequired,
|
|
373
|
+
releaseId: PropTypes.string.isRequired,
|
|
374
|
+
getData: PropTypes.func.isRequired,
|
|
375
|
+
getRelease: PropTypes.func.isRequired,
|
|
376
|
+
componentDid: PropTypes.string.isRequired,
|
|
377
|
+
resourceRelateComponents: PropTypes.object.isRequired,
|
|
378
|
+
disabledSelectComponents: PropTypes.bool.isRequired,
|
|
379
|
+
saveSelectedEventsRef: PropTypes.object.isRequired,
|
|
380
|
+
isSelectedResources: PropTypes.bool.isRequired,
|
|
381
|
+
initLogoUrl: PropTypes.string.isRequired,
|
|
382
|
+
setLoading: PropTypes.func.isRequired,
|
|
383
|
+
releaseUsedLast: PropTypes.bool.isRequired,
|
|
384
|
+
setReleaseUsedLast: PropTypes.func.isRequired,
|
|
385
|
+
projectType: PropTypes.string.isRequired,
|
|
386
|
+
setParamsErrTip: PropTypes.func.isRequired,
|
|
387
|
+
setParams: PropTypes.func.isRequired,
|
|
388
|
+
initUrl: PropTypes.object.isRequired
|
|
389
|
+
};
|
|
390
|
+
const Content = styled.div`
|
|
391
|
+
.sticky-header {
|
|
392
|
+
margin-top: -12px;
|
|
393
|
+
padding: 12px 0;
|
|
394
|
+
position: sticky;
|
|
395
|
+
top: 0;
|
|
396
|
+
z-index: 99;
|
|
397
|
+
display: flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
justify-content: space-between;
|
|
400
|
+
background-color: #fff;
|
|
401
|
+
padding-bottom: 12px;
|
|
402
|
+
border-bottom: ${({
|
|
403
|
+
theme
|
|
404
|
+
}) => `1px solid ${theme.palette.divider}`};
|
|
405
|
+
}
|
|
406
|
+
`;
|
|
407
|
+
export default Header;
|