@abtnode/ux 1.16.25-beta-e3dbef52 → 1.16.25-beta-44800645

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 (49) hide show
  1. package/es/actions.js +3 -1
  2. package/es/blocklet/actions.js +11 -7
  3. package/es/blocklet/router/action/add-rule.js +12 -0
  4. package/es/blocklet/router/action/config-routing-rule.js +55 -4
  5. package/es/blocklet/router/action/update-rule.js +12 -0
  6. package/es/blocklet/router/rule-list.js +10 -2
  7. package/es/locales/ar.js +12 -3
  8. package/es/locales/de.js +12 -3
  9. package/es/locales/en.js +11 -2
  10. package/es/locales/es.js +12 -3
  11. package/es/locales/fr.js +12 -3
  12. package/es/locales/hi.js +12 -3
  13. package/es/locales/i18n.db +0 -0
  14. package/es/locales/id.js +12 -3
  15. package/es/locales/ja.js +12 -3
  16. package/es/locales/ko.js +12 -3
  17. package/es/locales/pt.js +12 -3
  18. package/es/locales/ru.js +12 -3
  19. package/es/locales/th.js +12 -3
  20. package/es/locales/vi.js +12 -3
  21. package/es/locales/zh-tw.js +12 -3
  22. package/es/locales/zh.js +12 -3
  23. package/es/team/members/actions.js +61 -5
  24. package/es/team/members/index.js +87 -15
  25. package/lib/actions.js +3 -1
  26. package/lib/blocklet/actions.js +11 -7
  27. package/lib/blocklet/router/action/add-rule.js +12 -0
  28. package/lib/blocklet/router/action/config-routing-rule.js +52 -3
  29. package/lib/blocklet/router/action/update-rule.js +13 -0
  30. package/lib/blocklet/router/rule-list.js +10 -1
  31. package/lib/locales/ar.js +12 -3
  32. package/lib/locales/de.js +12 -3
  33. package/lib/locales/en.js +11 -2
  34. package/lib/locales/es.js +12 -3
  35. package/lib/locales/fr.js +12 -3
  36. package/lib/locales/hi.js +12 -3
  37. package/lib/locales/i18n.db +0 -0
  38. package/lib/locales/id.js +12 -3
  39. package/lib/locales/ja.js +12 -3
  40. package/lib/locales/ko.js +12 -3
  41. package/lib/locales/pt.js +12 -3
  42. package/lib/locales/ru.js +12 -3
  43. package/lib/locales/th.js +12 -3
  44. package/lib/locales/vi.js +12 -3
  45. package/lib/locales/zh-tw.js +12 -3
  46. package/lib/locales/zh.js +12 -3
  47. package/lib/team/members/actions.js +61 -5
  48. package/lib/team/members/index.js +93 -19
  49. package/package.json +15 -14
package/es/locales/th.js CHANGED
@@ -687,7 +687,9 @@ export default {
687
687
  installResourceHelp: 'เอกสารช่วยเหลือ',
688
688
  componentIncluded: 'รวมอยู่ใน',
689
689
  componentForceRequired: 'บังคับต้องการ'
690
- }
690
+ },
691
+ titleValidationError: 'ความยาวของชื่อต้องมีอย่างน้อย 3 ตัวอักษร',
692
+ descriptionValidationError: 'ความยาวคำอธิบายต้องอยู่ระหว่าง 3 ถึง 160 ตัวอักษร.'
691
693
  },
692
694
  dashboard: {
693
695
  nodeDid: 'โหนด',
@@ -1037,7 +1039,11 @@ export default {
1037
1039
  pathPrefixTip: "หากคุณตั้งค่าคำนำหน้าเป็น '/my-prefix' จะทำให้คำขอที่ตั้งต้นด้วยคำนำหน้าเหล่านั้นจะถูกส่งมายังบล็อกเลตที่กำหนด",
1038
1040
  blocklet: 'Blocklet ไหนจะดูแลการร้องขอเหล่านั้น?',
1039
1041
  port: 'พอร์ตของบล็อกเล็ตใดที่จะรับผิดชอบการร้องขอ?',
1040
- portTip: 'นี่คือค่าพื้นฐานของพอร์ตหลักของ blocklet ถ้า blocklet ของคุณฟังถึงพอร์ตหลายๆพอร์ต คุณสามารถปรับแต่งได้'
1042
+ portTip: 'นี่คือค่าพื้นฐานของพอร์ตหลักของ blocklet ถ้า blocklet ของคุณฟังถึงพอร์ตหลายๆพอร์ต คุณสามารถปรับแต่งได้',
1043
+ responseType: 'ประเภทการตอบกลับ',
1044
+ responseBody: 'เนื้อหาการตอบกลับ',
1045
+ responseBodyTip: 'วางเนื้อหาการตอบสนองของคุณที่นี่ ต้องไม่เกิน 4096 อักขระ',
1046
+ responseBodyRequired: 'เนื้อหาการตอบกลับต้องไม่เป็นค่าว่าง'
1041
1047
  },
1042
1048
  delete: {
1043
1049
  title: 'ลบการแมปลิงก์ URL',
@@ -1189,7 +1195,10 @@ export default {
1189
1195
  url: 'URL ที่กำหนดเอง',
1190
1196
  slack: 'Slack Webhook',
1191
1197
  tested: 'ส่งข้อความทดสอบแล้ว'
1192
- }
1198
+ },
1199
+ activeUserSessions: 'เซสชันผู้ใช้ที่ใช้งานอยู่',
1200
+ forceLogout: 'ออกจากระบบบังคับ',
1201
+ forceLogoutDescription: 'ยืนยันให้ออกจากระบบผู้ใช้นี้หรือไม่?'
1193
1202
  },
1194
1203
  transferNode: {
1195
1204
  name: 'โอนสิทธิ์การเป็นเจ้าของ',
package/es/locales/vi.js CHANGED
@@ -687,7 +687,9 @@ export default {
687
687
  installResourceHelp: 'Tài liệu giúp đỡ',
688
688
  componentIncluded: 'Bao gồm',
689
689
  componentForceRequired: 'Bắt Buộc Yêu Cầu'
690
- }
690
+ },
691
+ titleValidationError: 'Độ dài tiêu đề phải ít nhất 3 ký tự',
692
+ descriptionValidationError: 'Chiều dài mô tả phải từ 3 đến 160 ký tự.'
691
693
  },
692
694
  dashboard: {
693
695
  nodeDid: 'Nút',
@@ -1037,7 +1039,11 @@ export default {
1037
1039
  pathPrefixTip: "Nếu bạn đặt tiền tố là '/tiền-tố-của-tôi', thì tất cả các yêu cầu bắt đầu bằng tiền tố đó sẽ được định tuyến đến khối đã được cấu hình",
1038
1040
  blocklet: 'Blocklet nào sẽ xử lý những yêu cầu đó?',
1039
1041
  port: 'Cổng nào của blocklet sẽ xử lý các yêu cầu?',
1040
- portTip: 'Mặc định là cổng chính của blocklet, nếu blocklet của bạn lắng nghe trên nhiều cổng, bạn có thể tùy chỉnh điều này'
1042
+ portTip: 'Mặc định là cổng chính của blocklet, nếu blocklet của bạn lắng nghe trên nhiều cổng, bạn có thể tùy chỉnh điều này',
1043
+ responseType: 'Loại phản hồi',
1044
+ responseBody: 'Nội dung phản hồi',
1045
+ responseBodyTip: 'Dán nội dung đáp ứng của bạn vào đây, không vượt quá 4096 ký tự',
1046
+ responseBodyRequired: 'Nội dung phản hồi không thể trống'
1041
1047
  },
1042
1048
  delete: {
1043
1049
  title: 'Xóa Liên kết URL',
@@ -1189,7 +1195,10 @@ export default {
1189
1195
  url: 'URL tùy chỉnh',
1190
1196
  slack: 'Slack Webhook',
1191
1197
  tested: 'Tin nhắn kiểm tra đã được gửi'
1192
- }
1198
+ },
1199
+ activeUserSessions: 'Phiên người dùng hoạt động',
1200
+ forceLogout: 'Đăng xuất bắt buộc',
1201
+ forceLogoutDescription: 'Xác nhận đăng xuất buộc người dùng này?'
1193
1202
  },
1194
1203
  transferNode: {
1195
1204
  name: 'Chuyển quyền sở hữu',
@@ -687,7 +687,9 @@ export default {
687
687
  installResourceHelp: '幫助文件',
688
688
  componentIncluded: '已包含',
689
689
  componentForceRequired: '強制要求'
690
- }
690
+ },
691
+ titleValidationError: '標題長度必須至少為3到40個字符',
692
+ descriptionValidationError: '描述長度必須介於3到160個字符之間'
691
693
  },
692
694
  dashboard: {
693
695
  nodeDid: '節點',
@@ -1037,7 +1039,11 @@ export default {
1037
1039
  pathPrefixTip: "如果您將前綴設置為'/my-prefix',則所有以該前綴開頭的請求將被路由到配置的區塊",
1038
1040
  blocklet: '哪一個Blocklet將處理這些請求?',
1039
1041
  port: '區塊上的哪個埠將處理請求?',
1040
- portTip: '這預設為 blocklet 的主要埠口,如果您的 blocklet 監聽多個埠口,您可以自訂這個'
1042
+ portTip: '這預設為 blocklet 的主要埠口,如果您的 blocklet 監聽多個埠口,您可以自訂這個',
1043
+ responseType: '回應類型',
1044
+ responseBody: '回應內容',
1045
+ responseBodyTip: '請將您的回覆內容貼上此處,不得超過4096個字元',
1046
+ responseBodyRequired: '回應內容不能為空'
1041
1047
  },
1042
1048
  delete: {
1043
1049
  title: '刪除URL映射',
@@ -1189,7 +1195,10 @@ export default {
1189
1195
  url: '客製網址',
1190
1196
  slack: 'Slack Webhook',
1191
1197
  tested: '測試訊息已發送'
1192
- }
1198
+ },
1199
+ activeUserSessions: '活躍用戶會話',
1200
+ forceLogout: '強制登出',
1201
+ forceLogoutDescription: '確認是否強制登出此使用者?'
1193
1202
  },
1194
1203
  transferNode: {
1195
1204
  name: '轉讓所有權',
package/es/locales/zh.js CHANGED
@@ -690,7 +690,9 @@ export default {
690
690
  noDescription: '请填写 Blocklet 描述',
691
691
  noNote: '请填写 发布说明'
692
692
  }
693
- }
693
+ },
694
+ titleValidationError: '标题长度必须至少为3到40个字符',
695
+ descriptionValidationError: '描述长度必须在3到160个字符之间'
694
696
  },
695
697
  dashboard: {
696
698
  nodeDid: '节点地址',
@@ -1041,7 +1043,11 @@ export default {
1041
1043
  pathPrefixTip: "如果你填写了 '/prefix',那么所有以其为前缀的请求都会被转发到配置的基石程序",
1042
1044
  blocklet: '把请求代理到哪个服务?',
1043
1045
  port: '把请求代理到哪个端口?',
1044
- portTip: '这里的默认值是应用默认监听的端口,如果你的应用会启用多个端口,你可以根据需要自定义'
1046
+ portTip: '这里的默认值是应用默认监听的端口,如果你的应用会启用多个端口,你可以根据需要自定义',
1047
+ responseType: '回应类型',
1048
+ responseBody: '响应内容',
1049
+ responseBodyTip: '请将您的回复内容粘贴在这里,不要超过4096个字符',
1050
+ responseBodyRequired: '响应内容不能为空'
1045
1051
  },
1046
1052
  delete: {
1047
1053
  title: '删除规则',
@@ -1193,7 +1199,10 @@ export default {
1193
1199
  url: '自定义 URL',
1194
1200
  slack: 'Slack 通知',
1195
1201
  tested: '测试消息已经发送'
1196
- }
1202
+ },
1203
+ activeUserSessions: '活跃用户会话',
1204
+ forceLogout: '强制注销',
1205
+ forceLogoutDescription: '确认是否强制退出此用户?'
1197
1206
  },
1198
1207
  transferNode: {
1199
1208
  name: '转移所有者',
@@ -2,33 +2,66 @@ import { useState, useContext } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import MenuItem from '@mui/material/MenuItem';
4
4
  import AddIcon from '@mui/icons-material/Add';
5
+ import LogoutIcon from '@mui/icons-material/Logout';
5
6
  import ListItemIcon from '@mui/material/ListItemIcon';
6
7
  import ListItemText from '@mui/material/ListItemText';
7
8
  import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
8
9
  import ForbidLoginIcon from '@arcblock/icons/lib/ForbidLoginIcon';
9
10
  import AllowLoginIcon from '@arcblock/icons/lib/AllowLoginIcon';
10
11
  import { getWalletDid } from '@blocklet/meta/lib/did-utils';
12
+ import { useConfirm } from '@arcblock/ux/lib/Dialog';
13
+ import { useMemoizedFn } from 'ahooks';
14
+ import pAll from 'p-all';
11
15
  import { useTeamContext } from '../../contexts/team';
12
16
  import Actions from '../../actions';
13
17
  import IssuePassport from './issue-passport';
14
18
  import ToggleUserApproval from './toggle-user-approval';
19
+ import { useNodeContext } from '../../contexts/node';
15
20
  import { jsx as _jsx } from "react/jsx-runtime";
16
21
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
22
  import { Fragment as _Fragment } from "react/jsx-runtime";
18
23
  export default function MemberActions({
24
+ type,
19
25
  user,
20
- onIssuePassport
26
+ onIssuePassport,
27
+ onRefresh
21
28
  }) {
22
29
  const {
23
30
  teamDid,
24
31
  roles
25
32
  } = useTeamContext();
33
+ const {
34
+ confirmHolder,
35
+ confirmApi
36
+ } = useConfirm();
26
37
  const {
27
38
  t
28
39
  } = useContext(LocaleContext);
29
40
  const [enablePassportIssuance, setEnablePassportIssuance] = useState(false);
41
+ const {
42
+ api
43
+ } = useNodeContext();
44
+ const logoutUser = useMemoizedFn(async () => {
45
+ const {
46
+ userSessions = []
47
+ } = user;
48
+ const list = userSessions.map(x => {
49
+ return () => api.logoutUser({
50
+ input: {
51
+ teamDid,
52
+ appPid: teamDid,
53
+ userDid: user.did,
54
+ visitorId: x.visitorId
55
+ }
56
+ });
57
+ });
58
+ await pAll(list, {
59
+ concurrency: 3,
60
+ stopOnError: false
61
+ });
62
+ });
30
63
  return /*#__PURE__*/_jsxs(_Fragment, {
31
- children: [/*#__PURE__*/_jsx(Actions, {
64
+ children: [confirmHolder, /*#__PURE__*/_jsx(Actions, {
32
65
  "data-cy": "member-actions",
33
66
  actions: [{
34
67
  icon: /*#__PURE__*/_jsx(AddIcon, {
@@ -66,7 +99,27 @@ export default function MemberActions({
66
99
  primary: user.approved ? t('team.member.forbidLogin') : t('team.member.allowLogin')
67
100
  })]
68
101
  })
69
- }, "toggle-approval")]
102
+ }, "toggle-approval"), type === 'blocklet' && {
103
+ icon: /*#__PURE__*/_jsx(LogoutIcon, {
104
+ fontSize: "small"
105
+ }),
106
+ text: t('team.member.forceLogout'),
107
+ onClick: e => {
108
+ e.stopPropagation();
109
+ confirmApi.open({
110
+ title: t('team.member.forceLogout'),
111
+ content: t('team.member.forceLogoutDescription'),
112
+ confirmButtonText: t('common.confirm'),
113
+ cancelButtonText: t('common.cancel'),
114
+ onClick: event => event.stopPropagation(),
115
+ onConfirm: async () => {
116
+ await logoutUser();
117
+ await confirmApi.close();
118
+ onRefresh();
119
+ }
120
+ });
121
+ }
122
+ }].filter(Boolean)
70
123
  }), enablePassportIssuance && /*#__PURE__*/_jsx(IssuePassport, {
71
124
  teamDid: teamDid,
72
125
  ownerDid: user.did,
@@ -81,9 +134,12 @@ export default function MemberActions({
81
134
  });
82
135
  }
83
136
  MemberActions.propTypes = {
137
+ type: PropTypes.oneOf(['server', 'blocklet']).isRequired,
84
138
  user: PropTypes.object.isRequired,
85
- onIssuePassport: PropTypes.func
139
+ onIssuePassport: PropTypes.func,
140
+ onRefresh: PropTypes.func
86
141
  };
87
142
  MemberActions.defaultProps = {
88
- onIssuePassport: () => {}
143
+ onIssuePassport: () => {},
144
+ onRefresh: () => {}
89
145
  };
@@ -1,17 +1,15 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
2
  /* eslint-disable jsx-a11y/aria-role */
3
- import { useContext, useState, useEffect } from 'react';
3
+ import { useContext, useState, useEffect, useRef } from 'react';
4
4
  import styled from '@emotion/styled';
5
5
  import isEmpty from 'lodash/isEmpty';
6
6
  import PropTypes from 'prop-types';
7
7
  import classnames from 'classnames';
8
- import Dialog from '@arcblock/ux/lib/Dialog';
9
- import Tooltip from '@mui/material/Tooltip';
10
- import Box from '@mui/material/Box';
11
- import FormControlLabel from '@mui/material/FormControlLabel';
12
- import Checkbox from '@mui/material/Checkbox';
8
+ import { Badge, IconButton, Tooltip, Checkbox, Box, FormControlLabel } from '@mui/material';
9
+ import Dialog, { useConfirm } from '@arcblock/ux/lib/Dialog';
13
10
  import AddIcon from '@mui/icons-material/Add';
14
11
  import LoopIcon from '@mui/icons-material/Loop';
12
+ import ViewListIcon from '@mui/icons-material/ViewList';
15
13
  import Avatar from '@arcblock/did-connect/lib/Avatar';
16
14
  import { LocaleContext } from '@arcblock/ux/lib/Locale/context';
17
15
  import Button from '@arcblock/ux/lib/Button';
@@ -20,11 +18,12 @@ import ExternalIssuerIcon from '@arcblock/icons/lib/ExternalIssuerIcon';
20
18
  import { getTextColor } from '@abtnode/auth/lib/util/create-passport-svg';
21
19
  import Datatable, { getDurableData } from '@arcblock/ux/lib/Datatable';
22
20
  import RelativeTime from '@arcblock/ux/lib/RelativeTime';
21
+ import Toast from '@arcblock/ux/lib/Toast';
23
22
  import { USER_TYPE } from '@abtnode/constant';
24
23
  import { TeamEvents } from '@blocklet/constant';
25
24
  import useUrlState from '@ahooksjs/use-url-state';
26
- import { useMount } from 'ahooks';
27
- import Toast from '@arcblock/ux/lib/Toast';
25
+ import { useMemoizedFn, useMount } from 'ahooks';
26
+ import { UserSessions } from '@blocklet/ui-react';
28
27
  import Tag from '../../tag';
29
28
  import DidAddress from '../../did-address';
30
29
  import { useNodeContext } from '../../contexts/node';
@@ -116,6 +115,29 @@ export default function MemberList({
116
115
  type,
117
116
  createPassportSvg
118
117
  }) {
118
+ const {
119
+ confirmApi,
120
+ confirmHolder
121
+ } = useConfirm({
122
+ sx: {
123
+ '.MuiDialog-paper': {
124
+ borderRadius: 2,
125
+ maxWidth: 1000
126
+ },
127
+ '.ux-dialog_title': {
128
+ fontWeight: 600
129
+ },
130
+ '.ux-dialog_closeButton': {
131
+ p: 1
132
+ },
133
+ '.MuiDialogActions-root': {
134
+ display: {
135
+ xs: 'none',
136
+ md: 'flex'
137
+ }
138
+ }
139
+ }
140
+ });
119
141
  const {
120
142
  appIdList = []
121
143
  } = useBlockletContext();
@@ -188,7 +210,8 @@ export default function MemberList({
188
210
  });
189
211
  const getUsers = () => {
190
212
  const query = {
191
- includeTags: true
213
+ includeTags: true,
214
+ includeUserSessions: type === 'blocklet'
192
215
  };
193
216
  if (search.hideBlocked) {
194
217
  query.approved = true;
@@ -245,6 +268,21 @@ export default function MemberList({
245
268
  useSubscription(TeamEvents.userUpdated, handleUserChange, [search]);
246
269
  useSubscription(TeamEvents.userAdded, handleUserChange, [search]);
247
270
  const isInvitationEnabled = enablePassportIssuance;
271
+ const openUserSessions = useMemoizedFn(user => {
272
+ confirmApi.open({
273
+ title: 'User Sessions',
274
+ content: /*#__PURE__*/_jsx(UserSessions, {
275
+ user: user,
276
+ showAction: false,
277
+ showUser: false
278
+ }),
279
+ onConfirm() {
280
+ confirmApi.close();
281
+ },
282
+ confirmButtonText: t('common.close'),
283
+ showCancelButton: false
284
+ });
285
+ });
248
286
  const columns = [{
249
287
  label: t('common.name'),
250
288
  name: 'fullName',
@@ -310,6 +348,32 @@ export default function MemberList({
310
348
  return providerName;
311
349
  }
312
350
  }
351
+ }, type === 'blocklet' && {
352
+ label: t('team.member.activeUserSessions'),
353
+ name: 'userSessions',
354
+ options: {
355
+ customBodyRenderLite: rowIndex => {
356
+ const user = users[rowIndex];
357
+ return /*#__PURE__*/_jsx(IconButton, {
358
+ onClick: e => {
359
+ e.stopPropagation();
360
+ openUserSessions(user);
361
+ },
362
+ children: /*#__PURE__*/_jsx(Badge, {
363
+ badgeContent: user?.userSessions?.length,
364
+ color: user?.userSessions?.length > 0 ? 'primary' : 'default',
365
+ sx: user?.userSessions?.length > 0 ? {} : {
366
+ '.MuiBadge-badge': {
367
+ backgroundColor: 'grey',
368
+ color: 'white'
369
+ }
370
+ },
371
+ showZero: true,
372
+ children: /*#__PURE__*/_jsx(ViewListIcon, {})
373
+ })
374
+ });
375
+ }
376
+ }
313
377
  }, {
314
378
  label: t('common.actions'),
315
379
  name: '',
@@ -323,16 +387,20 @@ export default function MemberList({
323
387
  permission: inService ? '' : 'mutate_team',
324
388
  role: inService ? BlockletAdminRoles : [],
325
389
  children: /*#__PURE__*/_jsx(Actions, {
390
+ type: type,
326
391
  user: x,
327
392
  onIssuePassport: () => setMemberDialog({
328
393
  ...x,
329
394
  initTab: 'issuances'
395
+ }),
396
+ onRefresh: () => handleUserChange({
397
+ teamDid
330
398
  })
331
399
  })
332
400
  });
333
401
  }
334
402
  }
335
- }];
403
+ }].filter(Boolean);
336
404
  const customButtons = [];
337
405
  if (isInvitationEnabled) {
338
406
  customButtons.push( /*#__PURE__*/_jsxs(Button, {
@@ -440,17 +508,20 @@ export default function MemberList({
440
508
  }));
441
509
  }
442
510
  };
511
+ const datatableRef = useRef(null);
443
512
  const tableOptions = {
444
513
  sort: false,
445
514
  download: false,
446
515
  filter: false,
447
516
  print: false,
448
517
  expandableRowsOnClick: true,
449
- onRowClick(e, {
518
+ onRowClick(row, {
450
519
  dataIndex
451
- }) {
452
- const x = users[dataIndex];
453
- setMemberDialog(x);
520
+ }, e) {
521
+ if (datatableRef.current?.contains(e.target)) {
522
+ const x = users[dataIndex];
523
+ setMemberDialog(x);
524
+ }
454
525
  },
455
526
  page: search.page - 1,
456
527
  rowsPerPage: search.pageSize,
@@ -458,7 +529,7 @@ export default function MemberList({
458
529
  searchDebounceTime: 600
459
530
  };
460
531
  return /*#__PURE__*/_jsxs(Div, {
461
- children: [/*#__PURE__*/_jsxs(Box, {
532
+ children: [confirmHolder, /*#__PURE__*/_jsxs(Box, {
462
533
  className: "main",
463
534
  display: "flex",
464
535
  sx: {
@@ -483,6 +554,7 @@ export default function MemberList({
483
554
  }, x.name))
484
555
  })
485
556
  }), /*#__PURE__*/_jsx("div", {
557
+ ref: datatableRef,
486
558
  className: "right",
487
559
  children: /*#__PURE__*/_jsx(Datatable, {
488
560
  className: "main-table",
package/lib/actions.js CHANGED
@@ -66,7 +66,9 @@ function Actions(_ref) {
66
66
  keepMounted: true,
67
67
  open: open,
68
68
  onClose: onClose,
69
- PaperProps: {},
69
+ slotProps: {
70
+ paper: {}
71
+ },
70
72
  children: actions.map((action, index) => {
71
73
  if (typeof action === 'function') {
72
74
  return action({
@@ -342,13 +342,17 @@ function BlockletActions(_ref) {
342
342
  name: t('common.restart'),
343
343
  handler: createHandler('restart', node.api.restartBlocklet, true),
344
344
  disabled: disableStart || blocklet.status !== 'running'
345
- }, {
346
- action: 'reload',
347
- icon: _icons.default.Reload,
348
- name: t('common.reload'),
349
- handler: createHandler('reload', node.api.reloadBlocklet),
350
- disabled: disableStart || blocklet.status !== 'running'
351
- }, (0, _util2.isDownloading)(blocklet.status) ? cancelDownloadAction : removeAction, {
345
+ },
346
+ // hidden reload: https://github.com/ArcBlock/blocklet-server/issues/8655
347
+ // {
348
+ // action: 'reload',
349
+ // icon: Icons.Reload,
350
+ // name: t('common.reload'),
351
+ // handler: createHandler('reload', node.api.reloadBlocklet),
352
+ // disabled: disableStart || blocklet.status !== 'running',
353
+ // },
354
+
355
+ (0, _util2.isDownloading)(blocklet.status) ? cancelDownloadAction : removeAction, {
352
356
  separator: true
353
357
  }, {
354
358
  onlyInMenu: true,
@@ -78,6 +78,13 @@ function AddRule(_ref) {
78
78
  if (params.type === _constant.ROUTING_RULE_TYPES.GENERAL_REWRITE) {
79
79
  rule.to.url = (0, _urlPathFriendly.default)(params.url);
80
80
  }
81
+ if (params.type === _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE) {
82
+ rule.to.response = {
83
+ status: 200,
84
+ contentType: params.responseType,
85
+ body: params.responseBody
86
+ };
87
+ }
81
88
  await api.addRoutingRule({
82
89
  input: {
83
90
  id: siteId,
@@ -143,6 +150,9 @@ function AddRule(_ref) {
143
150
  if (params.type === _constant.ROUTING_RULE_TYPES.GENERAL_REWRITE && !params.url) {
144
151
  disable = true;
145
152
  }
153
+ if (params.type === _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE && (!params.responseType || !params.responseBody)) {
154
+ disable = true;
155
+ }
146
156
  if (!e.target.value.trim()) {
147
157
  disable = true;
148
158
  setError(t('router.validation.pathPrefixRequired'));
@@ -175,6 +185,8 @@ function AddRule(_ref) {
175
185
  componentId: '',
176
186
  pageGroup: '',
177
187
  redirectCode: 302,
188
+ responseType: 'text/plain',
189
+ responseBody: '',
178
190
  __disableConfirm: true
179
191
  },
180
192
  onConfirm,
@@ -204,17 +204,63 @@ function ConfigRoutingRule(_ref) {
204
204
  marginBottom: 32
205
205
  },
206
206
  onChange: e => {
207
+ const value = e.target.value.trim();
207
208
  setParams(_objectSpread(_objectSpread({}, params), {}, {
208
209
  url: e.target.value,
209
- __disableConfirm: !e.target.value.trim()
210
+ __disableConfirm: !value
210
211
  }));
211
- if (!e.target.value.trim()) {
212
+ if (!value) {
212
213
  setError(t('router.validation.rewriteUrlRequired'));
213
214
  } else {
214
215
  setError('');
215
216
  }
216
217
  }
217
- }, "url")]
218
+ }, "url"), params.type === _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE && [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
219
+ select: true,
220
+ label: t('router.rule.add.responseType'),
221
+ autoComplete: "off",
222
+ variant: "outlined",
223
+ name: "responseType",
224
+ fullWidth: true,
225
+ value: params.responseType,
226
+ onChange: e => setParams(_objectSpread(_objectSpread({}, params), {}, {
227
+ responseType: e.target.value
228
+ })),
229
+ style: {
230
+ marginBottom: 32
231
+ },
232
+ SelectProps: {},
233
+ children: _constant.ROUTING_RESPONSE_TYPES.map(x => /*#__PURE__*/(0, _jsxRuntime.jsx)(_MenuItem.default, {
234
+ value: x.value,
235
+ children: x.text
236
+ }, x.value))
237
+ }, "responseType"), /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
238
+ label: t('router.rule.add.responseBody'),
239
+ autoComplete: "off",
240
+ variant: "outlined",
241
+ name: "responseBody",
242
+ "data-cy": "response-body-input",
243
+ fullWidth: true,
244
+ multiline: true,
245
+ minRows: 3,
246
+ value: params.responseBody,
247
+ helperText: t('router.rule.add.responseBodyTip'),
248
+ style: {
249
+ marginBottom: 32
250
+ },
251
+ onChange: e => {
252
+ const value = e.target.value.trim();
253
+ setParams(_objectSpread(_objectSpread({}, params), {}, {
254
+ responseBody: e.target.value,
255
+ __disableConfirm: !value
256
+ }));
257
+ if (!value) {
258
+ setError(t('router.rule.add.responseBodyRequired'));
259
+ } else {
260
+ setError('');
261
+ }
262
+ }
263
+ }, "response-body")]]
218
264
  });
219
265
  }
220
266
  ConfigRoutingRule.propTypes = {
@@ -234,6 +280,9 @@ ConfigRoutingRule.defaultProps = {
234
280
  }, {
235
281
  name: 'Rewrite - Route traffic without redirect',
236
282
  value: _constant.ROUTING_RULE_TYPES.GENERAL_REWRITE
283
+ }, {
284
+ name: 'Response - Response with provided content',
285
+ value: _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE
237
286
  }, {
238
287
  name: 'Component - Pass traffic to blocklet component',
239
288
  value: _constant.ROUTING_RULE_TYPES.COMPONENT
@@ -29,6 +29,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
29
29
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
30
30
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
31
31
  function UpdateRule(_ref) {
32
+ var _to$response, _to$response2;
32
33
  let {
33
34
  id: ruleId,
34
35
  from,
@@ -81,6 +82,13 @@ function UpdateRule(_ref) {
81
82
  if (params.type === _constant.ROUTING_RULE_TYPES.GENERAL_REWRITE) {
82
83
  rule.to.url = (0, _urlPathFriendly.default)(params.url);
83
84
  }
85
+ if (params.type === _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE) {
86
+ rule.to.response = {
87
+ status: 200,
88
+ contentType: params.responseType,
89
+ body: params.responseBody
90
+ };
91
+ }
84
92
  await api.updateRoutingRule({
85
93
  input: {
86
94
  id: siteId,
@@ -135,6 +143,9 @@ function UpdateRule(_ref) {
135
143
  if (params.type === _constant.ROUTING_RULE_TYPES.GENERAL_REWRITE && !params.url) {
136
144
  disable = true;
137
145
  }
146
+ if (params.type === _constant.ROUTING_RULE_TYPES.DIRECT_RESPONSE && (!params.responseType || !params.responseBody)) {
147
+ disable = true;
148
+ }
138
149
  if (!e.target.value.trim()) {
139
150
  disable = true;
140
151
  setError(t('router.validation.pathPrefixRequired'));
@@ -169,6 +180,8 @@ function UpdateRule(_ref) {
169
180
  componentId: to.componentId || '',
170
181
  pageGroup: to.pageGroup || '',
171
182
  url: to.url || '',
183
+ responseType: ((_to$response = to.response) === null || _to$response === void 0 ? void 0 : _to$response.contentType) || '',
184
+ responseBody: (((_to$response2 = to.response) === null || _to$response2 === void 0 ? void 0 : _to$response2.body) || '').replace(/\\"/g, '"'),
172
185
  __disableConfirm: false
173
186
  },
174
187
  onConfirm,