@abtnode/ux 1.16.28-next-5a717317 → 1.16.28

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 (59) hide show
  1. package/lib/actions.js +8 -6
  2. package/lib/analytics/traffic.js +4 -10
  3. package/lib/blocklet/authentication/federated/federated-detail-dialog.js +2 -2
  4. package/lib/blocklet/blocklet-source.js +2 -2
  5. package/lib/blocklet/component/add-component/add-component-core.js +3 -2
  6. package/lib/blocklet/component/component-cell-mount-poin.js +164 -0
  7. package/lib/blocklet/component/component-cell.js +83 -84
  8. package/lib/blocklet/component/configuration.js +52 -36
  9. package/lib/blocklet/component/did-space/connect-to.js +4 -4
  10. package/lib/blocklet/component/index.js +29 -38
  11. package/lib/blocklet/component/navigation/navigation-dialog.js +2 -3
  12. package/lib/blocklet/component/space-connector.js +3 -3
  13. package/lib/blocklet/component/space-selector.js +2 -2
  14. package/lib/blocklet/component/store-blocklet-list.js +3 -3
  15. package/lib/blocklet/logo-uploader.js +2 -2
  16. package/lib/blocklet/notification/push-kit.js +1 -1
  17. package/lib/blocklet/preferences/index.js +3 -3
  18. package/lib/blocklet/publish/create-release/header.js +36 -31
  19. package/lib/blocklet/publish/create-release/index.js +54 -21
  20. package/lib/blocklet/publish/create-release/keep-now-resources.js +15 -0
  21. package/lib/blocklet/publish/create-release/release-stepper.js +4 -4
  22. package/lib/blocklet/publish/create-release/{resources.js → resource-select.js} +8 -7
  23. package/lib/blocklet/publish/create-release/resource-upload.js +105 -0
  24. package/lib/blocklet/publish/project-list.js +6 -0
  25. package/lib/blocklet/publish/release-list.js +4 -4
  26. package/lib/blocklet/publish/utils/validate-params.js +4 -4
  27. package/lib/blocklet/purchase/component-purchase.js +2 -2
  28. package/lib/blocklet/router/action/add-rule.js +31 -18
  29. package/lib/blocklet/router/rule-actions.js +8 -1
  30. package/lib/blocklet/storage/connect-to.js +4 -4
  31. package/lib/blocklet/storage/item.js +3 -3
  32. package/lib/blocklet/util.js +4 -4
  33. package/lib/hooks/url-evaluation.js +2 -2
  34. package/lib/hooks/use-app-logo.js +4 -4
  35. package/lib/hooks/use-bundle-logo.js +4 -4
  36. package/lib/invitation/invitation-receive.js +1 -1
  37. package/lib/locales/ar.js +12 -5
  38. package/lib/locales/de.js +11 -4
  39. package/lib/locales/en.js +11 -4
  40. package/lib/locales/es.js +11 -4
  41. package/lib/locales/fr.js +11 -4
  42. package/lib/locales/hi.js +11 -4
  43. package/lib/locales/i18n.db +0 -0
  44. package/lib/locales/id.js +11 -4
  45. package/lib/locales/ja.js +11 -4
  46. package/lib/locales/ko.js +11 -4
  47. package/lib/locales/pt.js +11 -4
  48. package/lib/locales/ru.js +11 -4
  49. package/lib/locales/th.js +11 -4
  50. package/lib/locales/vi.js +11 -4
  51. package/lib/locales/zh-tw.js +12 -5
  52. package/lib/locales/zh.js +12 -5
  53. package/lib/store/connect-actions.js +2 -2
  54. package/lib/store/item.js +2 -2
  55. package/lib/team/members/util.js +3 -3
  56. package/lib/util/index.js +18 -18
  57. package/lib/util/join-url-keep-search.js +2 -2
  58. package/lib/util/spaces.js +4 -2
  59. package/package.json +19 -20
package/lib/actions.js CHANGED
@@ -1,12 +1,8 @@
1
1
  import { useState, createElement as _createElement } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import styled from '@emotion/styled';
4
- import IconButton from '@mui/material/IconButton';
5
- import Menu from '@mui/material/Menu';
6
- import MenuItem from '@mui/material/MenuItem';
4
+ import { IconButton, Menu, MenuItem, ListItemIcon, ListItemText, Divider } from '@mui/material';
7
5
  import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
8
- import ListItemIcon from '@mui/material/ListItemIcon';
9
- import ListItemText from '@mui/material/ListItemText';
10
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
7
  export default function Actions({
12
8
  actions,
@@ -57,9 +53,14 @@ export default function Actions({
57
53
  close: onClose
58
54
  });
59
55
  }
56
+ if (action.separator) {
57
+ // eslint-disable-next-line react/no-array-index-key
58
+ return /*#__PURE__*/_jsx(Divider, {}, `separator-${index}`);
59
+ }
60
60
  const {
61
61
  icon,
62
62
  text,
63
+ render,
63
64
  onClick,
64
65
  disabled = false,
65
66
  ...opts
@@ -69,7 +70,8 @@ export default function Actions({
69
70
  disabled: disabled,
70
71
  dense: true,
71
72
  onClick: async e => {
72
- await onClick(e);
73
+ e.stopPropagation();
74
+ await onClick?.(e);
73
75
  onClose();
74
76
  }
75
77
  // eslint-disable-next-line react/no-array-index-key
@@ -3,16 +3,10 @@
3
3
  import { useEffect, useState } from 'react';
4
4
  import dayjs from '@abtnode/util/lib/dayjs';
5
5
  import nthArg from 'lodash/nthArg';
6
- import joinUrl from 'url-join';
6
+ import { joinURL } from 'ufo';
7
7
  import useAsyncRetry from 'react-use/lib/useAsyncRetry';
8
8
  import Iframe from 'react-iframe';
9
- import Alert from '@mui/material/Alert';
10
- import Spinner from '@mui/material/CircularProgress';
11
- import Grid from '@mui/material/Grid';
12
- import Typography from '@mui/material/Typography';
13
- import Button from '@mui/material/Button';
14
- import IconButton from '@mui/material/IconButton';
15
- import Popover from '@mui/material/Popover';
9
+ import { Alert, CircularProgress, Grid, Typography, Button, IconButton, Popover } from '@mui/material';
16
10
  import ViewIcon from '@mui/icons-material/LaunchOutlined';
17
11
  import { DateRangePicker } from 'mui-daterange-picker';
18
12
  import { DatePicker } from '@mui/x-date-pickers';
@@ -114,7 +108,7 @@ export default function TrafficInsights({
114
108
  error
115
109
  } = data;
116
110
  if (!list.length && loading) {
117
- return /*#__PURE__*/_jsx(Spinner, {});
111
+ return /*#__PURE__*/_jsx(CircularProgress, {});
118
112
  }
119
113
  if (error) {
120
114
  return /*#__PURE__*/_jsx(Alert, {
@@ -150,7 +144,7 @@ export default function TrafficInsights({
150
144
 
151
145
  // eslint-disable-next-line no-nested-ternary
152
146
  const pathPrefix = inService ? WELLKNOWN_SERVICE_PATH_PREFIX : process.env.NODE_ENV === 'production' ? info.routing.adminPath : '';
153
- const breakdownUrl = joinUrl(window.location.origin, pathPrefix, `/api/analytics/traffic?date=${dayjs(date).format('YYYY-MM-DD')}&did=${did}`);
147
+ const breakdownUrl = joinURL(window.location.origin, pathPrefix, `/api/analytics/traffic?date=${dayjs(date).format('YYYY-MM-DD')}&did=${did}`);
154
148
  const onRangeChange = range => {
155
149
  setDateRange(range);
156
150
  setAnchorEl(null);
@@ -11,7 +11,7 @@ import { Address } from '@arcblock/did-connect';
11
11
  import Dialog from '@arcblock/ux/lib/Dialog';
12
12
  import StarsIcon from '@mui/icons-material/Stars';
13
13
  import isUrl from 'is-url';
14
- import joinUrl from 'url-join';
14
+ import { joinURL } from 'ufo';
15
15
  import { useBlockletContext } from '../../../contexts/blocklet';
16
16
  import { useNodeContext } from '../../../contexts/node';
17
17
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
@@ -95,7 +95,7 @@ const FederatedDetailDialog = /*#__PURE__*/forwardRef((props, ref) => {
95
95
  });
96
96
  }
97
97
  if (['appLogo'].includes(key)) {
98
- const logoUrl = isUrl(value) ? value : joinUrl(state.data.appUrl || '', value || '');
98
+ const logoUrl = isUrl(value) ? value : joinURL(state.data.appUrl || '', value || '');
99
99
  try {
100
100
  const logoUrlInstance = new URL(logoUrl);
101
101
  logoUrlInstance.searchParams.set('imageFilter', 'resize');
@@ -1,6 +1,6 @@
1
1
  import { useContext } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import joinUrl from 'url-join';
3
+ import { joinURL } from 'ufo';
4
4
  import toUpper from 'lodash/toUpper';
5
5
  import Tag from '@arcblock/ux/lib/Tag';
6
6
  import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
@@ -21,7 +21,7 @@ export default function BlockletSource({
21
21
  type: "success",
22
22
  children: toUpper(sourceInfo.source)
23
23
  }, "source"), sourceInfo.source === 'registry' && /*#__PURE__*/_jsx(ExternalLink, {
24
- href: joinUrl(sourceInfo.deployedFrom, 'blocklets', blocklet?.meta?.bundleDid || ''),
24
+ href: joinURL(sourceInfo.deployedFrom, 'blocklets', blocklet?.meta?.bundleDid || ''),
25
25
  target: "_blank",
26
26
  className: "page-link",
27
27
  underline: "hover",
@@ -282,20 +282,21 @@ export default function AddComponentCore({
282
282
  componentDid = ''
283
283
  } = params;
284
284
  // eslint-disable-next-line no-shadow
285
+ const meta = component.current?.meta || {};
285
286
  const {
286
287
  configs = [],
287
288
  registryUrl,
288
289
  inStore,
289
290
  inputUrl,
290
291
  dist
291
- } = component.current?.meta || {};
292
+ } = meta;
292
293
  const downloadTokenList = component.current?.downloadTokenList;
293
294
  const url = inStore ? getBlockletMetaUrl(registryUrl, bundleDid, dist) : inputUrl;
294
295
  setLoading(true);
295
296
  const installInput = {
296
297
  rootDid: blocklet.meta.did,
297
298
  url,
298
- mountPoint: urlPathFriendly(mountPoint),
299
+ mountPoint: mountPoint ? urlPathFriendly(mountPoint) : `/${urlPathFriendly(meta.title || meta.name)}`,
299
300
  title,
300
301
  name: componentName,
301
302
  did: componentDid,
@@ -0,0 +1,164 @@
1
+ import normalizePathPrefix from '@abtnode/util/lib/normalize-path-prefix';
2
+ import { Icon } from '@iconify/react';
3
+ import { Box, CircularProgress, IconButton, TextField } from '@mui/material';
4
+ import PropTypes from 'prop-types';
5
+ import { useEffect, useState } from 'react';
6
+ import urlPathFriendly from '@blocklet/meta/lib/url-path-friendly';
7
+ import Toast from '@arcblock/ux/lib/Toast';
8
+ import { useNodeContext } from '../../contexts/node';
9
+ import { formatError } from '../../util';
10
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ function ComponentCellMountPoint({
12
+ blocklet,
13
+ ancestors,
14
+ mountPoint,
15
+ href
16
+ }) {
17
+ const [hover, setHover] = useState(false);
18
+ const [editing, setEditing] = useState(false);
19
+ const [loading, setLoading] = useState(false);
20
+ const [editValue, setEditValue] = useState(mountPoint);
21
+ const {
22
+ api
23
+ } = useNodeContext();
24
+ const isRoot = !ancestors.length;
25
+ const rootDid = isRoot ? blocklet.meta.did : ancestors.map(x => x.meta.did)[0];
26
+ useEffect(() => {
27
+ setEditing(false);
28
+ setHover(false);
29
+ setLoading(false);
30
+ }, [mountPoint]);
31
+ const handleCancel = () => {
32
+ setHover(false);
33
+ setEditing(false);
34
+ setEditValue(mountPoint);
35
+ };
36
+ const onSubmitMountPoint = async e => {
37
+ e.preventDefault();
38
+ setLoading(true);
39
+ setHover(false);
40
+ try {
41
+ const input = {
42
+ rootDid,
43
+ mountPoint: urlPathFriendly(editValue)
44
+ };
45
+ if (!isRoot) {
46
+ input.did = blocklet.meta.did;
47
+ }
48
+ await api.updateComponentMountPoint({
49
+ input
50
+ });
51
+ } catch (err) {
52
+ setLoading(false);
53
+ err.message = formatError(err);
54
+ Toast.error(err.message);
55
+ throw err;
56
+ }
57
+ };
58
+ const tools = editing ? /*#__PURE__*/_jsxs(Box, {
59
+ sx: {
60
+ ml: 1
61
+ },
62
+ children: [/*#__PURE__*/_jsx(IconButton, {
63
+ size: "medium",
64
+ onMouseEnter: () => setHover(true),
65
+ onMouseLeave: () => setHover(false),
66
+ "data-cy": "edit-mount-point-submit",
67
+ onClick: onSubmitMountPoint,
68
+ children: /*#__PURE__*/_jsx(Box, {
69
+ component: Icon,
70
+ icon: "material-symbols:done",
71
+ sx: {
72
+ color: 'primary.main',
73
+ transition: '0.3s opacity'
74
+ }
75
+ })
76
+ }), /*#__PURE__*/_jsx(IconButton, {
77
+ size: "medium",
78
+ onMouseEnter: () => setHover(true),
79
+ onMouseLeave: () => setHover(false),
80
+ onClick: handleCancel,
81
+ children: /*#__PURE__*/_jsx(Box, {
82
+ component: Icon,
83
+ icon: "iconoir:cancel",
84
+ sx: {
85
+ color: 'primary.main',
86
+ transition: '0.3s opacity'
87
+ }
88
+ })
89
+ })]
90
+ }) : /*#__PURE__*/_jsx(IconButton, {
91
+ size: "medium",
92
+ onMouseEnter: () => setHover(true),
93
+ onMouseLeave: () => setHover(false),
94
+ onClick: () => setEditing(true),
95
+ children: /*#__PURE__*/_jsx(Box, {
96
+ component: Icon,
97
+ "data-cy": "edit-mount-point",
98
+ icon: "lets-icons:edit-light",
99
+ sx: {
100
+ opacity: hover ? 1 : 0,
101
+ color: 'primary.main',
102
+ transition: '0.3s opacity'
103
+ }
104
+ })
105
+ });
106
+ return /*#__PURE__*/_jsxs(Box, {
107
+ sx: {
108
+ display: {
109
+ xs: 'none',
110
+ md: 'flex'
111
+ }
112
+ },
113
+ alignItems: "center",
114
+ flexGrow: "1",
115
+ children: [editing ? /*#__PURE__*/_jsx("form", {
116
+ onSubmit: onSubmitMountPoint,
117
+ children: /*#__PURE__*/_jsx(TextField, {
118
+ style: {
119
+ flex: 1
120
+ },
121
+ fullWidth: true,
122
+ "data-cy": "edit-mount-point-input",
123
+ value: editValue,
124
+ onChange: e => setEditValue(e.target.value),
125
+ autoFocus: true,
126
+ size: "small",
127
+ variant: "outlined",
128
+ placeholder: mountPoint
129
+ })
130
+ }) : /*#__PURE__*/_jsx(Box, {
131
+ component: "a",
132
+ target: "_blank",
133
+ href: href,
134
+ rel: "noopener noreferrer",
135
+ title: href,
136
+ onMouseEnter: () => setHover(true),
137
+ onMouseLeave: () => setHover(false),
138
+ children: /*#__PURE__*/_jsx(Box, {
139
+ maxWidth: 400,
140
+ sx: {
141
+ color: 'secondary.main',
142
+ fontSize: 16,
143
+ px: 2
144
+ },
145
+ overflow: "hidden",
146
+ whiteSpace: "nowrap",
147
+ textOverflow: "ellipsis",
148
+ children: normalizePathPrefix(mountPoint)
149
+ })
150
+ }), loading ? /*#__PURE__*/_jsx(CircularProgress, {
151
+ size: 20,
152
+ sx: {
153
+ ml: 1
154
+ }
155
+ }) : tools]
156
+ }, mountPoint);
157
+ }
158
+ ComponentCellMountPoint.propTypes = {
159
+ mountPoint: PropTypes.string.isRequired,
160
+ href: PropTypes.string.isRequired,
161
+ blocklet: PropTypes.object.isRequired,
162
+ ancestors: PropTypes.array.isRequired
163
+ };
164
+ export default ComponentCellMountPoint;
@@ -11,7 +11,6 @@ import DeleteIcon from '@mui/icons-material/Delete';
11
11
  import { Icon } from '@iconify/react';
12
12
  import Tooltip from '@mui/material/Tooltip';
13
13
  import Box from '@mui/material/Box';
14
- import normalizePathPrefix from '@abtnode/util/lib/normalize-path-prefix';
15
14
  import { getComponentMissingConfigs, getDisplayName, isInProgress, hasStartEngine } from '@blocklet/meta/lib/util';
16
15
  import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined';
17
16
  import { hasMountPoint } from '@blocklet/meta/lib/engine';
@@ -26,6 +25,7 @@ import StartComponent from './start';
26
25
  import Line from './line';
27
26
  import Actions from '../../actions';
28
27
  import ComponentInfoDialog from './component-info-dialog';
28
+ import ComponentCellMountPoint from './component-cell-mount-poin';
29
29
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
30
30
  const isResource = component => !component?.meta?.group;
31
31
  const getComponentName = (componentId, app) => {
@@ -62,6 +62,7 @@ export default function ComponentCell({
62
62
  const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
63
63
  const [loading, setLoading] = useState(false);
64
64
  const [confirmSetting, setConfirmSetting] = useState(null);
65
+ const [showComponentConfiguration, setShowComponentConfiguration] = useState(false);
65
66
  const {
66
67
  deletingBlocklets: deletingComponents
67
68
  } = useDeletingBlockletContext();
@@ -162,33 +163,11 @@ export default function ComponentCell({
162
163
  })]
163
164
  })]
164
165
  })]
165
- }, blocklet), hasMountPoint(blocklet.meta) && /*#__PURE__*/_jsx(Box, {
166
- sx: {
167
- display: {
168
- xs: 'none',
169
- md: 'flex'
170
- }
171
- },
172
- alignItems: "center",
173
- flexGrow: "1",
174
- children: /*#__PURE__*/_jsx("a", {
175
- target: "_blank",
176
- href: href,
177
- rel: "noopener noreferrer",
178
- title: href,
179
- children: /*#__PURE__*/_jsx(Box, {
180
- maxWidth: 400,
181
- sx: {
182
- color: 'secondary.main',
183
- fontSize: 16,
184
- px: 2
185
- },
186
- overflow: "hidden",
187
- whiteSpace: "nowrap",
188
- textOverflow: "ellipsis",
189
- children: normalizePathPrefix(mountPoint)
190
- })
191
- })
166
+ }, blocklet), hasMountPoint(blocklet.meta) && /*#__PURE__*/_jsx(ComponentCellMountPoint, {
167
+ blocklet: blocklet,
168
+ ancestors: ancestors,
169
+ mountPoint: mountPoint,
170
+ href: href
192
171
  }, mountPoint), /*#__PURE__*/_jsx("div", {
193
172
  style: {
194
173
  flex: 1
@@ -198,7 +177,14 @@ export default function ComponentCell({
198
177
  alignItems: "center",
199
178
  children: [hasStartEngine(blocklet.meta) && /*#__PURE__*/_jsx(Tooltip, {
200
179
  title: t('common.visit'),
201
- children: /*#__PURE__*/_jsx("a", {
180
+ children: /*#__PURE__*/_jsx(Box, {
181
+ component: "a",
182
+ sx: {
183
+ display: {
184
+ xs: 'flex',
185
+ md: 'none'
186
+ }
187
+ },
202
188
  target: "_blank",
203
189
  href: href,
204
190
  rel: "noopener noreferrer",
@@ -207,66 +193,73 @@ export default function ComponentCell({
207
193
  children: /*#__PURE__*/_jsx(LaunchIcon, {})
208
194
  })
209
195
  })
210
- }), /*#__PURE__*/_jsx(ComponentConfiguration, {
211
- blocklet: blocklet,
212
- ancestors: ancestors,
213
- children: ({
214
- open
215
- }) => /*#__PURE__*/_jsx(Tooltip, {
216
- title: t('common.config'),
217
- children: /*#__PURE__*/_jsx(StyledBadge, {
218
- color: "error",
219
- badgeContent: "",
220
- variant: "dot",
221
- invisible: !getComponentMissingConfigs(blocklet, ancestors[0]).length,
222
- children: /*#__PURE__*/_jsx(IconButton, {
223
- onClick: open,
224
- size: "small",
225
- children: /*#__PURE__*/_jsx(SettingsOutlinedIcon, {})
226
- })
227
- })
228
- }, "config")
229
196
  }), /*#__PURE__*/_jsx(StartComponent, {
230
197
  blocklet: app,
231
198
  component: blocklet,
232
199
  onStart: onStart,
233
200
  onStop: onStop,
234
201
  disabled: !['starting', 'stopping'].includes(app.status) && isInProgress(app.status)
235
- }), /*#__PURE__*/_jsx(Actions, {
236
- "data-cy": "component-actions",
237
- actions: [hasStartEngine(blocklet.meta) || isResource(blocklet) ? {
238
- icon: /*#__PURE__*/_jsx(InfoOutlinedIcon, {}),
239
- text: t('common.detail'),
240
- onClick: () => {
241
- setComponentInfo(blocklet);
242
- }
243
- } : null, {
244
- icon: /*#__PURE__*/_jsx(RestartIcon, {}),
245
- text: t('common.restart'),
246
- onClick: () => {
247
- setConfirmSetting({
248
- title: `${t('common.restart')} ${blocklet.meta.title}`,
249
- description: t('blocklet.action.restartDescription'),
250
- confirm: t('blocklet.action.confirmRestart'),
251
- cancel: t('common.cancel'),
252
- onConfirm: async () => {
253
- setLoading(true);
254
- await onRestart(blocklet);
255
- setLoading(false);
256
- },
257
- onCancel: () => setConfirmSetting(null)
258
- });
259
- },
260
- disabled: loading || appInProgress || componentInProgress || blocklet.status !== 'running'
261
- }, {
262
- icon: /*#__PURE__*/_jsx(DeleteIcon, {}),
263
- text: t('common.delete'),
264
- onClick: () => {
265
- setShowDeleteConfirm(true);
266
- },
267
- disabled: appInProgress || componentInProgress || !!deleteDisabledTip,
268
- tip: deleteDisabledTip
269
- }].filter(Boolean)
202
+ }), /*#__PURE__*/_jsx(StyledBadge, {
203
+ color: "error",
204
+ badgeContent: "",
205
+ variant: "dot",
206
+ invisible: !getComponentMissingConfigs(blocklet, ancestors[0]).length,
207
+ children: /*#__PURE__*/_jsx(Actions, {
208
+ "data-cy": "component-actions",
209
+ actions: [hasStartEngine(blocklet.meta) || isResource(blocklet) ? {
210
+ icon: /*#__PURE__*/_jsx(InfoOutlinedIcon, {}),
211
+ text: t('common.detail'),
212
+ onClick: () => {
213
+ setComponentInfo(blocklet);
214
+ }
215
+ } : null, {
216
+ icon: /*#__PURE__*/_jsx(RestartIcon, {}),
217
+ text: t('common.restart'),
218
+ onClick: () => {
219
+ setConfirmSetting({
220
+ title: `${t('common.restart')} ${blocklet.meta.title}`,
221
+ description: t('blocklet.action.restartDescription'),
222
+ confirm: t('blocklet.action.confirmRestart'),
223
+ cancel: t('common.cancel'),
224
+ onConfirm: async () => {
225
+ setLoading(true);
226
+ await onRestart(blocklet);
227
+ setLoading(false);
228
+ },
229
+ onCancel: () => setConfirmSetting(null)
230
+ });
231
+ },
232
+ disabled: loading || appInProgress || componentInProgress || blocklet.status !== 'running'
233
+ }, {
234
+ icon: /*#__PURE__*/_jsx(DeleteIcon, {}),
235
+ text: t('common.delete'),
236
+ onClick: () => {
237
+ setShowDeleteConfirm(true);
238
+ },
239
+ disabled: appInProgress || componentInProgress || !!deleteDisabledTip,
240
+ tip: deleteDisabledTip
241
+ }, {
242
+ separator: true
243
+ }, {
244
+ icon: /*#__PURE__*/_jsx(SettingsOutlinedIcon, {}),
245
+ onClick: () => {
246
+ setShowComponentConfiguration(true);
247
+ },
248
+ text: /*#__PURE__*/_jsx(StyledBadge, {
249
+ color: "error",
250
+ badgeContent: "",
251
+ variant: "dot",
252
+ invisible: !getComponentMissingConfigs(blocklet, ancestors[0]).length,
253
+ children: /*#__PURE__*/_jsx(Box, {
254
+ sx: {
255
+ width: '100%'
256
+ },
257
+ children: t('common.config')
258
+ })
259
+ }),
260
+ disabled: appInProgress || componentInProgress
261
+ }].filter(Boolean)
262
+ })
270
263
  })]
271
264
  }, "actions")]
272
265
  }, "group-not-gateway-box"), /*#__PURE__*/_jsx(Line, {}, "line"), /*#__PURE__*/_jsx(ComponentInfoDialog, {
@@ -290,7 +283,13 @@ export default function ComponentCell({
290
283
  params: confirmSetting.params,
291
284
  onConfirm: confirmSetting.onConfirm,
292
285
  onCancel: confirmSetting.onCancel
293
- }, "confirm-setting")]
286
+ }, "confirm-setting"), showComponentConfiguration && /*#__PURE__*/_jsx(ComponentConfiguration, {
287
+ open: true,
288
+ hiddenChildren: true,
289
+ onClose: () => setShowComponentConfiguration(false),
290
+ blocklet: blocklet,
291
+ ancestors: ancestors
292
+ })]
294
293
  });
295
294
  }
296
295
  ComponentCell.propTypes = {
@@ -12,13 +12,16 @@ import Tabs from '@arcblock/ux/lib/Tabs';
12
12
  import { isInstalling } from '../../util';
13
13
  import ComponentEnvironment from './environment';
14
14
  import ComponentSetting from './setting';
15
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
16
16
  export default function ComponentConfiguration({
17
+ open,
18
+ onClose,
19
+ hiddenChildren,
17
20
  blocklet,
18
21
  ancestors,
19
22
  children
20
23
  }) {
21
- const [showDialog, setShowDialog] = useState('');
24
+ const [showDialog, setShowDialog] = useState(false);
22
25
  const {
23
26
  t
24
27
  } = useLocaleContext();
@@ -31,10 +34,11 @@ export default function ComponentConfiguration({
31
34
  if (blocklet.status === 'unknown' && isInstalling(blocklet.status)) {
32
35
  return null;
33
36
  }
34
- const onClose = () => {
37
+ const handleClose = () => {
38
+ onClose?.();
35
39
  setShowDialog(false);
36
40
  };
37
- const onOpen = e => {
41
+ const handleOpen = e => {
38
42
  e.stopPropagation();
39
43
  // eslint-disable-next-line no-unused-expressions
40
44
  setShowDialog(true);
@@ -69,45 +73,57 @@ export default function ComponentConfiguration({
69
73
  setTab(newTab);
70
74
  };
71
75
  const tabConfig = tabConfigs[tab] || tabConfigsArr[0];
72
- return [typeof children === 'function' ? children({
73
- open: onOpen
74
- }) : /*#__PURE__*/_jsx(IconButton, {
75
- onClick: onOpen,
76
- "data-cy": "action-config-component",
77
- children: /*#__PURE__*/_jsx(EditIcon, {})
78
- }), showDialog && /*#__PURE__*/_jsx(StyledDialog, {
79
- open: true,
80
- fullWidth: true,
81
- maxWidth: "md",
82
- title: name,
83
- onClose: onClose,
84
- PaperProps: {
85
- style: {
86
- minHeight: 'auto'
87
- }
88
- },
89
- children: isComponent ? /*#__PURE__*/_jsxs(Box, {
90
- mt: 1,
91
- children: [/*#__PURE__*/_jsx(Tabs, {
92
- tabs: tabs,
93
- current: tab,
94
- onChange: onTabChange,
95
- scrollButtons: "auto"
96
- }), tabConfig.component]
97
- }) : /*#__PURE__*/_jsx(ComponentEnvironment, {
98
- blocklet: blocklet,
99
- ancestors: ancestors
100
- })
101
- })];
76
+ let child = null;
77
+ if (!hiddenChildren) {
78
+ child = typeof children === 'function' ? children({
79
+ open: handleOpen
80
+ }) : /*#__PURE__*/_jsx(IconButton, {
81
+ onClick: handleOpen,
82
+ "data-cy": "action-config-component",
83
+ children: /*#__PURE__*/_jsx(EditIcon, {})
84
+ });
85
+ }
86
+ return /*#__PURE__*/_jsxs(_Fragment, {
87
+ children: [child, (open || showDialog) && /*#__PURE__*/_jsx(StyledDialog, {
88
+ open: true,
89
+ fullWidth: true,
90
+ maxWidth: "md",
91
+ title: name,
92
+ onClose: handleClose,
93
+ PaperProps: {
94
+ style: {
95
+ minHeight: 'auto'
96
+ }
97
+ },
98
+ children: isComponent ? /*#__PURE__*/_jsxs(Box, {
99
+ mt: 1,
100
+ children: [/*#__PURE__*/_jsx(Tabs, {
101
+ tabs: tabs,
102
+ current: tab,
103
+ onChange: onTabChange,
104
+ scrollButtons: "auto"
105
+ }), tabConfig.component]
106
+ }) : /*#__PURE__*/_jsx(ComponentEnvironment, {
107
+ blocklet: blocklet,
108
+ ancestors: ancestors
109
+ })
110
+ })]
111
+ });
102
112
  }
103
113
  ComponentConfiguration.propTypes = {
104
114
  blocklet: PropTypes.object.isRequired,
105
115
  ancestors: PropTypes.array,
106
- children: PropTypes.any
116
+ children: PropTypes.any,
117
+ open: PropTypes.bool,
118
+ onClose: PropTypes.func,
119
+ hiddenChildren: PropTypes.bool
107
120
  };
108
121
  ComponentConfiguration.defaultProps = {
109
122
  ancestors: [],
110
- children: null
123
+ children: null,
124
+ open: false,
125
+ onClose: null,
126
+ hiddenChildren: false
111
127
  };
112
128
  const StyledDialog = styled(Dialog)`
113
129
  .MuiDialogContent-root {