@abtnode/ux 1.16.25-next-bc2f4c63 → 1.16.25

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 (61) hide show
  1. package/es/blocklet/actions.js +11 -1
  2. package/es/blocklet/component/add-component-core.js +5 -0
  3. package/es/blocklet/component/component-cell.js +2 -1
  4. package/es/blocklet/icons.js +3 -1
  5. package/es/blocklet/overview.js +13 -7
  6. package/es/blocklet/publish/create-release.js +150 -43
  7. package/es/blocklet/publish/index.js +0 -4
  8. package/es/blocklet/publish/project-list.js +133 -29
  9. package/es/blocklet/publish/release-list.js +18 -4
  10. package/es/blocklet/publish/resource.js +35 -32
  11. package/es/blocklet/router/rule-list.js +2 -1
  12. package/es/locales/ar.js +13 -8
  13. package/es/locales/de.js +13 -8
  14. package/es/locales/en.js +12 -7
  15. package/es/locales/es.js +13 -8
  16. package/es/locales/fr.js +13 -8
  17. package/es/locales/hi.js +13 -8
  18. package/es/locales/i18n.db +0 -0
  19. package/es/locales/id.js +13 -8
  20. package/es/locales/ja.js +13 -8
  21. package/es/locales/ko.js +13 -8
  22. package/es/locales/pt.js +13 -8
  23. package/es/locales/ru.js +13 -8
  24. package/es/locales/th.js +13 -8
  25. package/es/locales/vi.js +13 -8
  26. package/es/locales/zh-tw.js +13 -8
  27. package/es/locales/zh.js +17 -12
  28. package/es/team/members/connections.js +2 -1
  29. package/es/team/members/member.js +2 -1
  30. package/lib/blocklet/actions.js +14 -2
  31. package/lib/blocklet/component/add-component-core.js +1 -1
  32. package/lib/blocklet/component/component-cell.js +2 -1
  33. package/lib/blocklet/icons.js +3 -1
  34. package/lib/blocklet/overview.js +13 -7
  35. package/lib/blocklet/publish/create-release.js +154 -43
  36. package/lib/blocklet/publish/index.js +0 -4
  37. package/lib/blocklet/publish/project-list.js +133 -29
  38. package/lib/blocklet/publish/release-list.js +18 -4
  39. package/lib/blocklet/publish/resource.js +34 -31
  40. package/lib/blocklet/router/rule-list.js +2 -1
  41. package/lib/locales/ar.js +13 -8
  42. package/lib/locales/de.js +13 -8
  43. package/lib/locales/en.js +12 -7
  44. package/lib/locales/es.js +13 -8
  45. package/lib/locales/fr.js +13 -8
  46. package/lib/locales/hi.js +13 -8
  47. package/lib/locales/i18n.db +0 -0
  48. package/lib/locales/id.js +13 -8
  49. package/lib/locales/ja.js +13 -8
  50. package/lib/locales/ko.js +13 -8
  51. package/lib/locales/pt.js +13 -8
  52. package/lib/locales/ru.js +13 -8
  53. package/lib/locales/th.js +13 -8
  54. package/lib/locales/vi.js +13 -8
  55. package/lib/locales/zh-tw.js +13 -8
  56. package/lib/locales/zh.js +17 -12
  57. package/lib/team/members/connections.js +2 -1
  58. package/lib/team/members/member.js +2 -1
  59. package/package.json +16 -16
  60. package/es/blocklet/publish/create-project.js +0 -205
  61. package/lib/blocklet/publish/create-project.js +0 -215
@@ -296,7 +296,17 @@ export default function BlockletActions({
296
296
  } : null;
297
297
  const cancelDownloadAction = {
298
298
  action: 'remove',
299
- icon: Icons.Remove,
299
+ icon: ({
300
+ sx,
301
+ ...restProps
302
+ }) => /*#__PURE__*/_jsx(Icons.Cancel, {
303
+ sx: {
304
+ ...sx,
305
+ paddingRight: '2px',
306
+ zoom: 0.95
307
+ },
308
+ ...restProps
309
+ }),
300
310
  name: t('common.cancel'),
301
311
  handler: createHandler('cancelDownload', node.api.cancelDownloadBlocklet, true)
302
312
  };
@@ -1237,6 +1237,11 @@ const ContentWrapper = styled(Box)`
1237
1237
  }
1238
1238
  return `
1239
1239
  position: relative;
1240
+ .ll-container { // 通过 Launcher Layout 组件约定的 .ll-container class 自定义 Layout 样式
1241
+ width: 100%;
1242
+ height: 100%;
1243
+ }
1244
+
1240
1245
  .root-header {
1241
1246
  z-index: auto !important;
1242
1247
  position: fixed !important;
@@ -196,7 +196,8 @@ export default function ComponentCell({
196
196
  }, {
197
197
  name: t('common.did'),
198
198
  value: /*#__PURE__*/_jsx(DidAddress, {
199
- did: componentInfo.meta.did
199
+ did: componentInfo.meta.did,
200
+ showQrcode: true
200
201
  })
201
202
  }, {
202
203
  name: t('common.author'),
@@ -6,6 +6,7 @@ import Reload from '@mui/icons-material/Autorenew';
6
6
  import Config from '@mui/icons-material/Settings';
7
7
  import Log from '@mui/icons-material/Receipt';
8
8
  import Group from '@mui/icons-material/Group';
9
+ import Cancel from '@mui/icons-material/NotInterested';
9
10
  export default {
10
11
  Start,
11
12
  Stop,
@@ -14,5 +15,6 @@ export default {
14
15
  Remove,
15
16
  Config,
16
17
  Log,
17
- Group
18
+ Group,
19
+ Cancel
18
20
  };
@@ -42,18 +42,21 @@ export default function BlockletOverview() {
42
42
  const infoRows = [appDid ? {
43
43
  name: t('blocklet.appId'),
44
44
  value: /*#__PURE__*/_jsx(DidAddress, {
45
- did: appDid
45
+ did: appDid,
46
+ showQrcode: true
46
47
  })
47
48
  } : null, appPid ? {
48
49
  name: t('blocklet.appPid'),
49
50
  value: /*#__PURE__*/_jsx(DidAddress, {
50
- did: appPid
51
+ did: appPid,
52
+ showQrcode: true
51
53
  })
52
54
  } : null, migratedFrom?.length > 1 ? {
53
55
  name: t('blocklet.alsoKnownAs'),
54
56
  value: /*#__PURE__*/_jsxs("div", {
55
57
  children: [(showAllDIDs ? migratedFrom.slice(1) : migratedFrom.slice(1, 2)).map(x => /*#__PURE__*/_jsx(DidAddress, {
56
- did: x.appDid
58
+ did: x.appDid,
59
+ showQrcode: true
57
60
  })), migratedFrom.length > 2 && /*#__PURE__*/_jsx(Button, {
58
61
  style: {
59
62
  marginLeft: '18px'
@@ -78,7 +81,8 @@ export default function BlockletOverview() {
78
81
  value: /*#__PURE__*/_jsx(DidAddress, {
79
82
  external: true,
80
83
  href: getExplorerLink(blocklet?.controller?.chainHost, blocklet?.controller?.nftId, 'asset'),
81
- did: blocklet?.controller?.nftId
84
+ did: blocklet?.controller?.nftId,
85
+ showQrcode: true
82
86
  })
83
87
  } : null, {
84
88
  name: t('blocklet.installedAt'),
@@ -89,8 +93,9 @@ export default function BlockletOverview() {
89
93
  }, {
90
94
  name: t('common.owner'),
91
95
  value: blocklet.settings?.owner ? /*#__PURE__*/_jsx(DidAddress, {
92
- did: blocklet.settings.owner.did
93
- }) : '--'
96
+ did: blocklet.settings.owner.did,
97
+ showQrcode: true
98
+ }) : '-'
94
99
  }, {
95
100
  name: t('blocklet.config.walletType.name'),
96
101
  value: WalletType[chainType || 'arcblock'] || chainType
@@ -102,7 +107,8 @@ export default function BlockletOverview() {
102
107
  infoRows.push({
103
108
  name: t('common.serverDid'),
104
109
  value: /*#__PURE__*/_jsx(DidAddress, {
105
- did: nodeInfo.did
110
+ did: nodeInfo.did,
111
+ showQrcode: true
106
112
  })
107
113
  }, {
108
114
  name: t('common.serverVersion'),
@@ -1,4 +1,4 @@
1
- import { useState, useEffect, lazy, useRef, useCallback } from 'react';
1
+ import { useState, useEffect, lazy, useRef, useCallback, useMemo } from 'react';
2
2
  import { Link, useNavigate, useParams } from 'react-router-dom';
3
3
  import styled from '@emotion/styled';
4
4
  import useSetState from 'react-use/lib/useSetState';
@@ -15,6 +15,7 @@ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
15
15
  import InputAdornment from '@mui/material/InputAdornment';
16
16
  import Spinner from '@mui/material/CircularProgress';
17
17
  import Dialog from '@mui/material/Dialog';
18
+ import DidConnect from '@arcblock/did-connect/lib/Connect';
18
19
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
19
20
  import Button from '@arcblock/ux/lib/Button';
20
21
  import Toast from '@arcblock/ux/lib/Toast';
@@ -24,6 +25,7 @@ import Alert from '@arcblock/ux/lib/Alert';
24
25
  import { PROJECT } from '@blocklet/constant';
25
26
  import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
26
27
  import BlockletBundleAvatar from '../bundle-avatar';
28
+ import { useSessionContext } from '../../contexts/session';
27
29
  import { useNodeContext } from '../../contexts/node';
28
30
  import { useBlockletContext } from '../../contexts/blocklet';
29
31
  import EmptySpinner from '../../empty-spinner';
@@ -108,8 +110,8 @@ const pickParams = (release, app) => {
108
110
  if (!params.blockletComponents) {
109
111
  params.blockletComponents = (app.children || []).map(x => ({
110
112
  did: x.meta.did,
111
- included: true,
112
- required: true
113
+ included: false,
114
+ required: false
113
115
  }));
114
116
  } else {
115
117
  params.blockletComponents = params.blockletComponents.map(x => ({
@@ -126,11 +128,15 @@ export default function CreateRelease({
126
128
  const {
127
129
  projectId,
128
130
  releaseId: inputReleaseId,
129
- componentDid
131
+ componentDid = ''
130
132
  } = useParams();
131
133
  const {
132
- t
134
+ t,
135
+ locale
133
136
  } = useLocaleContext();
137
+ const {
138
+ api: sessionApi
139
+ } = useSessionContext();
134
140
  const {
135
141
  blocklet
136
142
  } = useBlockletContext();
@@ -144,10 +150,11 @@ export default function CreateRelease({
144
150
  } = useNodeContext();
145
151
  const uploaderLogoRef = useRef(null);
146
152
  const uploaderScreenshotRef = useRef(null);
147
- const [projectType, setProjectType] = useState();
148
153
  const [installResourceTip, setInstallResourceTip] = useState();
154
+ const [openConnect, setOpenConnect] = useState(false);
149
155
  const releaseId = inputReleaseId === 'create' ? '' : inputReleaseId;
150
156
  const mode = inputReleaseId === 'create' ? 'create' : 'edit';
157
+ const projectType = useMemo(() => params?.blockletComponents?.some(x => x.included) ? 'pack' : 'resource', [params?.blockletComponents]);
151
158
  const tabs = [];
152
159
  const resourceComponents = (blocklet?.children || []).filter(x => x.meta.resource?.exportApi).filter(x => !componentDid || x.meta.did === componentDid);
153
160
  resourceComponents.forEach(item => {
@@ -161,9 +168,11 @@ export default function CreateRelease({
161
168
  const [tab, setTab] = useState(tabs[0]?.value);
162
169
  const isPublished = release?.status === 'published';
163
170
  const readOnly = isPublished;
164
- const getProject = ({
165
- typeOnly
166
- } = {}) => {
171
+ const getProject = () => {
172
+ if (!projectId) {
173
+ Toast.error(t('blocklet.publish.errorTip.noDid'));
174
+ return;
175
+ }
167
176
  api.getProject({
168
177
  input: {
169
178
  did: blocklet.meta.did,
@@ -172,17 +181,16 @@ export default function CreateRelease({
172
181
  }).then(res => {
173
182
  setLoading(false);
174
183
  const data = res.project || {};
175
- if (typeOnly) {
176
- setProjectType(data.type);
177
- return;
178
- }
179
184
  if (!data.blockletVersion) {
180
185
  data.blockletVersion = '1.0.0';
181
186
  } else if (semver.valid(data.blockletVersion)) {
182
187
  data.blockletVersion = semver.inc(data.blockletVersion, 'patch');
183
188
  }
184
- setParams(pickParams(data, blocklet));
185
- setProjectType(data.type);
189
+ const theParams = pickParams(data, blocklet);
190
+ if (theParams.blockletTitle === projectId.slice(0, 8)) {
191
+ theParams.blockletTitle = '';
192
+ }
193
+ setParams(theParams);
186
194
  }).catch(err => {
187
195
  setLoading(false);
188
196
  Toast.error(formatError(err));
@@ -211,19 +219,18 @@ export default function CreateRelease({
211
219
  return;
212
220
  }
213
221
  getRelease();
214
- getProject({
215
- typeOnly: true
216
- });
222
+ // getProject({ typeOnly: true });
217
223
  }
218
224
  if (mode === 'create') {
219
225
  getProject();
220
226
  }
221
227
  // eslint-disable-next-line react-hooks/exhaustive-deps
222
228
  }, [mode, releaseId]);
223
- useEffect(() => {
224
- getData();
225
- }, [getData]);
226
229
  const onRelease = status => {
230
+ if (!projectId) {
231
+ Toast.error(t('blocklet.publish.errorTip.noDid'));
232
+ return;
233
+ }
227
234
  const errors = validateParams(params, status, t);
228
235
  if (errors) {
229
236
  Toast.error(errors.map(x => x.message).join('; '));
@@ -248,11 +255,7 @@ export default function CreateRelease({
248
255
  _params.blockletDescription = (_params.blockletDescription || '').trim();
249
256
  _params.blockletIntroduction = (_params.blockletIntroduction || '').trim();
250
257
  _params.note = (_params.note || '').trim();
251
- if (projectType === 'pack') {
252
- _params.blockletComponents = (_params.blockletComponents || []).filter(x => x.included).map(x => pick(x, ['did', 'required'])).map(JSON.stringify);
253
- } else {
254
- delete _params.blockletComponents;
255
- }
258
+ _params.blockletComponents = (_params.blockletComponents || []).filter(x => x.included).map(x => pick(x, ['did', 'required'])).map(JSON.stringify);
256
259
  setCreateLoading(status);
257
260
  setLoading(true);
258
261
  api.createRelease({
@@ -291,12 +294,96 @@ export default function CreateRelease({
291
294
  }
292
295
  });
293
296
  };
297
+ const handleDidConnectShow = e => {
298
+ e.preventDefault();
299
+ e.stopPropagation();
300
+ if (!params.blockletTitle) {
301
+ setParamsErrTip({
302
+ blockletTitle: t('blocklet.publish.errorTip.noTitle')
303
+ });
304
+ Toast.error(t('blocklet.publish.errorTip.noTitle'));
305
+ return;
306
+ }
307
+ if (projectId === '0') {
308
+ setOpenConnect(true);
309
+ }
310
+ };
311
+ const handleDidConnectClose = () => {
312
+ setOpenConnect(false);
313
+ };
314
+ const handleChangeSelectedComponents = data => {
315
+ setParams({
316
+ blockletComponents: data
317
+ });
318
+ };
319
+ const handleCreateBlockletDidError = err => {
320
+ Toast.error(err.message);
321
+ setOpenConnect(false);
322
+ };
323
+ const handleCreate = nextProjectDid => {
324
+ if (!nextProjectDid) {
325
+ Toast.error(t('blocklet.publish.errorTip.noDid'));
326
+ return;
327
+ }
328
+ setLoading(true);
329
+ api.createProject({
330
+ input: {
331
+ did: blocklet.meta.did,
332
+ blockletTitle: params.blockletTitle || nextProjectDid.slice(0, 9),
333
+ blockletDid: nextProjectDid,
334
+ type: params.blockletComponents?.length > 0 ? 'pack' : 'resource',
335
+ componentDid
336
+ }
337
+ }).then(() => {
338
+ setLoading(false);
339
+ navigate(`/.well-known/service/admin/publish/${nextProjectDid}/create`, {
340
+ replace: true
341
+ });
342
+ }).catch(err => {
343
+ setLoading(false);
344
+ Toast.error(err.message);
345
+ });
346
+ };
347
+ const handleCreateBlockletDidSuccess = result => {
348
+ const did = result?.blockletWallet?.address;
349
+ if (!did) {
350
+ Toast.error('Empty Blocklet DID');
351
+ } else {
352
+ handleCreate(did);
353
+ }
354
+ setOpenConnect(false);
355
+ };
356
+ useEffect(() => {
357
+ getData();
358
+ }, [getData]);
294
359
  if (!params && loading) {
295
360
  return /*#__PURE__*/_jsx(EmptySpinner, {});
296
361
  }
297
362
  if (!params) {
298
363
  return null;
299
364
  }
365
+ const connect = openConnect ? /*#__PURE__*/_jsx(DidConnect, {
366
+ open: true,
367
+ popup: true,
368
+ onClose: handleDidConnectClose,
369
+ action: "gen-blocklet-key-pair",
370
+ locale: locale,
371
+ checkFn: sessionApi.get,
372
+ saveConnect: false,
373
+ forceConnected: false,
374
+ checkTimeout: 5 * 60 * 1000,
375
+ onSuccess: handleCreateBlockletDidSuccess,
376
+ onError: handleCreateBlockletDidError,
377
+ extraParams: {
378
+ did: blocklet.meta.did
379
+ },
380
+ messages: {
381
+ title: t('blocklet.publish.connect.title'),
382
+ scan: t('blocklet.publish.connect.scan'),
383
+ confirm: t('blocklet.publish.connect.confirm'),
384
+ success: t('blocklet.publish.connect.success')
385
+ }
386
+ }) : null;
300
387
  const uploadLogoPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/logo/upload`;
301
388
  const uploadScreenshotPrefix = `${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/screenshot/upload`;
302
389
  const logoUrl = params?.blockletLogo ? `${uploadLogoPrefix}/${params.blockletLogo}` : `${WELLKNOWN_SERVICE_PATH_PREFIX}/static/images/logo.png`;
@@ -357,7 +444,7 @@ export default function CreateRelease({
357
444
  marginRight: 8
358
445
  },
359
446
  onClick: () => setInstallResourceTip(blockletMetaUrl),
360
- children: t('common.install')
447
+ children: t('blocklet.publish.copyInstallUrl')
361
448
  }), /*#__PURE__*/_jsx(Dialog, {
362
449
  fullWidth: true,
363
450
  maxWidth: "sm",
@@ -398,7 +485,7 @@ export default function CreateRelease({
398
485
  }
399
486
  return /*#__PURE__*/_jsxs(Main, {
400
487
  ...rest,
401
- children: [/*#__PURE__*/_jsxs(Box, {
488
+ children: [connect, /*#__PURE__*/_jsxs(Box, {
402
489
  className: "sticky-header",
403
490
  children: [/*#__PURE__*/_jsxs(Breadcrumbs, {
404
491
  className: "breadcrumbs",
@@ -452,14 +539,8 @@ export default function CreateRelease({
452
539
  })]
453
540
  })]
454
541
  }), /*#__PURE__*/_jsxs(Box, {
455
- children: [projectType === 'pack' && /*#__PURE__*/_jsx(Alert, {
456
- type: "info",
457
- style: {
458
- width: '100%'
459
- },
460
- children: t('blocklet.publish.packTip')
461
- }), /*#__PURE__*/_jsx(Box, {
462
- pt: 3
542
+ children: [/*#__PURE__*/_jsx(Box, {
543
+ pt: 5
463
544
  }), /*#__PURE__*/_jsxs(Box, {
464
545
  display: "flex",
465
546
  className: "section",
@@ -493,6 +574,30 @@ export default function CreateRelease({
493
574
  },
494
575
  error: !!paramsErrTip.blockletTitle,
495
576
  helperText: paramsErrTip.blockletTitle || ''
577
+ }), /*#__PURE__*/_jsx(TextField, {
578
+ required: true,
579
+ label: "Blocklet DID",
580
+ fullWidth: true,
581
+ readonly: true,
582
+ disabled: projectId !== '0',
583
+ autoComplete: "off",
584
+ variant: "outlined",
585
+ onClick: handleDidConnectShow,
586
+ InputProps: {
587
+ 'data-cy': 'export-blocklet-did',
588
+ endAdornment: projectId === '0' && /*#__PURE__*/_jsx(InputAdornment, {
589
+ position: "end",
590
+ children: /*#__PURE__*/_jsx(Button, {
591
+ onClick: handleDidConnectShow,
592
+ children: t('common.create')
593
+ })
594
+ })
595
+ },
596
+ helperText: "",
597
+ value: projectId === '0' ? '' : projectId,
598
+ sx: {
599
+ mt: 3
600
+ }
496
601
  }), /*#__PURE__*/_jsx(TextField, {
497
602
  label: `Blocklet ${t('common.description')}`,
498
603
  placeholder: `Blocklet ${t('common.description')}`,
@@ -778,7 +883,7 @@ export default function CreateRelease({
778
883
  children: resourceContent
779
884
  })]
780
885
  })]
781
- }), projectType === 'pack' && /*#__PURE__*/_jsxs(Box, {
886
+ }), /*#__PURE__*/_jsxs(Box, {
782
887
  display: "flex",
783
888
  mt: 3,
784
889
  className: "section full-width",
@@ -795,14 +900,16 @@ export default function CreateRelease({
795
900
  children: /*#__PURE__*/_jsx(SelectComponents, {
796
901
  disabled: loading || readOnly,
797
902
  app: blocklet,
798
- value: params.blockletComponents,
799
- onChange: data => {
800
- setParams({
801
- blockletComponents: data
802
- });
803
- }
903
+ value: params.blockletComponents || [],
904
+ onChange: handleChangeSelectedComponents
804
905
  })
805
906
  })]
907
+ }), projectType === 'pack' && /*#__PURE__*/_jsx(Alert, {
908
+ type: "info",
909
+ style: {
910
+ width: '100%'
911
+ },
912
+ children: t('blocklet.publish.packTip')
806
913
  })]
807
914
  })]
808
915
  });
@@ -5,7 +5,6 @@ import styled from '@emotion/styled';
5
5
  import Box from '@mui/material/Box';
6
6
  import { useBlockletContext } from '../../contexts/blocklet';
7
7
  import ProjectList from './project-list';
8
- import CreateProject from './create-project';
9
8
  import ReleasesList from './release-list';
10
9
  import CreateRelease from './create-release';
11
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -45,9 +44,6 @@ export default function BlockletPublish({
45
44
  children: [/*#__PURE__*/_jsx(Route, {
46
45
  path: "/",
47
46
  element: /*#__PURE__*/_jsx(ProjectList, {})
48
- }), /*#__PURE__*/_jsx(Route, {
49
- path: "/create",
50
- element: /*#__PURE__*/_jsx(CreateProject, {})
51
47
  }), /*#__PURE__*/_jsx(Route, {
52
48
  path: "/:projectId",
53
49
  element: /*#__PURE__*/_jsx(ReleasesList, {})
@@ -1,16 +1,23 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
2
  import React, { useState, useEffect } from 'react';
3
- import { Link, useParams } from 'react-router-dom';
3
+ import { Link, useNavigate, useParams } from 'react-router-dom';
4
4
  import styled from '@emotion/styled';
5
+ import joinUrl from 'url-join';
5
6
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
7
  import Box from '@mui/material/Box';
8
+ import AddIcon from '@mui/icons-material/Add';
7
9
  import IconButton from '@mui/material/IconButton';
10
+ import LibraryAddIcon from '@mui/icons-material/LibraryAdd';
8
11
  import DeleteIcon from '@mui/icons-material/Delete';
12
+ import InstallDesktopIcon from '@mui/icons-material/InstallDesktop';
13
+ import DownloadIcon from '@mui/icons-material/Download';
14
+ import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
9
15
  import Datatable from '@arcblock/ux/lib/Datatable';
10
16
  import Button from '@arcblock/ux/lib/Button';
11
17
  import Toast from '@arcblock/ux/lib/Toast';
12
18
  import Tag from '@arcblock/ux/lib/Tag';
13
19
  import RelativeTime from '@arcblock/ux/lib/RelativeTime';
20
+ import { Tooltip } from '@mui/material';
14
21
  import { useBlockletContext } from '../../contexts/blocklet';
15
22
  import { useNodeContext } from '../../contexts/node';
16
23
  import EmptySpinner from '../../empty-spinner';
@@ -18,7 +25,9 @@ import DidAddress from '../../did-address';
18
25
  import Confirm from '../../confirm';
19
26
  import BlockletBundleAvatar from '../bundle-avatar';
20
27
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
+ const serverEndpoint = window.env?.serverEndpoint;
21
29
  export default function ProjectList() {
30
+ const navigate = useNavigate();
22
31
  const {
23
32
  t,
24
33
  locale
@@ -50,6 +59,11 @@ export default function ProjectList() {
50
59
  Toast.error(err.message);
51
60
  });
52
61
  };
62
+ const handleNewBlocklet = () => {
63
+ navigate('/.well-known/service/admin/publish/0/create', {
64
+ replace: true
65
+ });
66
+ };
53
67
  const onDeleteProject = project => {
54
68
  setDeleteConfirm(project);
55
69
  };
@@ -76,7 +90,15 @@ export default function ProjectList() {
76
90
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
77
91
 
78
92
  if (!projects && loading) {
79
- return /*#__PURE__*/_jsx(EmptySpinner, {});
93
+ return /*#__PURE__*/_jsx(Box, {
94
+ sx: {
95
+ display: 'flex',
96
+ justifyContent: 'center',
97
+ alignItems: 'center',
98
+ marginTop: '40px'
99
+ },
100
+ children: /*#__PURE__*/_jsx(EmptySpinner, {})
101
+ });
80
102
  }
81
103
  if (!projects) {
82
104
  return null;
@@ -101,12 +123,10 @@ export default function ProjectList() {
101
123
  mb: 3
102
124
  },
103
125
  children: t('blocklet.publish.createBlockletTip')
104
- }), /*#__PURE__*/_jsx(Link, {
105
- to: "create",
106
- children: /*#__PURE__*/_jsx(Button, {
107
- variant: "contained",
108
- children: t('blocklet.publish.createBlocklet')
109
- })
126
+ }), /*#__PURE__*/_jsx(Button, {
127
+ onClick: handleNewBlocklet,
128
+ variant: "contained",
129
+ children: t('blocklet.publish.createBlocklet')
110
130
  })]
111
131
  });
112
132
  }
@@ -191,34 +211,118 @@ export default function ProjectList() {
191
211
  options: {
192
212
  customBodyRenderLite: rawIndex => {
193
213
  const project = projects[rawIndex];
194
- return /*#__PURE__*/_jsx(Box, {
214
+ let installUrl = '';
215
+ let downloadUrl = '';
216
+ if (project.lastReleaseId) {
217
+ const blockletMetaUrl = joinUrl(serverEndpoint, `/api/project/${blocklet.meta.did}/${project.id}/${project.lastReleaseId}/release/blocklet.json`);
218
+ const url = new URL(serverEndpoint);
219
+ url.pathname = joinUrl(url.pathname, '/launch-blocklet/agreement');
220
+ url.searchParams.set('blocklet_meta_url', blockletMetaUrl);
221
+ installUrl = url.href;
222
+ downloadUrl = joinUrl(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${project.id}/${project.lastReleaseId}/download/${(project.lastReleaseFiles || [])[0]}`);
223
+ }
224
+ return /*#__PURE__*/_jsxs(Box, {
195
225
  display: "flex",
196
- children: /*#__PURE__*/_jsx(IconButton, {
197
- color: "error",
198
- "aria-label": "delete",
199
- onClick: () => onDeleteProject(project),
200
- children: /*#__PURE__*/_jsx(DeleteIcon, {
201
- sx: {
202
- fontSize: 18
203
- }
226
+ children: [/*#__PURE__*/_jsx(Link, {
227
+ to: `${project.id}/create`,
228
+ children: /*#__PURE__*/_jsx(Tooltip, {
229
+ title: t('blocklet.publish.createRelease'),
230
+ placement: "top",
231
+ children: /*#__PURE__*/_jsx(IconButton, {
232
+ color: "primary",
233
+ "aria-label": "create",
234
+ children: /*#__PURE__*/_jsx(LibraryAddIcon, {
235
+ sx: {
236
+ fontSize: 18
237
+ }
238
+ })
239
+ })
240
+ })
241
+ }), !!project.lastReleaseId && project.type === 'pack' && /*#__PURE__*/_jsx(Tooltip, {
242
+ title: t('blocklet.publish.install', {
243
+ name: project.blockletTitle
244
+ }),
245
+ placement: "top",
246
+ children: /*#__PURE__*/_jsx(IconButton, {
247
+ color: "secondary",
248
+ "aria-label": "create",
249
+ children: /*#__PURE__*/_jsx("a", {
250
+ style: {
251
+ display: 'flex'
252
+ },
253
+ href: installUrl,
254
+ target: "_blank",
255
+ rel: "noreferrer",
256
+ children: /*#__PURE__*/_jsx(InstallDesktopIcon, {
257
+ sx: {
258
+ fontSize: 18
259
+ }
260
+ })
261
+ })
262
+ })
263
+ }), !!project.lastReleaseId && /*#__PURE__*/_jsx(Tooltip, {
264
+ title: t('blocklet.publish.download', {
265
+ name: project.blockletTitle
266
+ }),
267
+ placement: "top",
268
+ children: /*#__PURE__*/_jsx(IconButton, {
269
+ color: "primary",
270
+ "aria-label": "create",
271
+ children: /*#__PURE__*/_jsx("a", {
272
+ style: {
273
+ display: 'flex'
274
+ },
275
+ href: downloadUrl,
276
+ children: /*#__PURE__*/_jsx(DownloadIcon, {
277
+ sx: {
278
+ fontSize: 18
279
+ }
280
+ })
281
+ })
282
+ })
283
+ }), /*#__PURE__*/_jsx(Tooltip, {
284
+ title: t('blocklet.publish.delete', {
285
+ name: project.blockletTitle
286
+ }),
287
+ placement: "top",
288
+ children: /*#__PURE__*/_jsx(IconButton, {
289
+ color: "primary",
290
+ "aria-label": "delete",
291
+ onClick: () => onDeleteProject(project),
292
+ children: /*#__PURE__*/_jsx(DeleteIcon, {
293
+ sx: {
294
+ fontSize: 18
295
+ }
296
+ })
204
297
  })
205
- })
298
+ })]
206
299
  });
207
300
  }
208
301
  }
209
302
  }].filter(Boolean);
210
303
  return /*#__PURE__*/_jsxs(Main, {
211
- children: [/*#__PURE__*/_jsx(Box, {
212
- sx: {
213
- textAlign: 'right'
214
- },
215
- children: /*#__PURE__*/_jsx(Link, {
216
- to: "create",
217
- children: /*#__PURE__*/_jsx(Button, {
218
- variant: "contained",
219
- children: t('blocklet.publish.createBlocklet')
220
- })
221
- })
304
+ children: [/*#__PURE__*/_jsxs(Box, {
305
+ display: "flex",
306
+ justifyContent: "space-between",
307
+ alignItems: "center",
308
+ children: [/*#__PURE__*/_jsx(Box, {
309
+ sx: {
310
+ fontSize: '1.2rem',
311
+ fontWeight: 'bold'
312
+ },
313
+ children: t('blocklet.publish.productListTitle')
314
+ }), /*#__PURE__*/_jsxs(Button, {
315
+ onClick: handleNewBlocklet,
316
+ variant: "contained",
317
+ children: [/*#__PURE__*/_jsx(AddIcon, {
318
+ style: {
319
+ fontSize: '1.3em',
320
+ marginRight: 4
321
+ }
322
+ }), t('blocklet.publish.createBlocklet')]
323
+ })]
324
+ }), /*#__PURE__*/_jsx(Box, {
325
+ mt: 3
222
326
  }), /*#__PURE__*/_jsx(Datatable, {
223
327
  className: "main-table",
224
328
  locale: locale,