@abtnode/ux 1.16.26-beta-bdd2d7c0 → 1.16.26-beta-346cba92

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 (57) hide show
  1. package/es/blocklet/actions.js +32 -11
  2. package/es/blocklet/component/add-component-core.js +28 -29
  3. package/es/blocklet/component/select-store.js +9 -10
  4. package/es/blocklet/icons.js +3 -1
  5. package/es/blocklet/publish/connect-store-list.js +8 -4
  6. package/es/blocklet/publish/create-release.js +9 -3
  7. package/es/blocklet/publish/project-list.js +33 -51
  8. package/es/blocklet/publish/release-list.js +67 -24
  9. package/es/locales/ar.js +8 -4
  10. package/es/locales/de.js +8 -4
  11. package/es/locales/en.js +6 -2
  12. package/es/locales/es.js +8 -4
  13. package/es/locales/fr.js +8 -4
  14. package/es/locales/hi.js +8 -4
  15. package/es/locales/i18n.db +0 -0
  16. package/es/locales/id.js +8 -4
  17. package/es/locales/ja.js +8 -4
  18. package/es/locales/ko.js +8 -4
  19. package/es/locales/pt.js +8 -4
  20. package/es/locales/ru.js +8 -4
  21. package/es/locales/th.js +8 -4
  22. package/es/locales/vi.js +8 -4
  23. package/es/locales/zh-tw.js +9 -5
  24. package/es/locales/zh.js +9 -5
  25. package/es/store/connect-actions.js +130 -0
  26. package/es/store/delete.js +8 -2
  27. package/es/store/item.js +5 -9
  28. package/es/util/join-url-keep-search.js +15 -0
  29. package/lib/blocklet/actions.js +36 -13
  30. package/lib/blocklet/component/add-component-core.js +27 -28
  31. package/lib/blocklet/component/select-store.js +9 -10
  32. package/lib/blocklet/icons.js +3 -1
  33. package/lib/blocklet/publish/connect-store-list.js +8 -4
  34. package/lib/blocklet/publish/create-release.js +9 -3
  35. package/lib/blocklet/publish/project-list.js +33 -51
  36. package/lib/blocklet/publish/release-list.js +68 -24
  37. package/lib/locales/ar.js +8 -4
  38. package/lib/locales/de.js +8 -4
  39. package/lib/locales/en.js +6 -2
  40. package/lib/locales/es.js +8 -4
  41. package/lib/locales/fr.js +8 -4
  42. package/lib/locales/hi.js +8 -4
  43. package/lib/locales/i18n.db +0 -0
  44. package/lib/locales/id.js +8 -4
  45. package/lib/locales/ja.js +8 -4
  46. package/lib/locales/ko.js +8 -4
  47. package/lib/locales/pt.js +8 -4
  48. package/lib/locales/ru.js +8 -4
  49. package/lib/locales/th.js +8 -4
  50. package/lib/locales/vi.js +8 -4
  51. package/lib/locales/zh-tw.js +9 -5
  52. package/lib/locales/zh.js +9 -5
  53. package/lib/store/connect-actions.js +138 -0
  54. package/lib/store/delete.js +8 -2
  55. package/lib/store/item.js +5 -9
  56. package/lib/util/join-url-keep-search.js +22 -0
  57. package/package.json +19 -19
@@ -29,6 +29,7 @@ import { getServerUrl } from './util';
29
29
  import { useNodeContext } from '../contexts/node';
30
30
  import Confirm from '../confirm';
31
31
  import Icons from './icons';
32
+ import joinUrlKeepSearch from '../util/join-url-keep-search';
32
33
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
33
34
  export default function BlockletActions({
34
35
  blocklet,
@@ -36,6 +37,7 @@ export default function BlockletActions({
36
37
  onComplete,
37
38
  variant,
38
39
  hasPermission,
40
+ getComponentUrl,
39
41
  useBlockletUrlEvaluation,
40
42
  ...rest
41
43
  }) {
@@ -64,6 +66,14 @@ export default function BlockletActions({
64
66
  const {
65
67
  inService
66
68
  } = node;
69
+ const handleOpenDashboard = () => {
70
+ const mountPoint = `/${blocklet.mountPoint || '/'}`.replace(/\/+/g, '/');
71
+ const href = getComponentUrl?.({
72
+ mountPoint,
73
+ blocklet
74
+ });
75
+ window.open(joinUrlKeepSearch(href, '.well-known/service/admin'));
76
+ };
67
77
  const createHandler = (action, fn, requireUserConfirm = false) => async () => {
68
78
  const onConfirm = async params => {
69
79
  onStart({
@@ -329,17 +339,26 @@ export default function BlockletActions({
329
339
  name: t('common.restart'),
330
340
  handler: createHandler('restart', node.api.restartBlocklet, true),
331
341
  disabled: disableStart || blocklet.status !== 'running'
332
- },
333
- // hidden reload: https://github.com/ArcBlock/blocklet-server/issues/8655
334
- // {
335
- // action: 'reload',
336
- // icon: Icons.Reload,
337
- // name: t('common.reload'),
338
- // handler: createHandler('reload', node.api.reloadBlocklet),
339
- // disabled: disableStart || blocklet.status !== 'running',
340
- // },
341
-
342
- isDownloading(blocklet.status) ? cancelDownloadAction : removeAction, {
342
+ }, isDownloading(blocklet.status) ? cancelDownloadAction : removeAction, {
343
+ separator: true
344
+ }, !inService ? {
345
+ action: 'dashboard',
346
+ icon: ({
347
+ style,
348
+ ...restProps
349
+ }) => /*#__PURE__*/_jsx(Icons.Dashboard, {
350
+ ...restProps,
351
+ style: {
352
+ ...style,
353
+ width: '26px',
354
+ height: '26px',
355
+ paddingRight: '3px'
356
+ }
357
+ }),
358
+ name: t('sidebar.dashboard'),
359
+ handler: handleOpenDashboard,
360
+ disabled: disableStart || blocklet.status !== 'running'
361
+ } : null, {
343
362
  separator: true
344
363
  }, {
345
364
  onlyInMenu: true,
@@ -467,6 +486,7 @@ export default function BlockletActions({
467
486
  });
468
487
  }
469
488
  BlockletActions.propTypes = {
489
+ getComponentUrl: PropTypes.func,
470
490
  blocklet: PropTypes.object.isRequired,
471
491
  onStart: PropTypes.func.isRequired,
472
492
  onComplete: PropTypes.func.isRequired,
@@ -475,6 +495,7 @@ BlockletActions.propTypes = {
475
495
  useBlockletUrlEvaluation: PropTypes.func
476
496
  };
477
497
  BlockletActions.defaultProps = {
498
+ getComponentUrl: null,
478
499
  variant: 'menu',
479
500
  hasPermission: false,
480
501
  useBlockletUrlEvaluation: () => ({
@@ -1,45 +1,45 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
- import { useState, useRef, useImperativeHandle, forwardRef, useEffect } from 'react';
3
2
  import PropTypes from 'prop-types';
3
+ import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
4
4
  import { useParams } from 'react-router-dom';
5
- import uniqBy from 'lodash/uniqBy';
6
- import flatten from 'lodash/flatten';
7
- import isEmpty from 'lodash/isEmpty';
8
- import isNil from 'lodash/isNil';
9
- import PageHeader from '@blocklet/launcher-layout/lib/page-header';
10
- import Spinner from '@mui/material/CircularProgress';
11
- import Typography from '@mui/material/Typography';
12
- import TextField from '@mui/material/TextField';
13
- import AddIcon from '@mui/icons-material/Link';
14
- import CheckIcon from '@mui/icons-material/Check';
15
- import useMediaQuery from '@mui/material/useMediaQuery';
16
- import styled from '@emotion/styled';
5
+ import { isInServerlessMode } from '@abtnode/util/lib/serverless';
6
+ import Alert from '@arcblock/ux/lib/Alert';
7
+ import AnimationWaiter from '@arcblock/ux/lib/AnimationWaiter';
8
+ import Button from '@arcblock/ux/lib/Button';
17
9
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
18
- import { BLOCKLET_CONFIGURABLE_KEY, BlockletStatus, BlockletEvents, BLOCKLET_APP_SPACE_REQUIREMENT } from '@blocklet/constant';
10
+ import { BLOCKLET_APP_SPACE_REQUIREMENT, BLOCKLET_CONFIGURABLE_KEY, BlockletEvents, BlockletStatus } from '@blocklet/constant';
19
11
  import Layout from '@blocklet/launcher-layout';
20
12
  import { StepProvider, useStepContext } from '@blocklet/launcher-layout/lib/context/step';
21
- import Box from '@mui/material/Box';
22
- import { NODE_MODES } from '@abtnode/constant';
23
- import Button from '@arcblock/ux/lib/Button';
24
- import Alert from '@arcblock/ux/lib/Alert';
25
- import AnimationWaiter from '@arcblock/ux/lib/AnimationWaiter';
26
13
  import ResultMessage from '@blocklet/launcher-layout/lib/launch-result-message';
27
- import { getDisplayName, isFreeBlocklet, getSharedConfigObj, hasStartEngine } from '@blocklet/meta/lib/util';
14
+ import PageHeader from '@blocklet/launcher-layout/lib/page-header';
15
+ import styled from '@emotion/styled';
16
+ import CheckIcon from '@mui/icons-material/Check';
17
+ import AddIcon from '@mui/icons-material/Link';
18
+ import Box from '@mui/material/Box';
19
+ import Spinner from '@mui/material/CircularProgress';
20
+ import TextField from '@mui/material/TextField';
21
+ import Typography from '@mui/material/Typography';
22
+ import useMediaQuery from '@mui/material/useMediaQuery';
23
+ import flatten from 'lodash/flatten';
24
+ import isEmpty from 'lodash/isEmpty';
25
+ import isNil from 'lodash/isNil';
26
+ import uniqBy from 'lodash/uniqBy';
28
27
  import urlPathFriendly from '@blocklet/meta/lib/url-path-friendly';
28
+ import { getDisplayName, getSharedConfigObj, hasStartEngine, isFreeBlocklet } from '@blocklet/meta/lib/util';
29
29
  import Toast from '@arcblock/ux/lib/Toast';
30
- import { useNodeContext } from '../../contexts/node';
31
30
  import { useBlockletContext } from '../../contexts/blocklet';
32
- import { getBlockletLogoUrl, getBlockletMetaUrl, isNewStoreUrl, getStoreList, formatError, formatMountPoint } from '../../util';
33
- import SchemaForm from '../../schema-form';
31
+ import { ConfigSpaceProvider } from '../../contexts/config-space';
32
+ import { useNodeContext } from '../../contexts/node';
34
33
  import Required from '../../form/required';
35
- import { ComponentPurchaseSelect } from '../purchase';
36
- import { validatePathPrefix } from '../router/util';
34
+ import SchemaForm from '../../schema-form';
35
+ import { formatError, formatMountPoint, getBlockletLogoUrl, getBlockletMetaUrl, getStoreList, isNewStoreUrl } from '../../util';
37
36
  import Agreement from '../agreement';
38
37
  import InstallFromUrl from '../install-from-url';
38
+ import { ComponentPurchaseSelect } from '../purchase';
39
+ import { validatePathPrefix } from '../router/util';
40
+ import DidSpace from './did-space';
39
41
  import SelectStore from './select-store';
40
42
  import BlockletList from './store-blocklet-list';
41
- import DidSpace from './did-space';
42
- import { ConfigSpaceProvider } from '../../contexts/config-space';
43
43
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
44
44
  const requirePurchase = meta => meta.inStore && isFreeBlocklet(meta) === false;
45
45
  const isRequiredOnSetup = meta => {
@@ -209,7 +209,6 @@ export default function AddComponentCore({
209
209
  const {
210
210
  meta
211
211
  } = component.current;
212
- const isServerlessMode = nodeInfo.mode === NODE_MODES.SERVERLESS;
213
212
  const updateParams = obj => setParams(x => ({
214
213
  ...x,
215
214
  ...obj
@@ -725,7 +724,7 @@ export default function AddComponentCore({
725
724
  }
726
725
  }), /*#__PURE__*/_jsx(SelectStore, {
727
726
  stores: stores,
728
- extra: !isServerlessMode ? /*#__PURE__*/_jsxs(Button, {
727
+ extra: !isInServerlessMode(nodeInfo) ? /*#__PURE__*/_jsxs(Button, {
729
728
  variant: "text",
730
729
  color: "primary",
731
730
  "data-cy": "add-component-from-url",
@@ -1,17 +1,17 @@
1
- import { useState, useRef } from 'react';
2
1
  import PropTypes from 'prop-types';
3
- import styled from '@emotion/styled';
4
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
- import TextField from '@mui/material/TextField';
6
- import MenuItem from '@mui/material/MenuItem';
7
- import { NODE_MODES } from '@abtnode/constant';
2
+ import { useRef, useState } from 'react';
3
+ import { isInServerlessMode } from '@abtnode/util/lib/serverless';
8
4
  import Button from '@arcblock/ux/lib/Button';
5
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
6
+ import styled from '@emotion/styled';
9
7
  import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
8
+ import MenuItem from '@mui/material/MenuItem';
9
+ import TextField from '@mui/material/TextField';
10
10
  import Typography from '@mui/material/Typography';
11
- import useLocalStorage from 'react-use/lib/useLocalStorage';
12
11
  import uniqBy from 'lodash/uniqBy';
13
- import { useNodeContext } from '../../contexts/node';
12
+ import useLocalStorage from 'react-use/lib/useLocalStorage';
14
13
  import { useBlockletContext } from '../../contexts/blocklet';
14
+ import { useNodeContext } from '../../contexts/node';
15
15
  import AddStore from '../../store/add';
16
16
  import StoreItem from '../../store/item';
17
17
  import { getStoreList } from '../../util';
@@ -52,7 +52,6 @@ export default function SelectStore({
52
52
  protected: true
53
53
  })), ...appStoreList], 'url');
54
54
  const currentRegistry = storeUrl && storeList.find(x => storeUrl === x.url) || storeList[0];
55
- const isServerlessMode = nodeInfo.mode === NODE_MODES.SERVERLESS;
56
55
  return /*#__PURE__*/_jsxs(_Fragment, {
57
56
  children: [/*#__PURE__*/_jsxs(SelectStoreTitle, {
58
57
  children: [/*#__PURE__*/_jsx(Button, {
@@ -126,7 +125,7 @@ export default function SelectStore({
126
125
  }
127
126
  })
128
127
  }, x.url);
129
- }), !isServerlessMode && /*#__PURE__*/_jsx(AddStore, {
128
+ }), !isInServerlessMode(nodeInfo) && /*#__PURE__*/_jsx(AddStore, {
130
129
  disabled: loading,
131
130
  storeList: storeList,
132
131
  teamDid: teamDid,
@@ -7,6 +7,7 @@ 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
9
  import Cancel from '@mui/icons-material/NotInterested';
10
+ import Dashboard from '@arcblock/icons/lib/Dashboard';
10
11
  export default {
11
12
  Start,
12
13
  Stop,
@@ -16,5 +17,6 @@ export default {
16
17
  Config,
17
18
  Log,
18
19
  Group,
19
- Cancel
20
+ Cancel,
21
+ Dashboard
20
22
  };
@@ -10,7 +10,8 @@ function ConnectStoreList({
10
10
  projectId,
11
11
  releaseType,
12
12
  publishedStoreIds,
13
- onPublish
13
+ onPublish,
14
+ onDelete
14
15
  }) {
15
16
  const storeList = blocklet?.settings?.storeList || [];
16
17
  const connectedMap = useMemo(() => {
@@ -37,13 +38,14 @@ function ConnectStoreList({
37
38
  store: x,
38
39
  published: publishedStoreIds?.indexOf(x.id) > -1,
39
40
  connected: !!connectedMap[x.url],
40
- onPublish: onPublish
41
+ onPublish: onPublish,
42
+ onDelete: onDelete
41
43
  })
42
44
  })
43
45
  }, x.url)), /*#__PURE__*/_jsx(AddStore, {
44
46
  onAdd: handleAddStore,
45
47
  teamDid: did,
46
- blockletRegistryList: storeList
48
+ storeList: storeList
47
49
  })]
48
50
  });
49
51
  }
@@ -53,10 +55,12 @@ ConnectStoreList.propTypes = {
53
55
  releaseId: PropTypes.string.isRequired,
54
56
  releaseType: PropTypes.string.isRequired,
55
57
  onPublish: PropTypes.func,
58
+ onDelete: PropTypes.func,
56
59
  publishedStoreIds: PropTypes.arrayOf(PropTypes.string)
57
60
  };
58
61
  ConnectStoreList.defaultProps = {
59
62
  publishedStoreIds: [],
60
- onPublish: () => {}
63
+ onPublish: () => {},
64
+ onDelete: () => {}
61
65
  };
62
66
  export default ConnectStoreList;
@@ -12,6 +12,7 @@ import Breadcrumbs from '@mui/material/Breadcrumbs';
12
12
  import Box from '@mui/material/Box';
13
13
  import IconButton from '@mui/material/IconButton';
14
14
  import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
15
+ import CloudUploadRoundedIcon from '@mui/icons-material/CloudUploadRounded';
15
16
  import InputAdornment from '@mui/material/InputAdornment';
16
17
  import Spinner from '@mui/material/CircularProgress';
17
18
  import MaterialDialog from '@mui/material/Dialog';
@@ -502,7 +503,7 @@ export default function CreateRelease({
502
503
  "aria-label": "breadcrumb",
503
504
  children: [/*#__PURE__*/_jsx(Link, {
504
505
  to: "../",
505
- children: t('common.publish')
506
+ children: t('common.blockletStudio')
506
507
  }), /*#__PURE__*/_jsx(Link, {
507
508
  to: `../${projectId}`,
508
509
  children: params?.blockletTitle || 'Blocklet'
@@ -551,10 +552,15 @@ export default function CreateRelease({
551
552
  href: joinUrl(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${projectId}/${releaseId}/download/${(release.files || [])[0]}`),
552
553
  children: t('common.download')
553
554
  })
554
- }), /*#__PURE__*/_jsx(Button, {
555
+ }), /*#__PURE__*/_jsxs(Button, {
555
556
  variant: "contained",
556
557
  onClick: () => setShowStoreDialog(true),
557
- children: t('common.uploadToStore')
558
+ children: [/*#__PURE__*/_jsx(CloudUploadRoundedIcon, {
559
+ style: {
560
+ fontSize: '1.3em',
561
+ marginRight: 4
562
+ }
563
+ }), t('common.uploadToStore')]
558
564
  })]
559
565
  })]
560
566
  })]
@@ -2,16 +2,15 @@
2
2
  import React, { useState, useEffect } from 'react';
3
3
  import { Link, useNavigate, useParams } from 'react-router-dom';
4
4
  import styled from '@emotion/styled';
5
- import joinUrl from 'url-join';
6
5
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
7
6
  import Box from '@mui/material/Box';
8
7
  import AddIcon from '@mui/icons-material/Add';
9
8
  import IconButton from '@mui/material/IconButton';
10
- import LibraryAddIcon from '@mui/icons-material/LibraryAdd';
11
9
  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, UNOWNED_DID } from '@abtnode/constant';
10
+ import VisibilityIcon from '@mui/icons-material/FileOpen';
11
+ import NewFileIcon from '@mui/icons-material/AddBox';
12
+ import HelpOutlineOutlinedIcon from '@mui/icons-material/HelpOutlineOutlined';
13
+ import { UNOWNED_DID } from '@abtnode/constant';
15
14
  import Datatable from '@arcblock/ux/lib/Datatable';
16
15
  import Button from '@arcblock/ux/lib/Button';
17
16
  import Toast from '@arcblock/ux/lib/Toast';
@@ -25,7 +24,6 @@ import DidAddress from '../../did-address';
25
24
  import Confirm from '../../confirm';
26
25
  import BlockletBundleAvatar from '../bundle-avatar';
27
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
28
- const serverEndpoint = window.env?.serverEndpoint;
29
27
  export default function ProjectList() {
30
28
  const navigate = useNavigate();
31
29
  const {
@@ -211,16 +209,6 @@ export default function ProjectList() {
211
209
  options: {
212
210
  customBodyRenderLite: rawIndex => {
213
211
  const project = projects[rawIndex];
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
212
  return /*#__PURE__*/_jsxs(Box, {
225
213
  display: "flex",
226
214
  children: [/*#__PURE__*/_jsx(Link, {
@@ -231,49 +219,27 @@ export default function ProjectList() {
231
219
  children: /*#__PURE__*/_jsx(IconButton, {
232
220
  color: "primary",
233
221
  "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: {
222
+ children: /*#__PURE__*/_jsx(NewFileIcon, {
223
+ style: {
258
224
  fontSize: 18
259
225
  }
260
226
  })
261
227
  })
262
228
  })
263
229
  }), !!project.lastReleaseId && /*#__PURE__*/_jsx(Tooltip, {
264
- title: t('blocklet.publish.download', {
230
+ title: t('blocklet.publish.viewLastRelease', {
265
231
  name: project.blockletTitle
266
232
  }),
267
233
  placement: "top",
268
234
  children: /*#__PURE__*/_jsx(IconButton, {
269
- color: "primary",
235
+ color: "secondary",
270
236
  "aria-label": "create",
271
- children: /*#__PURE__*/_jsx("a", {
237
+ children: /*#__PURE__*/_jsx(Link, {
272
238
  style: {
273
239
  display: 'flex'
274
240
  },
275
- href: downloadUrl,
276
- children: /*#__PURE__*/_jsx(DownloadIcon, {
241
+ to: `${project.id}/${project.lastReleaseId}`,
242
+ children: /*#__PURE__*/_jsx(VisibilityIcon, {
277
243
  sx: {
278
244
  fontSize: 18
279
245
  }
@@ -305,12 +271,28 @@ export default function ProjectList() {
305
271
  display: "flex",
306
272
  justifyContent: "space-between",
307
273
  alignItems: "center",
308
- children: [/*#__PURE__*/_jsx(Box, {
309
- sx: {
310
- fontSize: '1.2rem',
311
- fontWeight: 'bold'
312
- },
313
- children: t('blocklet.publish.productListTitle')
274
+ children: [/*#__PURE__*/_jsxs(Box, {
275
+ display: "flex",
276
+ flexDirection: "row",
277
+ alignItems: "center",
278
+ children: [/*#__PURE__*/_jsx(Box, {
279
+ sx: {
280
+ fontSize: '1.2rem',
281
+ fontWeight: 'bold'
282
+ },
283
+ children: t('blocklet.publish.productListTitle')
284
+ }), /*#__PURE__*/_jsx(Tooltip, {
285
+ title: t('blocklet.publish.createBlockletTip'),
286
+ arrow: true,
287
+ placement: "right",
288
+ children: /*#__PURE__*/_jsx(HelpOutlineOutlinedIcon, {
289
+ sx: {
290
+ opacity: 0.6,
291
+ fontSize: '1.1em',
292
+ ml: 1
293
+ }
294
+ })
295
+ })]
314
296
  }), /*#__PURE__*/_jsxs(Button, {
315
297
  onClick: handleNewBlocklet,
316
298
  variant: "contained",
@@ -8,6 +8,7 @@ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
8
8
  import Box from '@mui/material/Box';
9
9
  import IconButton from '@mui/material/IconButton';
10
10
  import Typography from '@mui/material/Typography';
11
+ import Tooltip from '@mui/material/Tooltip';
11
12
  import Breadcrumbs from '@mui/material/Breadcrumbs';
12
13
  import DownloadIcon from '@mui/icons-material/Download';
13
14
  import DeleteIcon from '@mui/icons-material/Delete';
@@ -19,6 +20,7 @@ import Toast from '@arcblock/ux/lib/Toast';
19
20
  import Tag from '@arcblock/ux/lib/Tag';
20
21
  import RelativeTime from '@arcblock/ux/lib/RelativeTime';
21
22
  import { PROJECT } from '@blocklet/constant';
23
+ import InstallDesktopIcon from '@mui/icons-material/InstallDesktop';
22
24
  import { useBlockletContext } from '../../contexts/blocklet';
23
25
  import { useNodeContext } from '../../contexts/node';
24
26
  import EmptySpinner from '../../empty-spinner';
@@ -42,6 +44,7 @@ export default function ReleaseList() {
42
44
  const [releases, setReleases] = useState(null);
43
45
  const [project, setProject] = useState(null);
44
46
  const [deleteConfirm, setDeleteConfirm] = useState(null);
47
+ const serverEndpoint = window.env?.serverEndpoint;
45
48
  const getReleases = () => {
46
49
  api.getReleases({
47
50
  input: {
@@ -125,7 +128,7 @@ export default function ReleaseList() {
125
128
  "aria-label": "breadcrumb",
126
129
  children: [/*#__PURE__*/_jsx(Link, {
127
130
  to: "..",
128
- children: t('common.publish')
131
+ children: t('common.blockletStudio')
129
132
  }), /*#__PURE__*/_jsx(Typography, {
130
133
  color: "text.primary",
131
134
  children: project.blockletTitle
@@ -218,36 +221,76 @@ export default function ReleaseList() {
218
221
  options: {
219
222
  customBodyRenderLite: rawIndex => {
220
223
  const release = releases[rawIndex];
224
+ let installUrl = '';
225
+ let downloadUrl = '';
226
+ const published = release.status === 'published';
227
+ if (published) {
228
+ const blockletMetaUrl = joinUrl(serverEndpoint, `/api/project/${blocklet.meta.did}/${project.id}/${project.lastReleaseId}/release/blocklet.json`);
229
+ const url = new URL(serverEndpoint);
230
+ url.pathname = joinUrl(url.pathname, '/launch-blocklet/agreement');
231
+ url.searchParams.set('blocklet_meta_url', blockletMetaUrl);
232
+ installUrl = url.href;
233
+ downloadUrl = joinUrl(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${project.id}/${project.lastReleaseId}/download/${(project.lastReleaseFiles || [])[0]}`);
234
+ }
221
235
  return /*#__PURE__*/_jsxs(Box, {
222
236
  display: "flex",
223
237
  alignItems: "center",
224
- children: [/*#__PURE__*/_jsx(IconButton, {
225
- color: "primary",
226
- "aria-label": "download",
227
- disabled: release.status !== 'published',
228
- children: release.status === 'published' ? /*#__PURE__*/_jsx("a", {
229
- style: {
230
- display: 'flex'
231
- },
232
- href: joinUrl(`${WELLKNOWN_SERVICE_PATH_PREFIX}/api/project/${blocklet.meta.did}/${project.id}/${release.id}/download/${(release.files || [])[0]}`),
233
- children: /*#__PURE__*/_jsx(DownloadIcon, {
238
+ children: [published && project.type === 'pack' && /*#__PURE__*/_jsx(Tooltip, {
239
+ title: t('blocklet.publish.install', {
240
+ name: project.blockletTitle
241
+ }),
242
+ placement: "top",
243
+ children: /*#__PURE__*/_jsx(IconButton, {
244
+ color: "secondary",
245
+ "aria-label": "create",
246
+ children: /*#__PURE__*/_jsx("a", {
247
+ style: {
248
+ display: 'flex'
249
+ },
250
+ href: installUrl,
251
+ target: "_blank",
252
+ rel: "noreferrer",
253
+ children: /*#__PURE__*/_jsx(InstallDesktopIcon, {
254
+ sx: {
255
+ fontSize: 18
256
+ }
257
+ })
258
+ })
259
+ })
260
+ }), published && /*#__PURE__*/_jsx(Tooltip, {
261
+ title: t('blocklet.publish.download', {
262
+ name: project.blockletTitle
263
+ }),
264
+ placement: "top",
265
+ children: /*#__PURE__*/_jsx(IconButton, {
266
+ color: "primary",
267
+ "aria-label": "download",
268
+ children: /*#__PURE__*/_jsx("a", {
269
+ style: {
270
+ display: 'flex'
271
+ },
272
+ href: downloadUrl,
273
+ children: /*#__PURE__*/_jsx(DownloadIcon, {
274
+ sx: {
275
+ fontSize: 18
276
+ }
277
+ })
278
+ })
279
+ })
280
+ }), /*#__PURE__*/_jsx(Tooltip, {
281
+ title: t('blocklet.publish.delete', {
282
+ name: project.blockletTitle
283
+ }),
284
+ placement: "top",
285
+ children: /*#__PURE__*/_jsx(IconButton, {
286
+ color: "primary",
287
+ "aria-label": "delete",
288
+ onClick: () => onDeleteRelease(release),
289
+ children: /*#__PURE__*/_jsx(DeleteIcon, {
234
290
  sx: {
235
291
  fontSize: 18
236
292
  }
237
293
  })
238
- }) : /*#__PURE__*/_jsx(DownloadIcon, {
239
- sx: {
240
- fontSize: 18
241
- }
242
- })
243
- }), /*#__PURE__*/_jsx(IconButton, {
244
- color: "primary",
245
- "aria-label": "delete",
246
- onClick: () => onDeleteRelease(release),
247
- children: /*#__PURE__*/_jsx(DeleteIcon, {
248
- sx: {
249
- fontSize: 18
250
- }
251
294
  })
252
295
  })]
253
296
  });
package/es/locales/ar.js CHANGED
@@ -256,7 +256,6 @@ export default {
256
256
  preview: 'معاينة',
257
257
  protected: 'محمي',
258
258
  protocol: 'بروتوكول',
259
- publish: 'نشر',
260
259
  published: 'نشرت',
261
260
  purchase: 'شراء',
262
261
  readMore: 'أكثر',
@@ -353,7 +352,10 @@ export default {
353
352
  connectToStore: 'الاتصال بالمتجر',
354
353
  uploaded: 'تم التحميل',
355
354
  uploadToStore: 'تحميل إلى المتجر',
356
- upload: 'تحميل'
355
+ upload: 'تحميل',
356
+ blockletStudio: 'استوديو بلوكليت',
357
+ visitStore: 'قم بزيارة المتجر',
358
+ reconnect: 'إعادة الاتصال'
357
359
  },
358
360
  blocklet: {
359
361
  external: 'خارجي',
@@ -692,14 +694,16 @@ export default {
692
694
  installResourceHelp: 'وثيقة المساعدة',
693
695
  componentIncluded: 'مدرج',
694
696
  componentForceRequired: 'مجبر مطلوب',
695
- productListTitle: 'نشر بلوكلتس',
697
+ productListTitle: 'استوديو بلوكليت',
696
698
  download: 'تحميل {name}',
697
699
  delete: 'احذف {name}',
698
700
  copyInstallUrl: 'انسخ عنوان URL للتثبيت',
699
701
  install: 'تثبيت {name}',
700
702
  publishToStoreSuccess: 'تم نشر بلوكليت بنجاح في المتجر',
701
703
  connectStoreSuccess: 'تم الاتصال بمتجر البلوكليت بنجاح',
702
- uploadToStoreSuccess: 'تم تحميل بلوكليت بنجاح في المتجر ، تحتاج إلى نشره في المتجر'
704
+ uploadToStoreSuccess: 'تم تحميل بلوكليت بنجاح في المتجر ، تحتاج إلى نشره في المتجر',
705
+ viewLastRelease: 'عرض آخر إصدار',
706
+ reconnectStoreTip: 'بعد إعادة الاتصال، سيتم ربط مطور جديد. هل أنت متأكد أنك تريد إعادة الاتصال؟'
703
707
  },
704
708
  titleValidationError: 'يجب أن يكون طول العنوان على الأقل 3 أحرف',
705
709
  descriptionValidationError: 'يجب أن تكون طول الوصف بين 3 و 160 حرفًا'
package/es/locales/de.js CHANGED
@@ -256,7 +256,6 @@ export default {
256
256
  preview: 'Vorschau',
257
257
  protected: 'Geschützt',
258
258
  protocol: 'Protokoll',
259
- publish: 'Veröffentlichen',
260
259
  published: 'Veröffentlicht',
261
260
  purchase: 'Kauf',
262
261
  readMore: 'Mehr',
@@ -353,7 +352,10 @@ export default {
353
352
  connectToStore: 'Verbinden Sie mit dem Geschäft',
354
353
  uploaded: 'Hochgeladen',
355
354
  uploadToStore: 'Upload in den Shop',
356
- upload: 'Hochladen'
355
+ upload: 'Hochladen',
356
+ blockletStudio: 'Blocklet Studio',
357
+ visitStore: 'Besuche den Laden',
358
+ reconnect: 'Verbinden wiederherstellen'
357
359
  },
358
360
  blocklet: {
359
361
  external: 'Extern',
@@ -692,14 +694,16 @@ export default {
692
694
  installResourceHelp: 'Hilfe-Dokument',
693
695
  componentIncluded: 'Eingeschlossen',
694
696
  componentForceRequired: 'Erzwungen Erforderlich',
695
- productListTitle: 'Veröffentliche Blocklets',
697
+ productListTitle: 'Blocklet Studio',
696
698
  download: 'Download {name}',
697
699
  delete: 'Lösche {name}',
698
700
  copyInstallUrl: 'Kopiere Installations-URL',
699
701
  install: 'Installiere {name}',
700
702
  publishToStoreSuccess: 'Blocklet erfolgreich im Store veröffentlicht',
701
703
  connectStoreSuccess: 'Blocklet Store erfolgreich verbunden',
702
- uploadToStoreSuccess: 'Blocklet erfolgreich im Store hochgeladen, du musst es im Store veröffentlichen'
704
+ uploadToStoreSuccess: 'Blocklet erfolgreich im Store hochgeladen, du musst es im Store veröffentlichen',
705
+ viewLastRelease: 'Letzte Version anzeigen',
706
+ reconnectStoreTip: 'Nach dem erneuten Verbinden wird ein neuer Entwickler zugewiesen. Bist du sicher, dass du dich erneut verbinden möchtest?'
703
707
  },
704
708
  titleValidationError: 'Die Länge des Titels muss mindestens 3 Zeichen betragen',
705
709
  descriptionValidationError: 'Die Beschreibungslänge muss zwischen 3 und 160 Zeichen liegen'