@abtnode/ux 1.16.17-beta-d282d63e → 1.16.17-beta-1cab4b42
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/es/blocklet/publish/create-project.js +33 -21
- package/es/blocklet/publish/create-release.js +150 -67
- package/es/blocklet/publish/project-list.js +26 -2
- package/es/blocklet/publish/release-list.js +21 -0
- package/es/blocklet/publish/resource.js +129 -22
- package/es/blocklet/publish/tree.js +235 -0
- package/es/blocklet/router/util.js +2 -1
- package/es/locales/en.js +3 -1
- package/es/locales/zh.js +3 -1
- package/es/team/members/toggle-user-approval.js +4 -1
- package/lib/blocklet/publish/create-project.js +33 -21
- package/lib/blocklet/publish/create-release.js +145 -64
- package/lib/blocklet/publish/project-list.js +26 -2
- package/lib/blocklet/publish/release-list.js +21 -0
- package/lib/blocklet/publish/resource.js +115 -20
- package/lib/blocklet/publish/tree.js +199 -0
- package/lib/blocklet/router/util.js +2 -1
- package/lib/locales/en.js +3 -1
- package/lib/locales/zh.js +3 -1
- package/lib/team/members/toggle-user-approval.js +4 -1
- package/package.json +18 -18
|
@@ -1,12 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable react/no-unstable-nested-components */
|
|
3
|
-
import { useState, useRef, useEffect } from 'react';
|
|
1
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
4
2
|
import PropTypes from 'prop-types';
|
|
5
3
|
import styled from '@emotion/styled';
|
|
6
|
-
import
|
|
4
|
+
import difference from 'lodash/difference';
|
|
7
5
|
import joinUrl from 'url-join';
|
|
6
|
+
import Box from '@mui/material/Box';
|
|
8
7
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
8
|
+
import Button from '@arcblock/ux/lib/Button';
|
|
9
|
+
import Toast from '@arcblock/ux/lib/Toast';
|
|
10
|
+
import Tree from './tree';
|
|
11
|
+
import { useNodeContext } from '../../contexts/node';
|
|
12
|
+
import { axios } from '../../util/api';
|
|
9
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
const fillParent = (nodes, parentId) => {
|
|
16
|
+
nodes.forEach(node => {
|
|
17
|
+
if (parentId) {
|
|
18
|
+
node.parent = parentId;
|
|
19
|
+
}
|
|
20
|
+
(node.children || []).forEach(child => {
|
|
21
|
+
child.parent = node.id;
|
|
22
|
+
fillParent(child.children || [], child.id);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
return nodes;
|
|
26
|
+
};
|
|
27
|
+
const checkDiff = (a, b) => {
|
|
28
|
+
if (a.length !== b.length) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return !!difference(a, b || []).length;
|
|
32
|
+
};
|
|
10
33
|
export default function Resource({
|
|
11
34
|
app,
|
|
12
35
|
component,
|
|
@@ -17,20 +40,81 @@ export default function Resource({
|
|
|
17
40
|
t,
|
|
18
41
|
locale
|
|
19
42
|
} = useLocaleContext();
|
|
20
|
-
const
|
|
43
|
+
const {
|
|
44
|
+
api
|
|
45
|
+
} = useNodeContext();
|
|
46
|
+
const [resources, setResources] = useState([]);
|
|
47
|
+
const [selectedResourceIds, setSelectedResourceIds] = useState([]);
|
|
48
|
+
const [savedResourceIds, setSavedResourceIds] = useState([]);
|
|
49
|
+
const [loading, setLoading] = useState(false);
|
|
21
50
|
const releaseId = release.id;
|
|
22
51
|
const readonly = release.status === 'published';
|
|
23
52
|
const {
|
|
24
|
-
|
|
53
|
+
resourceExportApi = '/'
|
|
25
54
|
} = component?.meta.capabilities || {};
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
const hasDiff = useMemo(() => checkDiff(savedResourceIds, selectedResourceIds), [savedResourceIds, selectedResourceIds]);
|
|
56
|
+
const urlObj = new URL(joinUrl('http://127.0.0.1', component.mountPoint, resourceExportApi || '/').replace(/\/+/g, '/'));
|
|
57
|
+
urlObj.searchParams.set('projectId', projectId);
|
|
58
|
+
urlObj.searchParams.set('releaseId', releaseId);
|
|
59
|
+
urlObj.searchParams.set('local', locale);
|
|
60
|
+
const url = `${urlObj.pathname}${urlObj.search}`;
|
|
61
|
+
const saveSelected = async data => {
|
|
62
|
+
try {
|
|
63
|
+
await api.updateSelectedResources({
|
|
64
|
+
input: {
|
|
65
|
+
did: app.meta.did,
|
|
66
|
+
projectId,
|
|
67
|
+
releaseId,
|
|
68
|
+
componentDid: component.meta.did,
|
|
69
|
+
resources: data
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
setSavedResourceIds(data);
|
|
73
|
+
} catch (err) {
|
|
74
|
+
Toast.error(err.message);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const onSave = async () => {
|
|
78
|
+
const params = selectedResourceIds;
|
|
79
|
+
try {
|
|
80
|
+
setLoading(true);
|
|
81
|
+
await axios.post(url, {
|
|
82
|
+
resources: params,
|
|
83
|
+
projectId,
|
|
84
|
+
releaseId,
|
|
85
|
+
locale
|
|
86
|
+
});
|
|
87
|
+
Toast.success(t('common.saveSuccess'));
|
|
88
|
+
setLoading(false);
|
|
89
|
+
saveSelected(selectedResourceIds);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
setLoading(false);
|
|
92
|
+
Toast.error(err.message);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
axios.get(url).then(res => {
|
|
97
|
+
const tree = fillParent(res.data?.resources || []);
|
|
98
|
+
setResources(tree);
|
|
99
|
+
}).catch(err => {
|
|
100
|
+
Toast.error(err.message);
|
|
101
|
+
});
|
|
102
|
+
api.getSelectedResources({
|
|
103
|
+
input: {
|
|
104
|
+
did: app.meta.did,
|
|
105
|
+
projectId,
|
|
106
|
+
releaseId,
|
|
107
|
+
componentDid: component.meta.did
|
|
108
|
+
}
|
|
109
|
+
}).then(res => {
|
|
110
|
+
const list = res?.resources || [];
|
|
111
|
+
setSelectedResourceIds(list);
|
|
112
|
+
setSavedResourceIds(list);
|
|
113
|
+
}).catch(err => {
|
|
114
|
+
Toast.error(err.message);
|
|
115
|
+
});
|
|
116
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
117
|
+
}, [url]);
|
|
34
118
|
if (component.status !== 'running') {
|
|
35
119
|
return /*#__PURE__*/_jsx(Container, {
|
|
36
120
|
children: /*#__PURE__*/_jsx(Box, {
|
|
@@ -42,12 +126,23 @@ export default function Resource({
|
|
|
42
126
|
});
|
|
43
127
|
}
|
|
44
128
|
return /*#__PURE__*/_jsx(Container, {
|
|
45
|
-
children: /*#__PURE__*/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
129
|
+
children: /*#__PURE__*/_jsxs(Box, {
|
|
130
|
+
children: [/*#__PURE__*/_jsx(Tree, {
|
|
131
|
+
data: resources,
|
|
132
|
+
value: selectedResourceIds,
|
|
133
|
+
onChange: data => {
|
|
134
|
+
setSelectedResourceIds(data);
|
|
135
|
+
},
|
|
136
|
+
disabled: loading || readonly
|
|
137
|
+
}), !readonly && /*#__PURE__*/_jsx(Box, {
|
|
138
|
+
className: "footer",
|
|
139
|
+
children: /*#__PURE__*/_jsx(Button, {
|
|
140
|
+
variant: "contained",
|
|
141
|
+
disabled: loading || !hasDiff,
|
|
142
|
+
onClick: () => onSave(),
|
|
143
|
+
children: t('common.save')
|
|
144
|
+
})
|
|
145
|
+
})]
|
|
51
146
|
})
|
|
52
147
|
});
|
|
53
148
|
}
|
|
@@ -66,7 +161,19 @@ Resource.defaultProps = {
|
|
|
66
161
|
}
|
|
67
162
|
};
|
|
68
163
|
const Container = styled(Box)`
|
|
69
|
-
|
|
70
|
-
|
|
164
|
+
border: 1px solid #ccc;
|
|
165
|
+
border-radius: 4px;
|
|
166
|
+
padding: 16px;
|
|
167
|
+
padding-bottom: 0px;
|
|
168
|
+
max-height: 600px;
|
|
169
|
+
overflow-y: auto;
|
|
170
|
+
.footer {
|
|
171
|
+
border-top: 1px solid #ddd;
|
|
172
|
+
display: flex;
|
|
173
|
+
padding: 12px 0;
|
|
174
|
+
margin-top: 12px;
|
|
175
|
+
position: sticky;
|
|
176
|
+
bottom: 0;
|
|
177
|
+
background: #fff;
|
|
71
178
|
}
|
|
72
179
|
`;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import styled from '@emotion/styled';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import isUrl from 'is-url';
|
|
5
|
+
import Box from '@mui/material/Box';
|
|
6
|
+
import FormControlLabel from '@mui/material/FormControlLabel';
|
|
7
|
+
import TreeView from '@mui/lab/TreeView';
|
|
8
|
+
import TreeItem from '@mui/lab/TreeItem';
|
|
9
|
+
import Checkbox from '@mui/material/Checkbox';
|
|
10
|
+
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|
11
|
+
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
|
|
12
|
+
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
|
|
13
|
+
import { Icon } from '@iconify/react';
|
|
14
|
+
|
|
15
|
+
// BFS algorithm to find node by his ID
|
|
16
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
const bfsSearch = (graph, targetId) => {
|
|
19
|
+
const queue = [...graph];
|
|
20
|
+
while (queue.length > 0) {
|
|
21
|
+
const currNode = queue.shift();
|
|
22
|
+
if (currNode.id === targetId) {
|
|
23
|
+
return currNode;
|
|
24
|
+
}
|
|
25
|
+
if (currNode.children) {
|
|
26
|
+
queue.push(...currNode.children);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return []; // Target node not found
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function ResourceIcon({
|
|
33
|
+
icon
|
|
34
|
+
}) {
|
|
35
|
+
if (!icon) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
if (isUrl(icon)) {
|
|
39
|
+
return /*#__PURE__*/_jsx("img", {
|
|
40
|
+
className: "resource-icon",
|
|
41
|
+
src: icon,
|
|
42
|
+
alt: "icon"
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return /*#__PURE__*/_jsx(Icon, {
|
|
46
|
+
className: "resource-icon",
|
|
47
|
+
icon: icon
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
ResourceIcon.propTypes = {
|
|
51
|
+
icon: PropTypes.string
|
|
52
|
+
};
|
|
53
|
+
ResourceIcon.defaultProps = {
|
|
54
|
+
icon: ''
|
|
55
|
+
};
|
|
56
|
+
export default function Tree({
|
|
57
|
+
disabled,
|
|
58
|
+
data,
|
|
59
|
+
onChange,
|
|
60
|
+
value
|
|
61
|
+
}) {
|
|
62
|
+
const selectedNodes = value;
|
|
63
|
+
|
|
64
|
+
// Retrieve all ids from node to his children's
|
|
65
|
+
function getAllIds(node, idList = []) {
|
|
66
|
+
idList.push(node.id);
|
|
67
|
+
if (node.children) {
|
|
68
|
+
node.children.forEach(child => getAllIds(child, idList));
|
|
69
|
+
}
|
|
70
|
+
return idList;
|
|
71
|
+
}
|
|
72
|
+
// Get IDs of all children from specific node
|
|
73
|
+
const getAllChild = id => {
|
|
74
|
+
return getAllIds(bfsSearch(data, id));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Get all father IDs from specific node
|
|
78
|
+
const getAllFathers = (id, list = []) => {
|
|
79
|
+
const node = bfsSearch(data, id);
|
|
80
|
+
if (node.parent) {
|
|
81
|
+
list.push(node.parent);
|
|
82
|
+
return getAllFathers(node.parent, list);
|
|
83
|
+
}
|
|
84
|
+
return list;
|
|
85
|
+
};
|
|
86
|
+
function isAllChildrenChecked(node, list) {
|
|
87
|
+
const allChild = getAllChild(node.id);
|
|
88
|
+
const nodeIdIndex = allChild.indexOf(node.id);
|
|
89
|
+
allChild.splice(nodeIdIndex, 1);
|
|
90
|
+
return allChild.every(nodeId => selectedNodes.concat(list).includes(nodeId));
|
|
91
|
+
}
|
|
92
|
+
const handleNodeSelect = (event, nodeId) => {
|
|
93
|
+
event.stopPropagation();
|
|
94
|
+
const allChild = getAllChild(nodeId);
|
|
95
|
+
const fathers = getAllFathers(nodeId);
|
|
96
|
+
if (selectedNodes.includes(nodeId)) {
|
|
97
|
+
// Need to de-check
|
|
98
|
+
const newValue = selectedNodes.filter(id => !allChild.concat(fathers).includes(id));
|
|
99
|
+
onChange(newValue);
|
|
100
|
+
} else {
|
|
101
|
+
// Need to check
|
|
102
|
+
const ToBeChecked = allChild;
|
|
103
|
+
for (let i = 0; i < fathers.length; ++i) {
|
|
104
|
+
if (isAllChildrenChecked(bfsSearch(data, fathers[i]), ToBeChecked)) {
|
|
105
|
+
ToBeChecked.push(fathers[i]);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
onChange([...selectedNodes].concat(ToBeChecked));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const stopExpand = event => {
|
|
112
|
+
// prevent the click event from propagating to the checkbox
|
|
113
|
+
event.stopPropagation();
|
|
114
|
+
};
|
|
115
|
+
const hadChildren = data.some(node => node.children?.length > 0);
|
|
116
|
+
const renderTree = node => /*#__PURE__*/_jsx(TreeItem, {
|
|
117
|
+
nodeId: node.id,
|
|
118
|
+
label: /*#__PURE__*/_jsx(FormControlLabel, {
|
|
119
|
+
onClick: stopExpand,
|
|
120
|
+
control: /*#__PURE__*/_jsx(Checkbox, {
|
|
121
|
+
size: "small",
|
|
122
|
+
checked: selectedNodes.indexOf(node.id) !== -1,
|
|
123
|
+
tabIndex: -1,
|
|
124
|
+
disableRipple: true,
|
|
125
|
+
onClick: event => handleNodeSelect(event, node.id),
|
|
126
|
+
disabled: disabled
|
|
127
|
+
}),
|
|
128
|
+
label: /*#__PURE__*/_jsxs(Box, {
|
|
129
|
+
className: "content",
|
|
130
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
131
|
+
display: "flex",
|
|
132
|
+
alignItems: "center",
|
|
133
|
+
children: [node.icon && /*#__PURE__*/_jsx(ResourceIcon, {
|
|
134
|
+
icon: node.icon
|
|
135
|
+
}), /*#__PURE__*/_jsx(Box, {
|
|
136
|
+
className: "name",
|
|
137
|
+
children: node.name
|
|
138
|
+
}), node.url && /*#__PURE__*/_jsx("a", {
|
|
139
|
+
href: node.url,
|
|
140
|
+
target: "_blank",
|
|
141
|
+
rel: "noreferrer",
|
|
142
|
+
className: "link",
|
|
143
|
+
children: /*#__PURE__*/_jsx(OpenInNewIcon, {
|
|
144
|
+
className: "link-icon"
|
|
145
|
+
})
|
|
146
|
+
})]
|
|
147
|
+
}), !!node.description && /*#__PURE__*/_jsx(Box, {
|
|
148
|
+
className: "description",
|
|
149
|
+
children: node.description
|
|
150
|
+
})]
|
|
151
|
+
})
|
|
152
|
+
}),
|
|
153
|
+
children: Array.isArray(node.children) ? node.children.map(renderTree) : null
|
|
154
|
+
}, node.id);
|
|
155
|
+
return /*#__PURE__*/_jsx(StyledTreeView, {
|
|
156
|
+
className: classnames(!hadChildren && 'no-children'),
|
|
157
|
+
multiSelect: true,
|
|
158
|
+
defaultCollapseIcon: /*#__PURE__*/_jsx(ExpandMoreIcon, {}),
|
|
159
|
+
defaultExpandIcon: /*#__PURE__*/_jsx(ChevronRightIcon, {}),
|
|
160
|
+
selected: selectedNodes,
|
|
161
|
+
children: data.map(node => renderTree(node))
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
Tree.propTypes = {
|
|
165
|
+
data: PropTypes.array,
|
|
166
|
+
value: PropTypes.array,
|
|
167
|
+
onChange: PropTypes.func,
|
|
168
|
+
disabled: PropTypes.bool
|
|
169
|
+
};
|
|
170
|
+
Tree.defaultProps = {
|
|
171
|
+
data: [],
|
|
172
|
+
value: [],
|
|
173
|
+
onChange: () => {},
|
|
174
|
+
disabled: false
|
|
175
|
+
};
|
|
176
|
+
const StyledTreeView = styled(TreeView)`
|
|
177
|
+
&.no-children {
|
|
178
|
+
.MuiTreeItem-content {
|
|
179
|
+
padding: 0;
|
|
180
|
+
.MuiTreeItem-iconContainer {
|
|
181
|
+
display: none;
|
|
182
|
+
}
|
|
183
|
+
.MuiTreeItem-label {
|
|
184
|
+
padding-left: 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
.MuiTreeItem-content {
|
|
189
|
+
align-items: flex-start;
|
|
190
|
+
.MuiTreeItem-iconContainer {
|
|
191
|
+
transform: translateY(10px);
|
|
192
|
+
}
|
|
193
|
+
&.Mui-selected {
|
|
194
|
+
background-color: transparent;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
.MuiTreeItem-label {
|
|
198
|
+
cursor: default;
|
|
199
|
+
}
|
|
200
|
+
.MuiFormControlLabel-root {
|
|
201
|
+
align-items: flex-start;
|
|
202
|
+
}
|
|
203
|
+
.content {
|
|
204
|
+
padding-top: 6px;
|
|
205
|
+
}
|
|
206
|
+
.name {
|
|
207
|
+
font-size: 16px;
|
|
208
|
+
font-weight: 700;
|
|
209
|
+
}
|
|
210
|
+
.resource-icon {
|
|
211
|
+
margin-right: 2px;
|
|
212
|
+
font-size: 16px;
|
|
213
|
+
}
|
|
214
|
+
img.resource-icon {
|
|
215
|
+
width: 1rem;
|
|
216
|
+
height: 1rem;
|
|
217
|
+
}
|
|
218
|
+
.link {
|
|
219
|
+
margin-left: 8px;
|
|
220
|
+
font-size: 16px;
|
|
221
|
+
color: ${({
|
|
222
|
+
theme
|
|
223
|
+
}) => theme.palette.primary.main};
|
|
224
|
+
display: flex;
|
|
225
|
+
}
|
|
226
|
+
.link-icon {
|
|
227
|
+
font-size: inherit;
|
|
228
|
+
}
|
|
229
|
+
.description {
|
|
230
|
+
font-size: 14px;
|
|
231
|
+
color: ${({
|
|
232
|
+
theme
|
|
233
|
+
}) => theme.palette.text.secondary};
|
|
234
|
+
}
|
|
235
|
+
`;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { ROUTING_RULE_TYPES, DEFAULT_IP_DOMAIN_SUFFIX, DOMAIN_FOR_IP_SITE_REGEXP, DOMAIN_FOR_DEFAULT_SITE, DOMAIN_FOR_IP_SITE } from '@abtnode/constant';
|
|
3
3
|
import isPathPrefixEqual from '@abtnode/util/lib/is-path-prefix-equal';
|
|
4
4
|
import { BLOCKLET_DYNAMIC_PATH_PREFIX } from '@blocklet/constant';
|
|
5
|
+
import hasStartEngine from '@blocklet/meta/lib/has-start-engine';
|
|
5
6
|
const validateRuleByServiceType = (params, localeContext) => {
|
|
6
7
|
if (params.type === ROUTING_RULE_TYPES.REDIRECT) {
|
|
7
8
|
if (!params.url) {
|
|
@@ -74,7 +75,7 @@ export const validatePathPrefix = ({
|
|
|
74
75
|
}) => {
|
|
75
76
|
// validate children
|
|
76
77
|
if (curBlocklet) {
|
|
77
|
-
let exist = (curBlocklet.children || []).find(x => isPathPrefixEqual(x.mountPoint, params.pathPrefix));
|
|
78
|
+
let exist = (curBlocklet.children || []).find(x => hasStartEngine(x.meta) && isPathPrefixEqual(x.mountPoint, params.pathPrefix));
|
|
78
79
|
if (curBlocklet.meta.group !== 'gateway' && params.pathPrefix === '/') {
|
|
79
80
|
exist = '/';
|
|
80
81
|
}
|
package/es/locales/en.js
CHANGED
|
@@ -632,6 +632,7 @@ module.exports = {
|
|
|
632
632
|
saveDraft: 'Save Draft',
|
|
633
633
|
releaseNote: 'Release Note',
|
|
634
634
|
errorTip: {
|
|
635
|
+
noDid: 'Blocklet DID is required',
|
|
635
636
|
noTitle: 'Blocklet Title is required',
|
|
636
637
|
noVersion: 'Blocklet Version is required',
|
|
637
638
|
noDescription: 'Blocklet Description is required',
|
|
@@ -1313,7 +1314,8 @@ module.exports = {
|
|
|
1313
1314
|
launchFailed: 'Failed to launch the app, please try again',
|
|
1314
1315
|
installedButStopped: 'The app is installed successfully, but cannot be started. You can start it manually after resolving blocking issues',
|
|
1315
1316
|
installedButError: 'The app is successfully installed, but failed to start',
|
|
1316
|
-
restoreFailed: 'Failed to restore app, please try again'
|
|
1317
|
+
restoreFailed: 'Failed to restore app, please try again',
|
|
1318
|
+
resourceBlocklet: 'Resource Blocklet cannot be installed as an application, you can mount this blocklet into existing applications.'
|
|
1317
1319
|
},
|
|
1318
1320
|
steps: {
|
|
1319
1321
|
introduction: 'Introduction',
|
package/es/locales/zh.js
CHANGED
|
@@ -639,6 +639,7 @@ module.exports = {
|
|
|
639
639
|
saveDraft: '保存草稿',
|
|
640
640
|
releaseNote: '发布说明',
|
|
641
641
|
errorTip: {
|
|
642
|
+
noDid: '请填写 Blocklet DID',
|
|
642
643
|
noTitle: '请填写 Blocklet 名称',
|
|
643
644
|
noVersion: '请填写 Blocklet 版本号',
|
|
644
645
|
noDescription: '请填写 Blocklet 描述',
|
|
@@ -1318,7 +1319,8 @@ module.exports = {
|
|
|
1318
1319
|
launchFailed: '启动应用失败,请重试',
|
|
1319
1320
|
installedButStopped: '应用安装成功,但是无法启动,解决启动问题之后后可手动启动',
|
|
1320
1321
|
installedButError: '应用已经安装,但是运行出错了',
|
|
1321
|
-
restoreFailed: '还原应用失败,请重试'
|
|
1322
|
+
restoreFailed: '还原应用失败,请重试',
|
|
1323
|
+
resourceBlocklet: '资源 Blocklet 无法作为应用被安装,你可以将该 Blocklet 挂载到现有的应用中。'
|
|
1322
1324
|
},
|
|
1323
1325
|
steps: {
|
|
1324
1326
|
introduction: '简介',
|
|
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
4
4
|
import Toast from '@arcblock/ux/lib/Toast';
|
|
5
|
+
import { hasActiveOwnerPassport } from '@abtnode/util/lib/passport';
|
|
5
6
|
import Confirm from '../../confirm';
|
|
6
7
|
import { useNodeContext } from '../../contexts/node';
|
|
7
8
|
import { useTeamContext } from '../../contexts/team';
|
|
@@ -82,7 +83,9 @@ export default function ToggleUserApproval({
|
|
|
82
83
|
color: user.approved ? 'error' : 'primary'
|
|
83
84
|
};
|
|
84
85
|
let can;
|
|
85
|
-
if (
|
|
86
|
+
if (hasActiveOwnerPassport(user)) {
|
|
87
|
+
can = false;
|
|
88
|
+
} else if (!inService) {
|
|
86
89
|
can = nodeInfo.nodeOwner && !isNodeOwner(nodeInfo, user.did) && !isSelf(session.user, user.did);
|
|
87
90
|
} else {
|
|
88
91
|
can = !isSelf(session.user, user.did);
|
|
@@ -10,13 +10,13 @@ var _MenuItem = _interopRequireDefault(require("@mui/material/MenuItem"));
|
|
|
10
10
|
var _TextField = _interopRequireDefault(require("@mui/material/TextField"));
|
|
11
11
|
var _Typography = _interopRequireDefault(require("@mui/material/Typography"));
|
|
12
12
|
var _Breadcrumbs = _interopRequireDefault(require("@mui/material/Breadcrumbs"));
|
|
13
|
+
var _InputAdornment = _interopRequireDefault(require("@mui/material/InputAdornment"));
|
|
13
14
|
var _styled = _interopRequireDefault(require("@emotion/styled"));
|
|
14
15
|
var _context = require("@arcblock/ux/lib/Locale/context");
|
|
15
16
|
var _Box = _interopRequireDefault(require("@mui/material/Box"));
|
|
16
17
|
var _Button = _interopRequireDefault(require("@arcblock/ux/lib/Button"));
|
|
17
18
|
var _Connect = _interopRequireDefault(require("@arcblock/did-connect/lib/Connect"));
|
|
18
19
|
var _Toast = _interopRequireDefault(require("@arcblock/ux/lib/Toast"));
|
|
19
|
-
var _didAddress = _interopRequireDefault(require("../../did-address"));
|
|
20
20
|
var _node = require("../../contexts/node");
|
|
21
21
|
var _blocklet = require("../../contexts/blocklet");
|
|
22
22
|
var _session = require("../../contexts/session");
|
|
@@ -80,6 +80,14 @@ function CreateProject(_ref) {
|
|
|
80
80
|
setOpenConnect(false);
|
|
81
81
|
};
|
|
82
82
|
const onCreate = () => {
|
|
83
|
+
if (!blockletDid) {
|
|
84
|
+
_Toast.default.error(t('blocklet.publish.errorTip.noDid'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!blockletTitle) {
|
|
88
|
+
_Toast.default.error(t('blocklet.publish.errorTip.noTitle'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
83
91
|
setLoading(true);
|
|
84
92
|
api.createProject({
|
|
85
93
|
input: {
|
|
@@ -113,26 +121,29 @@ function CreateProject(_ref) {
|
|
|
113
121
|
style: {
|
|
114
122
|
maxWidth: 500
|
|
115
123
|
},
|
|
116
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
124
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
|
|
125
|
+
required: true,
|
|
117
126
|
sx: {
|
|
118
|
-
mb:
|
|
127
|
+
mb: 4
|
|
119
128
|
},
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
129
|
+
label: "Blocklet DID",
|
|
130
|
+
fullWidth: true,
|
|
131
|
+
readonly: true,
|
|
132
|
+
autoComplete: "off",
|
|
133
|
+
variant: "outlined",
|
|
134
|
+
onClick: () => !blockletDid && setOpenConnect(true),
|
|
135
|
+
InputProps: {
|
|
136
|
+
'data-cy': 'export-blocklet-did',
|
|
137
|
+
endAdornment: /*#__PURE__*/(0, _jsxRuntime.jsx)(_InputAdornment.default, {
|
|
138
|
+
position: "end",
|
|
139
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
|
|
140
|
+
onClick: () => setOpenConnect(true),
|
|
141
|
+
children: t(blockletDid ? 'common.update' : 'common.create')
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
},
|
|
145
|
+
helperText: "",
|
|
146
|
+
value: blockletDid || ''
|
|
136
147
|
}), openConnect && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Connect.default, {
|
|
137
148
|
open: true,
|
|
138
149
|
popup: true,
|
|
@@ -155,10 +166,11 @@ function CreateProject(_ref) {
|
|
|
155
166
|
success: t('blocklet.publish.connect.success')
|
|
156
167
|
}
|
|
157
168
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
|
|
169
|
+
required: true,
|
|
158
170
|
label: "Blocklet ".concat(t('common.title')),
|
|
159
171
|
autoComplete: "off",
|
|
160
172
|
variant: "outlined",
|
|
161
|
-
|
|
173
|
+
InputProps: {
|
|
162
174
|
'data-cy': 'export-blocklet-title'
|
|
163
175
|
},
|
|
164
176
|
fullWidth: true,
|
|
@@ -186,7 +198,7 @@ function CreateProject(_ref) {
|
|
|
186
198
|
})]
|
|
187
199
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Button.default, {
|
|
188
200
|
variant: "contained",
|
|
189
|
-
disabled: loading
|
|
201
|
+
disabled: loading,
|
|
190
202
|
onClick: onCreate,
|
|
191
203
|
children: t('common.create')
|
|
192
204
|
})]
|