@abtnode/ux 1.16.14-beta-c308dc3b → 1.16.14-beta-cb53c14b

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 (202) hide show
  1. package/es/actions.js +97 -0
  2. package/es/analytics/card.js +92 -0
  3. package/es/analytics/chart.js +96 -0
  4. package/es/analytics/cpu.js +36 -0
  5. package/es/analytics/disk.js +111 -0
  6. package/es/analytics/memory.js +72 -0
  7. package/es/analytics/runtime.js +173 -0
  8. package/es/analytics/traffic.js +259 -0
  9. package/es/blocklet/access/config-access.js +307 -0
  10. package/es/blocklet/access/index.js +216 -0
  11. package/es/blocklet/actions.js +474 -0
  12. package/es/blocklet/add-cert.js +177 -0
  13. package/es/blocklet/agreement-app.js +21 -0
  14. package/es/blocklet/agreement.js +127 -0
  15. package/es/blocklet/app-avatar.js +57 -0
  16. package/es/blocklet/audit-logs.js +259 -0
  17. package/es/blocklet/blocklet-source.js +48 -0
  18. package/es/blocklet/bundle-avatar.js +64 -0
  19. package/es/blocklet/component/add.js +1308 -0
  20. package/es/blocklet/component/configuration.js +122 -0
  21. package/es/blocklet/component/delete.js +134 -0
  22. package/es/blocklet/component/environment.js +370 -0
  23. package/es/blocklet/component/index.js +975 -0
  24. package/es/blocklet/component/line.js +20 -0
  25. package/es/blocklet/component/navigation/locale-tabs.js +225 -0
  26. package/es/blocklet/component/navigation/navigation-actions.js +112 -0
  27. package/es/blocklet/component/navigation/navigation-dialog.js +607 -0
  28. package/es/blocklet/component/navigation/navigation-preview.js +101 -0
  29. package/es/blocklet/component/navigation/simple-select.js +124 -0
  30. package/es/blocklet/component/select-store.js +155 -0
  31. package/es/blocklet/component/setting.js +109 -0
  32. package/es/blocklet/component/sortable-tree.js +126 -0
  33. package/es/blocklet/component/space-connector.js +199 -0
  34. package/es/blocklet/component/space-selector.js +178 -0
  35. package/es/blocklet/component/start.js +101 -0
  36. package/es/blocklet/component/store-blocklet-list.js +200 -0
  37. package/es/blocklet/component/switch-control.js +57 -0
  38. package/es/blocklet/config-navigation.js +331 -0
  39. package/es/blocklet/configuration.js +603 -0
  40. package/es/blocklet/disk-info.js +75 -0
  41. package/es/blocklet/icons.js +18 -0
  42. package/es/blocklet/install-from-url.js +337 -0
  43. package/es/blocklet/log.js +90 -0
  44. package/es/blocklet/migration.js +149 -0
  45. package/es/blocklet/mode.js +19 -0
  46. package/es/blocklet/notification/email.js +257 -0
  47. package/es/blocklet/notification/index.js +49 -0
  48. package/es/blocklet/oauth/auth0.js +145 -0
  49. package/es/blocklet/oauth/common-settings.js +133 -0
  50. package/es/blocklet/oauth/federated-detail-dialog.js +175 -0
  51. package/es/blocklet/oauth/federated-invite-dialog.js +83 -0
  52. package/es/blocklet/oauth/federated-join-dialog.js +111 -0
  53. package/es/blocklet/oauth/federated-site-list.js +338 -0
  54. package/es/blocklet/oauth/federated.js +81 -0
  55. package/es/blocklet/oauth/index.js +69 -0
  56. package/es/blocklet/overview.js +293 -0
  57. package/es/blocklet/page-group.js +19 -0
  58. package/es/blocklet/preferences/app-sk.js +142 -0
  59. package/es/blocklet/preferences/index.js +305 -0
  60. package/es/blocklet/purchase/common.js +95 -0
  61. package/es/blocklet/purchase/component-purchase.js +237 -0
  62. package/es/blocklet/purchase/index.js +4 -0
  63. package/es/blocklet/router/action/add-domain-alias.js +167 -0
  64. package/es/blocklet/router/action/add-rule.js +211 -0
  65. package/es/blocklet/router/action/config-routing-rule.js +232 -0
  66. package/es/blocklet/router/action/delete-domain-alias.js +99 -0
  67. package/es/blocklet/router/action/delete-rule.js +108 -0
  68. package/es/blocklet/router/action/update-rule.js +209 -0
  69. package/es/blocklet/router/domain-actions.js +64 -0
  70. package/es/blocklet/router/domain-status.js +88 -0
  71. package/es/blocklet/router/rule-actions.js +66 -0
  72. package/es/blocklet/router/rule-list.js +190 -0
  73. package/es/blocklet/router/util.js +131 -0
  74. package/es/blocklet/runtime-info.js +68 -0
  75. package/es/blocklet/status.js +91 -0
  76. package/es/blocklet/storage/action.js +134 -0
  77. package/es/blocklet/storage/backups.js +241 -0
  78. package/es/blocklet/storage/connect-to.js +373 -0
  79. package/es/blocklet/storage/connected.js +198 -0
  80. package/es/blocklet/storage/delete.js +113 -0
  81. package/es/blocklet/storage/disconnect.js +243 -0
  82. package/es/blocklet/storage/index.js +19 -0
  83. package/es/blocklet/storage/item.js +558 -0
  84. package/es/blocklet/storage/preview-nft.js +286 -0
  85. package/es/blocklet/transfer-owner.js +198 -0
  86. package/es/blocklet/types.js +18 -0
  87. package/es/blocklet/util.js +145 -0
  88. package/es/blocklet/version.js +141 -0
  89. package/es/card-selector.js +134 -0
  90. package/es/certificate.js +105 -0
  91. package/es/chain.js +13 -0
  92. package/es/click-to-copy.js +22 -0
  93. package/es/confirm.js +149 -0
  94. package/es/contexts/audit-log.js +152 -0
  95. package/es/contexts/blocklet.js +10 -0
  96. package/es/contexts/deleting-blocklets.js +70 -0
  97. package/es/contexts/node.js +17 -0
  98. package/es/contexts/session.js +8 -0
  99. package/es/contexts/team.js +10 -0
  100. package/es/delete-confirm.js +121 -0
  101. package/es/did-address.js +46 -0
  102. package/es/dot.js +14 -0
  103. package/es/exchange-passport.js +102 -0
  104. package/es/form/form-select-input.js +184 -0
  105. package/es/form/form-text-input.js +178 -0
  106. package/es/form/form-wrapper.js +88 -0
  107. package/es/form/input-triggers.js +98 -0
  108. package/es/form/required.js +8 -0
  109. package/es/hooks/blocklet.js +229 -0
  110. package/es/hooks/confirm.js +90 -0
  111. package/es/hooks/mobile-width.js +11 -0
  112. package/es/hooks/url-evaluation.js +155 -0
  113. package/es/hooks/use-app-logo.js +16 -0
  114. package/es/hooks/use-backup-progress.js +31 -0
  115. package/es/hooks/use-blocklet-info-for-connect-did-spaces.js +50 -0
  116. package/es/hooks/use-bundle-logo.js +27 -0
  117. package/es/hooks/use-navigation.js +347 -0
  118. package/es/hooks/use-passport-id.js +14 -0
  119. package/es/hooks/use-subscription.js +22 -0
  120. package/es/icons/empty-space-nft.svg +59 -0
  121. package/es/icons/empty-spaces-nft.svg +58 -0
  122. package/es/icons/long-arrow.svg +5 -0
  123. package/es/icons/space-connected.svg +3 -0
  124. package/es/icons/space-disconnect.svg +3 -0
  125. package/es/index.js +3 -0
  126. package/es/invitation/invitation-app.js +58 -0
  127. package/es/invitation/invitation-login.js +68 -0
  128. package/es/invitation/invitation-passport.js +144 -0
  129. package/es/invitation/invitation-receive.js +138 -0
  130. package/es/invitation/invitation-success.js +93 -0
  131. package/es/invitation/invitation-user.js +90 -0
  132. package/es/invitation/invitation.js +90 -0
  133. package/es/issue-passport.js +142 -0
  134. package/es/launch-blocklet/content-layout.js +58 -0
  135. package/es/launch-blocklet/page-header.js +43 -0
  136. package/es/layout/addon.js +114 -0
  137. package/es/layout/feedback.js +55 -0
  138. package/es/locales/en.js +1534 -0
  139. package/es/locales/index.js +9 -0
  140. package/es/locales/zh.js +1537 -0
  141. package/es/logs/clock.js +11 -0
  142. package/es/logs/download.js +132 -0
  143. package/es/logs/log-terminal.js +253 -0
  144. package/es/lost-passport.js +452 -0
  145. package/es/nav-logo.js +219 -0
  146. package/es/passport-tag.js +43 -0
  147. package/es/permission.js +57 -0
  148. package/es/relative-time.js +53 -0
  149. package/es/result-message.js +11 -0
  150. package/es/schema-form/color-input.js +98 -0
  151. package/es/schema-form/common-prop-types.js +13 -0
  152. package/es/schema-form/index.js +215 -0
  153. package/es/schema-form/passport-input.js +54 -0
  154. package/es/schema-form/text-input.js +57 -0
  155. package/es/store/add.js +179 -0
  156. package/es/store/delete.js +96 -0
  157. package/es/store/item.js +76 -0
  158. package/es/subscription.js +144 -0
  159. package/es/table-icons.js +34 -0
  160. package/es/table.js +52 -0
  161. package/es/tag.js +21 -0
  162. package/es/team/members/actions.js +89 -0
  163. package/es/team/members/index.js +636 -0
  164. package/es/team/members/invitations.js +188 -0
  165. package/es/team/members/invite-member.js +208 -0
  166. package/es/team/members/issue-passport.js +152 -0
  167. package/es/team/members/member.js +408 -0
  168. package/es/team/members/passport-issuances.js +155 -0
  169. package/es/team/members/passports.js +364 -0
  170. package/es/team/members/toggle-user-approval.js +122 -0
  171. package/es/team/members/transfer-node.js +256 -0
  172. package/es/team/members/util.js +14 -0
  173. package/es/team/passports/color.js +126 -0
  174. package/es/team/passports/detail.js +312 -0
  175. package/es/team/passports/index.js +282 -0
  176. package/es/team/passports/mutate-role.js +198 -0
  177. package/es/team/passports/trusted-factories.js +221 -0
  178. package/es/team/passports/trusted-factory.js +343 -0
  179. package/es/team/passports/trusted-issuer.js +296 -0
  180. package/es/team/passports/trusted-issuers.js +226 -0
  181. package/es/team/search-input.js +46 -0
  182. package/es/team/styles/dialog.js +72 -0
  183. package/es/team/styles/list-header.js +31 -0
  184. package/es/util/api.js +6 -0
  185. package/es/util/constants.js +2 -0
  186. package/es/util/index.js +598 -0
  187. package/es/util/mode.js +4 -0
  188. package/es/util/space-gateway.js +51 -0
  189. package/es/util/spaces.js +151 -0
  190. package/es/who-can-access/config.js +38 -0
  191. package/es/wrap-locale.js +15 -0
  192. package/lib/blocklet/component/space-connector.js +1 -1
  193. package/lib/blocklet/component/space-selector.js +1 -1
  194. package/lib/blocklet/storage/backups.js +1 -1
  195. package/lib/blocklet/storage/connect-to.js +1 -1
  196. package/lib/blocklet/storage/connected.js +1 -1
  197. package/lib/blocklet/storage/disconnect.js +1 -1
  198. package/lib/blocklet/storage/index.js +1 -1
  199. package/lib/blocklet/storage/item.js +1 -1
  200. package/lib/invitation/invitation-receive.js +1 -1
  201. package/lib/team/passports/trusted-factory.js +1 -1
  202. package/package.json +81 -18
@@ -0,0 +1,259 @@
1
+ /* eslint-disable react/prop-types */
2
+ /* eslint-disable react-hooks/exhaustive-deps */
3
+ import { useEffect, useState } from 'react';
4
+ import dayjs from '@abtnode/util/lib/dayjs';
5
+ import nthArg from 'lodash/nthArg';
6
+ import joinUrl from 'url-join';
7
+ import filesize from 'filesize';
8
+ import useAsyncRetry from 'react-use/lib/useAsyncRetry';
9
+ import Iframe from 'react-iframe';
10
+ import Alert from '@mui/material/Alert';
11
+ import Spinner from '@mui/material/CircularProgress';
12
+ import Grid from '@mui/material/Grid';
13
+ import Typography from '@mui/material/Typography';
14
+ import Button from '@mui/material/Button';
15
+ import IconButton from '@mui/material/IconButton';
16
+ import Popover from '@mui/material/Popover';
17
+ import ViewIcon from '@mui/icons-material/LaunchOutlined';
18
+ import { DateRangePicker } from 'mui-daterange-picker';
19
+ import { DatePicker } from '@mui/x-date-pickers';
20
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
21
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
22
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
23
+ import { WELLKNOWN_SERVICE_PATH_PREFIX } from '@abtnode/constant';
24
+ import { startOfWeek, endOfWeek, addWeeks, startOfMonth, endOfMonth, addMonths, startOfYear, endOfYear, addYears } from 'date-fns';
25
+ import { formatError, formatToDate } from '../util';
26
+ import { useNodeContext } from '../contexts/node';
27
+ import Chart from './chart';
28
+ import { jsx as _jsx } from "react/jsx-runtime";
29
+ import { jsxs as _jsxs } from "react/jsx-runtime";
30
+ const noop = nthArg(0);
31
+ export const getDefaultRanges = (date, locale) => [{
32
+ label: 'This Week',
33
+ startDate: startOfWeek(date, {
34
+ locale
35
+ }),
36
+ endDate: endOfWeek(date, {
37
+ locale
38
+ })
39
+ }, {
40
+ label: 'Last Week',
41
+ startDate: startOfWeek(addWeeks(date, -1), {
42
+ locale
43
+ }),
44
+ endDate: endOfWeek(addWeeks(date, -1), {
45
+ locale
46
+ })
47
+ }, {
48
+ label: 'Last 7 Days',
49
+ startDate: addWeeks(date, -1),
50
+ endDate: date
51
+ }, {
52
+ label: 'This Month',
53
+ startDate: startOfMonth(date),
54
+ endDate: endOfMonth(date)
55
+ }, {
56
+ label: 'Last Month',
57
+ startDate: startOfMonth(addMonths(date, -1)),
58
+ endDate: endOfMonth(addMonths(date, -1))
59
+ }, {
60
+ label: 'This Year',
61
+ startDate: startOfYear(date),
62
+ endDate: endOfYear(date)
63
+ }, {
64
+ label: 'Last Year',
65
+ startDate: startOfYear(addYears(date, -1)),
66
+ endDate: endOfYear(addYears(date, -1))
67
+ }];
68
+ export default function TrafficInsights({
69
+ client,
70
+ did
71
+ }) {
72
+ const maxDate = dayjs().subtract(1, 'day').toDate();
73
+ const {
74
+ info,
75
+ inService
76
+ } = useNodeContext();
77
+ const {
78
+ t,
79
+ locale
80
+ } = useLocaleContext();
81
+ const [anchorEl, setAnchorEl] = useState(null);
82
+ const [loaded, setLoaded] = useState(false);
83
+ const [date, setDate] = useState(maxDate);
84
+ const [dateRange, setDateRange] = useState({
85
+ startDate: dayjs().subtract(30, 'day').toDate(),
86
+ endDate: maxDate
87
+ });
88
+ const data = useAsyncRetry(async () => {
89
+ const result = await client.getTrafficInsights({
90
+ input: {
91
+ did,
92
+ startDate: dayjs(dateRange.startDate).format('YYYY-MM-DD'),
93
+ endDate: dayjs(dateRange.endDate).format('YYYY-MM-DD')
94
+ }
95
+ });
96
+ return result.list;
97
+ });
98
+ useEffect(() => {
99
+ if (data.loading) {
100
+ return;
101
+ }
102
+ if (dateRange.startDate && dateRange.endDate) {
103
+ data.retry();
104
+ }
105
+ }, [dateRange]);
106
+ const onTriggerClick = e => {
107
+ if (anchorEl) {
108
+ setAnchorEl(null);
109
+ } else {
110
+ setAnchorEl(e.currentTarget);
111
+ }
112
+ };
113
+ const list = data.value || [];
114
+ const {
115
+ loading,
116
+ error
117
+ } = data;
118
+ if (!list.length && loading) {
119
+ return /*#__PURE__*/_jsx(Spinner, {});
120
+ }
121
+ if (error) {
122
+ return /*#__PURE__*/_jsx(Alert, {
123
+ severity: "error",
124
+ children: formatError(error)
125
+ });
126
+ }
127
+ const metrics = {
128
+ totalRequests: noop,
129
+ validRequests: noop,
130
+ failedRequests: noop,
131
+ uniqueVisitors: noop,
132
+ uniqueFiles: noop,
133
+ uniqueReferrers: noop,
134
+ uniqueNotFound: noop,
135
+ uniqueStaticFiles: noop,
136
+ logSize: filesize,
137
+ bandwidth: filesize
138
+ };
139
+ const charts = Object.keys(metrics).map(key => ({
140
+ id: `${key}_chart`,
141
+ title: t(`analytics.traffic.${key}`),
142
+ current: list.length ? metrics[key](list[0][key]) : 0,
143
+ data: list.map(v => ({
144
+ date: v.date,
145
+ value: v[key]
146
+ })).reverse(),
147
+ dateFn: noop,
148
+ valueFn: metrics[key]
149
+ }));
150
+ const open = Boolean(anchorEl);
151
+ const id = open ? 'date-range-picker-popover' : undefined;
152
+
153
+ // eslint-disable-next-line no-nested-ternary
154
+ const pathPrefix = inService ? WELLKNOWN_SERVICE_PATH_PREFIX : process.env.NODE_ENV === 'production' ? info.routing.adminPath : '';
155
+ const breakdownUrl = joinUrl(window.location.origin, pathPrefix, `/api/analytics/traffic?date=${dayjs(date).format('YYYY-MM-DD')}&did=${did}`);
156
+ const onRangeChange = range => {
157
+ setDateRange(range);
158
+ setAnchorEl(null);
159
+ };
160
+ const onDateChange = newDate => {
161
+ setDate(newDate.toDate());
162
+ setLoaded(false);
163
+ };
164
+ const onOpenBreakdown = () => {
165
+ window.open(breakdownUrl);
166
+ };
167
+ return /*#__PURE__*/_jsxs("div", {
168
+ children: [/*#__PURE__*/_jsxs(Typography, {
169
+ component: "div",
170
+ variant: "h5",
171
+ className: "page-header",
172
+ color: "textPrimary",
173
+ style: {
174
+ fontSize: 18,
175
+ fontWeight: 'bold'
176
+ },
177
+ mb: 2,
178
+ children: [t('analytics.trend'), /*#__PURE__*/_jsxs(Button, {
179
+ onClick: onTriggerClick,
180
+ variant: "outlined",
181
+ size: "small",
182
+ color: "secondary",
183
+ children: [formatToDate(dateRange.startDate, locale), " - ", formatToDate(dateRange.endDate, locale)]
184
+ })]
185
+ }), /*#__PURE__*/_jsx(Popover, {
186
+ id: id,
187
+ open: open,
188
+ anchorEl: anchorEl,
189
+ onClose: () => setAnchorEl(null),
190
+ anchorOrigin: {
191
+ vertical: 'bottom',
192
+ horizontal: 'left'
193
+ },
194
+ children: /*#__PURE__*/_jsx(DateRangePicker, {
195
+ open: true,
196
+ toggle: onTriggerClick,
197
+ maxDate: maxDate,
198
+ definedRanges: getDefaultRanges(date),
199
+ onChange: onRangeChange
200
+ })
201
+ }), /*#__PURE__*/_jsx(Grid, {
202
+ container: true,
203
+ spacing: 4,
204
+ children: charts.map(x => /*#__PURE__*/_jsx(Grid, {
205
+ item: true,
206
+ lg: 3,
207
+ md: 6,
208
+ sm: 6,
209
+ xs: 12,
210
+ children: /*#__PURE__*/_jsx(Chart, {
211
+ ...x
212
+ })
213
+ }, x.id))
214
+ }), /*#__PURE__*/_jsxs(Typography, {
215
+ component: "div",
216
+ variant: "h5",
217
+ className: "page-header",
218
+ color: "textPrimary",
219
+ style: {
220
+ fontSize: 18,
221
+ fontWeight: 'bold'
222
+ },
223
+ mt: 4,
224
+ mb: 1,
225
+ children: [t('analytics.detail'), /*#__PURE__*/_jsxs("span", {
226
+ children: [loaded && /*#__PURE__*/_jsx(IconButton, {
227
+ onClick: onOpenBreakdown,
228
+ style: {
229
+ marginRight: 32
230
+ },
231
+ children: /*#__PURE__*/_jsx(ViewIcon, {})
232
+ }), /*#__PURE__*/_jsx(LocalizationProvider, {
233
+ dateAdapter: AdapterDayjs,
234
+ children: /*#__PURE__*/_jsx(DatePicker, {
235
+ disableFuture: true,
236
+ format: "ll",
237
+ value: dayjs(date),
238
+ onChange: onDateChange,
239
+ slotProps: {
240
+ textField: {
241
+ size: 'small'
242
+ }
243
+ }
244
+ })
245
+ })]
246
+ })]
247
+ }), /*#__PURE__*/_jsx(Iframe, {
248
+ url: breakdownUrl,
249
+ width: "100%",
250
+ height: "100%",
251
+ frameBorder: 0,
252
+ onLoad: () => setLoaded(true),
253
+ styles: {
254
+ border: 0,
255
+ minHeight: '400vh'
256
+ }
257
+ })]
258
+ });
259
+ }
@@ -0,0 +1,307 @@
1
+ import { useState } from 'react';
2
+ import get from 'lodash/get';
3
+ import styled from '@emotion/styled';
4
+ import PropTypes from 'prop-types';
5
+ import TextField from '@mui/material/TextField';
6
+ import MenuItem from '@mui/material/MenuItem';
7
+ import IconButton from '@mui/material/IconButton';
8
+ import Box from '@mui/material/Box';
9
+ import EditIcon from '@mui/icons-material/Edit';
10
+ import useTheme from '@mui/material/styles/useTheme';
11
+ import GroupIcon from '@mui/icons-material/Group';
12
+ import Chip from '@mui/material/Chip';
13
+ import ListItemText from '@mui/material/ListItemText';
14
+ import Checkbox from '@mui/material/Checkbox';
15
+ import { BLOCKLET_CONFIGURABLE_KEY } from '@blocklet/constant';
16
+ import { WHO_CAN_ACCESS, NODE_SERVICES, WHO_CAN_ACCESS_PREFIX_ROLES } from '@abtnode/constant';
17
+ import { getDisplayName, findServiceFromMeta, getRolesFromAuthConfig } from '@blocklet/meta/lib/util';
18
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
19
+ import Dialog from '@arcblock/ux/lib/Dialog';
20
+ import Button from '@arcblock/ux/lib/Button';
21
+ import Spinner from '@mui/material/CircularProgress';
22
+ import Toast from '@arcblock/ux/lib/Toast';
23
+ import { useNodeContext } from '../../contexts/node';
24
+ import { useTeamContext } from '../../contexts/team';
25
+ import { isInstalling, formatError } from '../../util';
26
+ import AccessConfig from '../../who-can-access/config';
27
+ import { jsx as _jsx } from "react/jsx-runtime";
28
+ import { jsxs as _jsxs } from "react/jsx-runtime";
29
+ import { Fragment as _Fragment } from "react/jsx-runtime";
30
+ const CONFIG_ROLE = 'roles';
31
+ const Configs = [...AccessConfig, {
32
+ value: CONFIG_ROLE,
33
+ icon: GroupIcon,
34
+ title: {
35
+ zh: '指定通行证可访问',
36
+ en: 'Accessible to selected passports'
37
+ },
38
+ description: {
39
+ zh: '只有指定的通行证可以访问',
40
+ en: 'Only specified passports can access'
41
+ }
42
+ }];
43
+ const getAccess = (whoCanAccess, roleStore) => {
44
+ if (whoCanAccess && whoCanAccess.startsWith(WHO_CAN_ACCESS_PREFIX_ROLES)) {
45
+ const roleNames = getRolesFromAuthConfig({
46
+ whoCanAccess
47
+ });
48
+ const filterRoles = roleStore.filter(x => roleNames.includes(x.name));
49
+ return {
50
+ access: CONFIG_ROLE,
51
+ roles: filterRoles
52
+ };
53
+ }
54
+ return {
55
+ access: whoCanAccess,
56
+ roles: []
57
+ };
58
+ };
59
+ export const getComponentWhoCanAccess = (component, app, {
60
+ roles = []
61
+ } = {}) => {
62
+ const access = (component.configs || []).find(x => x.key === BLOCKLET_CONFIGURABLE_KEY.COMPONENT_ACCESS_WHO);
63
+ if (access) {
64
+ return getAccess(access.value, roles);
65
+ }
66
+ if (app && get(app, 'settings.whoCanAccess') && get(app, 'settings.whoCanAccess') !== WHO_CAN_ACCESS.ALL) {
67
+ return getAccess(get(app, 'settings.whoCanAccess'), roles);
68
+ }
69
+ const service = findServiceFromMeta(component.meta, NODE_SERVICES.AUTH);
70
+ if (get(service, 'config.whoCanAccess')) {
71
+ return getAccess(service.config.whoCanAccess, roles);
72
+ }
73
+ return {
74
+ access: WHO_CAN_ACCESS.ALL,
75
+ roles: []
76
+ };
77
+ };
78
+ export default function ConfigAccess({
79
+ blocklet,
80
+ ancestors,
81
+ children
82
+ }) {
83
+ const theme = useTheme();
84
+ const [showDialog, setShowDialog] = useState('');
85
+ const {
86
+ t,
87
+ locale
88
+ } = useLocaleContext();
89
+ const {
90
+ api
91
+ } = useNodeContext();
92
+ const {
93
+ roles: roleList
94
+ } = useTeamContext();
95
+ const [loading, setLoading] = useState('');
96
+ const root = ancestors[0] || blocklet;
97
+ const {
98
+ access: defaultValue,
99
+ roles: defaultRoles
100
+ } = getComponentWhoCanAccess(blocklet, root, {
101
+ roles: roleList
102
+ });
103
+ const [whoCanAccess, setWhoCanAccess] = useState(defaultValue);
104
+ const [roles, setRoles] = useState(defaultRoles);
105
+ const dids = [...ancestors.map(x => x.meta.did), blocklet.meta.did];
106
+ const iconStyle = {
107
+ marginRight: 4,
108
+ fontSize: 18,
109
+ verticalAlign: 'text-bottom',
110
+ color: theme.palette.text.secondary
111
+ };
112
+ const componentName = ancestors.concat(blocklet).map(x => getDisplayName(x, true)).join(' / ');
113
+ if (isInstalling(blocklet.status)) {
114
+ return null;
115
+ }
116
+ if (blocklet.status === 'unknown' && isInstalling(blocklet.status)) {
117
+ return null;
118
+ }
119
+ const onClose = () => {
120
+ setShowDialog(false);
121
+ };
122
+ const onOpen = e => {
123
+ e.stopPropagation();
124
+ // eslint-disable-next-line no-unused-expressions
125
+ setShowDialog(true);
126
+ };
127
+ const onWhoCanAccessChange = e => {
128
+ const {
129
+ value
130
+ } = e.target;
131
+ setWhoCanAccess(value);
132
+ };
133
+ const onRolesChange = e => {
134
+ setRoles(roleList.filter(x => (e.target.value || []).includes(x.name)));
135
+ };
136
+ const onConfirm = async () => {
137
+ if (loading) {
138
+ return;
139
+ }
140
+ setLoading(true);
141
+ try {
142
+ let value = whoCanAccess;
143
+ if (value === CONFIG_ROLE) {
144
+ value = `${WHO_CAN_ACCESS_PREFIX_ROLES}${roles.map(x => x.name).join(',')}`;
145
+ }
146
+ await api.updateWhoCanAccess({
147
+ input: {
148
+ did: dids,
149
+ whoCanAccess: value
150
+ }
151
+ });
152
+ Toast.success(t('blocklet.config.access.updatedTip'));
153
+ onClose();
154
+ setLoading(false);
155
+ } catch (err) {
156
+ setLoading(false);
157
+ Toast.error(formatError(err));
158
+ }
159
+ };
160
+ const disabled = loading || whoCanAccess === CONFIG_ROLE && !roles.length;
161
+ return [typeof children === 'function' ? children({
162
+ open: onOpen
163
+ }) : /*#__PURE__*/_jsx(IconButton, {
164
+ onClick: onOpen,
165
+ "data-cy": "action-config-component",
166
+ children: /*#__PURE__*/_jsx(EditIcon, {})
167
+ }), showDialog && /*#__PURE__*/_jsxs(StyledDialog, {
168
+ open: true,
169
+ fullWidth: true,
170
+ title: componentName,
171
+ onClose: onClose,
172
+ PaperProps: {
173
+ style: {
174
+ minHeight: 'auto'
175
+ }
176
+ },
177
+ actions: /*#__PURE__*/_jsxs(_Fragment, {
178
+ children: [/*#__PURE__*/_jsx(Button, {
179
+ onClick: onClose,
180
+ color: "inherit",
181
+ "data-cy": "config-access-cancel",
182
+ children: t('common.cancel')
183
+ }), /*#__PURE__*/_jsxs(Button, {
184
+ onClick: onConfirm,
185
+ color: "primary",
186
+ disabled: disabled,
187
+ variant: "contained",
188
+ autoFocus: true,
189
+ "data-cy": "config-access-confirm",
190
+ children: [loading && /*#__PURE__*/_jsx(Spinner, {
191
+ size: 16
192
+ }), t('common.confirm')]
193
+ })]
194
+ }),
195
+ children: [/*#__PURE__*/_jsx(Box, {
196
+ mt: 4,
197
+ mb: 3,
198
+ children: /*#__PURE__*/_jsx(TextField, {
199
+ label: t('blocklet.config.access.description'),
200
+ select: true,
201
+ fullWidth: true,
202
+ value: whoCanAccess,
203
+ onChange: onWhoCanAccessChange,
204
+ "data-cy": "config-access-select",
205
+ SelectProps: {
206
+ renderValue: selected => {
207
+ const d = Configs.find(x => x.value === selected);
208
+ return d ? /*#__PURE__*/_jsxs(Box, {
209
+ children: [/*#__PURE__*/_jsx(d.icon, {
210
+ style: iconStyle
211
+ }), d.title[locale]]
212
+ }) : null;
213
+ }
214
+ },
215
+ children: Configs.map(d => {
216
+ return /*#__PURE__*/_jsxs(StyledMenuItem, {
217
+ value: d.value,
218
+ sx: {
219
+ display: 'block'
220
+ },
221
+ "data-cy": `config-access-opt-${d.value}`,
222
+ children: [/*#__PURE__*/_jsxs(Box, {
223
+ display: "flex",
224
+ alignItems: "center",
225
+ children: [/*#__PURE__*/_jsx(d.icon, {
226
+ style: iconStyle
227
+ }), /*#__PURE__*/_jsx(Box, {
228
+ children: d.title[locale]
229
+ })]
230
+ }), /*#__PURE__*/_jsx(Box, {
231
+ children: /*#__PURE__*/_jsx(Box, {
232
+ className: "tip",
233
+ children: d.description[locale]
234
+ })
235
+ })]
236
+ });
237
+ })
238
+ })
239
+ }), whoCanAccess === CONFIG_ROLE && /*#__PURE__*/_jsx(Box, {
240
+ mt: 4,
241
+ mb: 3,
242
+ children: /*#__PURE__*/_jsx(TextField, {
243
+ label: t('blocklet.config.access.description'),
244
+ select: true,
245
+ fullWidth: true,
246
+ value: roles.map(x => x.name),
247
+ onChange: onRolesChange,
248
+ SelectProps: {
249
+ multiple: true,
250
+ renderValue: selected => /*#__PURE__*/_jsx(Box, {
251
+ sx: {
252
+ display: 'flex',
253
+ flexWrap: 'wrap',
254
+ gap: 0.5
255
+ },
256
+ children: selected.map(value => {
257
+ const role = roleList.find(x => x.name === value);
258
+ return /*#__PURE__*/_jsx(Chip, {
259
+ label: role.title
260
+ }, role.text);
261
+ })
262
+ })
263
+ },
264
+ children: roleList.map(({
265
+ name,
266
+ title
267
+ }) => {
268
+ return /*#__PURE__*/_jsxs(MenuItem, {
269
+ value: name,
270
+ children: [/*#__PURE__*/_jsx(Checkbox, {
271
+ checked: roles.some(x => x.name === name)
272
+ }), /*#__PURE__*/_jsx(ListItemText, {
273
+ primary: title
274
+ })]
275
+ }, name);
276
+ })
277
+ })
278
+ })]
279
+ })];
280
+ }
281
+ ConfigAccess.propTypes = {
282
+ blocklet: PropTypes.object.isRequired,
283
+ ancestors: PropTypes.array,
284
+ children: PropTypes.any
285
+ };
286
+ ConfigAccess.defaultProps = {
287
+ ancestors: [],
288
+ children: null
289
+ };
290
+ const StyledDialog = styled(Dialog)`
291
+ .MuiDialogContent-root {
292
+ padding-top: 0;
293
+ margin-top: -32px;
294
+ }
295
+ .MuiToolbar-root {
296
+ padding-right: 12px;
297
+ }
298
+ .ux-dialog_right {
299
+ padding-right: 20px;
300
+ }
301
+ `;
302
+ const StyledMenuItem = styled(MenuItem)`
303
+ .tip {
304
+ font-size: 12px;
305
+ color: ${props => props.theme.palette.text.secondary};
306
+ }
307
+ `;