@abtnode/ux 1.16.14-beta-c308dc3b → 1.16.14-beta-963cb583

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 (213) 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 +1313 -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/selected/index.js +94 -0
  32. package/es/blocklet/component/setting.js +109 -0
  33. package/es/blocklet/component/sortable-tree.js +126 -0
  34. package/es/blocklet/component/space-connector.js +199 -0
  35. package/es/blocklet/component/space-selector.js +178 -0
  36. package/es/blocklet/component/start.js +101 -0
  37. package/es/blocklet/component/store-blocklet-list.js +200 -0
  38. package/es/blocklet/component/switch-control.js +57 -0
  39. package/es/blocklet/config-navigation.js +331 -0
  40. package/es/blocklet/configuration.js +603 -0
  41. package/es/blocklet/disk-info.js +75 -0
  42. package/es/blocklet/icons.js +18 -0
  43. package/es/blocklet/install-from-url.js +337 -0
  44. package/es/blocklet/log.js +90 -0
  45. package/es/blocklet/migration.js +149 -0
  46. package/es/blocklet/mode.js +19 -0
  47. package/es/blocklet/notification/email.js +257 -0
  48. package/es/blocklet/notification/index.js +49 -0
  49. package/es/blocklet/oauth/auth0.js +145 -0
  50. package/es/blocklet/oauth/common-settings.js +133 -0
  51. package/es/blocklet/oauth/federated-detail-dialog.js +175 -0
  52. package/es/blocklet/oauth/federated-invite-dialog.js +83 -0
  53. package/es/blocklet/oauth/federated-join-dialog.js +111 -0
  54. package/es/blocklet/oauth/federated-site-list.js +338 -0
  55. package/es/blocklet/oauth/federated.js +81 -0
  56. package/es/blocklet/oauth/index.js +69 -0
  57. package/es/blocklet/overview.js +293 -0
  58. package/es/blocklet/page-group.js +19 -0
  59. package/es/blocklet/preferences/app-sk.js +142 -0
  60. package/es/blocklet/preferences/index.js +305 -0
  61. package/es/blocklet/purchase/common.js +95 -0
  62. package/es/blocklet/purchase/component-purchase.js +237 -0
  63. package/es/blocklet/purchase/index.js +4 -0
  64. package/es/blocklet/router/action/add-domain-alias.js +167 -0
  65. package/es/blocklet/router/action/add-rule.js +211 -0
  66. package/es/blocklet/router/action/config-routing-rule.js +232 -0
  67. package/es/blocklet/router/action/delete-domain-alias.js +99 -0
  68. package/es/blocklet/router/action/delete-rule.js +108 -0
  69. package/es/blocklet/router/action/update-rule.js +209 -0
  70. package/es/blocklet/router/domain-actions.js +64 -0
  71. package/es/blocklet/router/domain-status.js +88 -0
  72. package/es/blocklet/router/rule-actions.js +66 -0
  73. package/es/blocklet/router/rule-list.js +190 -0
  74. package/es/blocklet/router/util.js +131 -0
  75. package/es/blocklet/runtime-info.js +68 -0
  76. package/es/blocklet/status.js +91 -0
  77. package/es/blocklet/storage/action.js +134 -0
  78. package/es/blocklet/storage/backups.js +241 -0
  79. package/es/blocklet/storage/connect-to.js +372 -0
  80. package/es/blocklet/storage/connected.js +198 -0
  81. package/es/blocklet/storage/delete.js +113 -0
  82. package/es/blocklet/storage/disconnect.js +243 -0
  83. package/es/blocklet/storage/index.js +19 -0
  84. package/es/blocklet/storage/item.js +558 -0
  85. package/es/blocklet/storage/preview-nft.js +286 -0
  86. package/es/blocklet/transfer-owner.js +198 -0
  87. package/es/blocklet/types.js +18 -0
  88. package/es/blocklet/util.js +145 -0
  89. package/es/blocklet/version.js +141 -0
  90. package/es/card-selector.js +134 -0
  91. package/es/certificate.js +105 -0
  92. package/es/chain.js +13 -0
  93. package/es/click-to-copy.js +22 -0
  94. package/es/confirm.js +149 -0
  95. package/es/contexts/audit-log.js +152 -0
  96. package/es/contexts/blocklet.js +10 -0
  97. package/es/contexts/deleting-blocklets.js +70 -0
  98. package/es/contexts/node.js +17 -0
  99. package/es/contexts/session.js +8 -0
  100. package/es/contexts/team.js +10 -0
  101. package/es/delete-confirm.js +121 -0
  102. package/es/did-address.js +46 -0
  103. package/es/dot.js +14 -0
  104. package/es/exchange-passport.js +102 -0
  105. package/es/form/form-select-input.js +184 -0
  106. package/es/form/form-text-input.js +178 -0
  107. package/es/form/form-wrapper.js +88 -0
  108. package/es/form/input-triggers.js +98 -0
  109. package/es/form/required.js +8 -0
  110. package/es/hooks/blocklet.js +229 -0
  111. package/es/hooks/confirm.js +90 -0
  112. package/es/hooks/mobile-width.js +11 -0
  113. package/es/hooks/url-evaluation.js +155 -0
  114. package/es/hooks/use-app-logo.js +16 -0
  115. package/es/hooks/use-backup-progress.js +31 -0
  116. package/es/hooks/use-blocklet-info-for-connect-did-spaces.js +50 -0
  117. package/es/hooks/use-bundle-logo.js +27 -0
  118. package/es/hooks/use-navigation.js +347 -0
  119. package/es/hooks/use-passport-id.js +14 -0
  120. package/es/hooks/use-subscription.js +22 -0
  121. package/es/icons/empty-space-nft.svg +59 -0
  122. package/es/icons/empty-spaces-nft.svg +58 -0
  123. package/es/icons/long-arrow.svg +5 -0
  124. package/es/icons/space-connected.svg +3 -0
  125. package/es/icons/space-disconnect.svg +3 -0
  126. package/es/index.js +3 -0
  127. package/es/invitation/invitation-app.js +58 -0
  128. package/es/invitation/invitation-login.js +68 -0
  129. package/es/invitation/invitation-passport.js +146 -0
  130. package/es/invitation/invitation-receive.js +138 -0
  131. package/es/invitation/invitation-success.js +93 -0
  132. package/es/invitation/invitation-user.js +90 -0
  133. package/es/invitation/invitation.js +90 -0
  134. package/es/issue-passport.js +142 -0
  135. package/es/launch-blocklet/content-layout.js +58 -0
  136. package/es/launch-blocklet/page-header.js +43 -0
  137. package/es/layout/addon.js +114 -0
  138. package/es/layout/feedback.js +55 -0
  139. package/es/locales/en.js +1541 -0
  140. package/es/locales/index.js +9 -0
  141. package/es/locales/zh.js +1544 -0
  142. package/es/logs/clock.js +11 -0
  143. package/es/logs/download.js +132 -0
  144. package/es/logs/log-terminal.js +253 -0
  145. package/es/lost-passport.js +452 -0
  146. package/es/nav-logo.js +219 -0
  147. package/es/passport-tag.js +43 -0
  148. package/es/permission.js +57 -0
  149. package/es/relative-time.js +53 -0
  150. package/es/result-message.js +11 -0
  151. package/es/schema-form/color-input.js +98 -0
  152. package/es/schema-form/common-prop-types.js +13 -0
  153. package/es/schema-form/index.js +215 -0
  154. package/es/schema-form/passport-input.js +55 -0
  155. package/es/schema-form/text-input.js +57 -0
  156. package/es/store/add.js +179 -0
  157. package/es/store/delete.js +96 -0
  158. package/es/store/item.js +76 -0
  159. package/es/subscription.js +144 -0
  160. package/es/table-icons.js +34 -0
  161. package/es/table.js +52 -0
  162. package/es/tag.js +21 -0
  163. package/es/team/members/actions.js +89 -0
  164. package/es/team/members/index.js +636 -0
  165. package/es/team/members/invitations.js +188 -0
  166. package/es/team/members/invite-member.js +208 -0
  167. package/es/team/members/issue-passport.js +152 -0
  168. package/es/team/members/member.js +408 -0
  169. package/es/team/members/passport-issuances.js +155 -0
  170. package/es/team/members/passports.js +364 -0
  171. package/es/team/members/toggle-user-approval.js +122 -0
  172. package/es/team/members/transfer-node.js +256 -0
  173. package/es/team/members/util.js +14 -0
  174. package/es/team/passports/color.js +127 -0
  175. package/es/team/passports/detail.js +312 -0
  176. package/es/team/passports/index.js +282 -0
  177. package/es/team/passports/mutate-role.js +198 -0
  178. package/es/team/passports/trusted-factories.js +221 -0
  179. package/es/team/passports/trusted-factory.js +343 -0
  180. package/es/team/passports/trusted-issuer.js +296 -0
  181. package/es/team/passports/trusted-issuers.js +226 -0
  182. package/es/team/search-input.js +46 -0
  183. package/es/team/styles/dialog.js +72 -0
  184. package/es/team/styles/list-header.js +31 -0
  185. package/es/util/api.js +6 -0
  186. package/es/util/constants.js +2 -0
  187. package/es/util/index.js +598 -0
  188. package/es/util/mode.js +4 -0
  189. package/es/util/space-gateway.js +51 -0
  190. package/es/util/spaces.js +160 -0
  191. package/es/who-can-access/config.js +38 -0
  192. package/es/wrap-locale.js +15 -0
  193. package/lib/blocklet/component/add.js +5 -0
  194. package/lib/blocklet/component/selected/index.js +47 -0
  195. package/lib/blocklet/component/space-connector.js +1 -1
  196. package/lib/blocklet/component/space-selector.js +1 -1
  197. package/lib/blocklet/storage/backups.js +1 -1
  198. package/lib/blocklet/storage/connect-to.js +6 -7
  199. package/lib/blocklet/storage/connected.js +1 -1
  200. package/lib/blocklet/storage/disconnect.js +1 -1
  201. package/lib/blocklet/storage/index.js +1 -1
  202. package/lib/blocklet/storage/item.js +1 -1
  203. package/lib/card-selector.js +14 -14
  204. package/lib/invitation/invitation-passport.js +7 -6
  205. package/lib/invitation/invitation-receive.js +1 -1
  206. package/lib/locales/en.js +12 -5
  207. package/lib/locales/zh.js +10 -3
  208. package/lib/lost-passport.js +2 -2
  209. package/lib/schema-form/passport-input.js +12 -11
  210. package/lib/team/passports/color.js +14 -14
  211. package/lib/team/passports/trusted-factory.js +1 -1
  212. package/lib/util/spaces.js +13 -1
  213. package/package.json +88 -21
@@ -0,0 +1,607 @@
1
+ import PropTypes from 'prop-types';
2
+ import Button from '@arcblock/ux/lib/Button';
3
+ import Dialog from '@arcblock/ux/lib/Dialog';
4
+ import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
+ import Autocomplete from '@mui/material/Autocomplete';
6
+ import Box from '@mui/material/Box';
7
+ import FormControl from '@mui/material/FormControl';
8
+ import IconButton from '@mui/material/IconButton';
9
+ import InputAdornment from '@mui/material/InputAdornment';
10
+ import TextField from '@mui/material/TextField';
11
+ import Typography from '@mui/material/Typography';
12
+ import { useAsyncEffect, useBoolean, useReactive } from 'ahooks';
13
+ import omit from 'lodash/omit';
14
+ import pick from 'lodash/pick';
15
+ import values from 'lodash/values';
16
+ import without from 'lodash/without';
17
+ import isEmpty from 'lodash/isEmpty';
18
+ import isString from 'lodash/isString';
19
+ import isObject from 'lodash/isObject';
20
+ import cloneDeep from 'lodash/cloneDeep';
21
+ import Toast from '@arcblock/ux/lib/Toast';
22
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
23
+ import { Controller, useForm } from 'react-hook-form';
24
+ import { Icon, loadIcon } from '@iconify/react';
25
+ import { isMatchSection, checkLink, flattenNavigation } from '@blocklet/meta/lib/parse-navigation-from-blocklet';
26
+ import urljoin from 'url-join';
27
+ import { withoutTrailingSlash } from 'ufo/dist/index.mjs';
28
+ import isAbsoluteUrl from 'is-absolute-url';
29
+ import { SUPPORTED_LANGUAGES } from '@blocklet/constant';
30
+ import LocaleTabs from './locale-tabs';
31
+ import SimpleSelect from './simple-select';
32
+ import { useTeamContext } from '../../../contexts/team';
33
+ import { useBlockletContext } from '../../../contexts/blocklet';
34
+ import { jsx as _jsx } from "react/jsx-runtime";
35
+ import { jsxs as _jsxs } from "react/jsx-runtime";
36
+ const MAX_TITLE_LENGTH = 24;
37
+ const defaultType = 'add';
38
+ const defaultLocale = 'en';
39
+ const initialFormState = {
40
+ title: {
41
+ [defaultLocale]: ''
42
+ },
43
+ link: {
44
+ [defaultLocale]: ''
45
+ }
46
+ };
47
+ function IconSuffix({
48
+ icon
49
+ }) {
50
+ const [loaded, setLoaded] = useState(false);
51
+ useAsyncEffect(async () => {
52
+ setLoaded(false);
53
+ await loadIcon(icon);
54
+ setLoaded(true);
55
+ }, [icon]);
56
+ if (icon) {
57
+ if (loaded) {
58
+ return /*#__PURE__*/_jsx(Icon, {
59
+ icon: icon
60
+ });
61
+ }
62
+ return /*#__PURE__*/_jsx(Icon, {
63
+ color: "#f06f6e",
64
+ icon: "ic:baseline-error"
65
+ });
66
+ }
67
+ return /*#__PURE__*/_jsx(Icon, {
68
+ icon: "codicon:blank"
69
+ });
70
+ }
71
+ IconSuffix.propTypes = {
72
+ icon: PropTypes.string.isRequired
73
+ };
74
+ const NavigationDialog = /*#__PURE__*/forwardRef(function NavigationDialog({
75
+ section,
76
+ components,
77
+ rawNavigations
78
+ }, ref) {
79
+ const {
80
+ roles
81
+ } = useTeamContext();
82
+ const {
83
+ t,
84
+ locale
85
+ } = useLocaleContext();
86
+ const {
87
+ blocklet
88
+ } = useBlockletContext();
89
+ const config = blocklet.environments.find(x => x.key === 'BLOCKLET_APP_LANGUAGES');
90
+ const languages = config ? config.value.split(',') : ['en', 'zh'];
91
+ const localeMap = languages.filter(x => SUPPORTED_LANGUAGES[x]).reduce((acc, x) => {
92
+ acc[x] = SUPPORTED_LANGUAGES[x].nativeName;
93
+ return acc;
94
+ }, {});
95
+ const saveFn = useRef(() => {});
96
+ const [show, {
97
+ setFalse,
98
+ setTrue
99
+ }] = useBoolean(false);
100
+ const state = useReactive({
101
+ isRoot: true,
102
+ type: defaultType,
103
+ linkDisabled: false,
104
+ locale: defaultLocale,
105
+ formState: cloneDeep(initialFormState),
106
+ get localeList() {
107
+ // eslint-disable-next-line react/no-this-in-sfc
108
+ return without(Object.keys(this.formState.title), defaultLocale);
109
+ }
110
+ });
111
+ const {
112
+ handleSubmit,
113
+ control,
114
+ watch,
115
+ setValue,
116
+ clearErrors,
117
+ formState: {
118
+ errors
119
+ }
120
+ } = useForm({
121
+ mode: 'onChange',
122
+ defaultValues: {
123
+ id: undefined,
124
+ title: undefined,
125
+ icon: undefined,
126
+ link: undefined,
127
+ component: undefined,
128
+ parent: undefined,
129
+ role: []
130
+ }
131
+ });
132
+ useEffect(() => {
133
+ setValue('title', state.formState.title[state.locale]);
134
+ setValue('link', state.formState.link[state.locale]);
135
+ // eslint-disable-next-line react-hooks/exhaustive-deps
136
+ }, [setValue, state.locale, show]);
137
+ const watchComponent = watch('component');
138
+ const watchTitle = watch('title');
139
+ const watchLink = watch('link');
140
+ const watchIcon = watch('icon');
141
+ const watchParent = watch('parent');
142
+ useEffect(() => {
143
+ state.formState.title[state.locale] = watchTitle;
144
+ // eslint-disable-next-line react-hooks/exhaustive-deps
145
+ }, [watchTitle]);
146
+ useEffect(() => {
147
+ state.formState.link[state.locale] = watchLink;
148
+ // eslint-disable-next-line react-hooks/exhaustive-deps
149
+ }, [watchLink]);
150
+ const selectedOption = useMemo(() => {
151
+ const parentData = rawNavigations.find(item => {
152
+ if (watchComponent) {
153
+ const findComponent = components.find(x => x.name === watchComponent);
154
+ return findComponent.did === item.id;
155
+ }
156
+ return item.id === watchParent;
157
+ });
158
+ return parentData;
159
+ }, [components, rawNavigations, watchComponent, watchParent]);
160
+ const linkPrefix = useMemo(() => {
161
+ if (selectedOption?.component) {
162
+ const findComponent = components.find(item => item.name === selectedOption.component);
163
+ const {
164
+ link
165
+ } = findComponent || {};
166
+ const stringLink = isObject(link) ? link[state.locale] : link;
167
+ if (watchComponent) {
168
+ return withoutTrailingSlash(stringLink);
169
+ }
170
+ const selectedLink = isObject(selectedOption.link) ? selectedOption.link[state.locale] : selectedOption.link;
171
+ return withoutTrailingSlash(urljoin(stringLink, selectedLink || '/'));
172
+ }
173
+ return null;
174
+ }, [components, state.locale, selectedOption, watchComponent]);
175
+ const autocompleteOptions = useMemo(() => {
176
+ const {
177
+ component
178
+ } = selectedOption || {};
179
+ const componentBlocklet = components.find(item => item.name === component);
180
+ const {
181
+ navigation = []
182
+ } = componentBlocklet || {};
183
+ const flattenedNavigation = flattenNavigation(navigation, {
184
+ transform(item, parent) {
185
+ if (parent?.section) {
186
+ item.section = item.section || parent.section;
187
+ }
188
+ return item;
189
+ }
190
+ });
191
+ return flattenedNavigation.filter(item => item.link)
192
+ // 在指定 section 下只展示能够展示的 navigation
193
+ .filter(item => isMatchSection(item.section, section)).map(item => {
194
+ return {
195
+ label: item.link,
196
+ title: item.title[locale] || item.title
197
+ };
198
+ });
199
+ }, [selectedOption, components, section, locale]);
200
+ const name = useMemo(() => {
201
+ const typeMap = {
202
+ add: t('common.create'),
203
+ edit: t('common.edit')
204
+ };
205
+ const typeName = typeMap[state.type];
206
+ if (typeName) {
207
+ return `${typeName} ${t('navigation.navigation')}`;
208
+ }
209
+ return '--';
210
+ }, [state.type, t]);
211
+ const reset = useCallback(() => {
212
+ state.isRoot = true;
213
+ state.locale = defaultLocale;
214
+ state.type = defaultType;
215
+ state.linkDisabled = false;
216
+ saveFn.current = () => {};
217
+ setValue('id', undefined);
218
+ setValue('icon', undefined);
219
+ setValue('title', undefined);
220
+ setValue('link', undefined);
221
+ setValue('component', undefined);
222
+ setValue('parent', undefined);
223
+ setValue('role', []);
224
+ state.formState = cloneDeep(initialFormState);
225
+ clearErrors();
226
+ }, [clearErrors, setValue, state]);
227
+ const patchFormValues = useCallback((params = {}) => {
228
+ if (state.localeList.length > 0) {
229
+ if (new Set(values(state.formState.title)).size > 1) {
230
+ params.title = state.formState.title;
231
+ }
232
+ if (new Set(values(state.formState.link)).size > 1) {
233
+ params.link = state.formState.link;
234
+ }
235
+ }
236
+ if (isEmpty(params.role)) {
237
+ params.role = undefined;
238
+ }
239
+ return params;
240
+ }, [state.formState.link, state.formState.title, state.localeList]);
241
+ const close = useCallback(() => {
242
+ setFalse();
243
+ setTimeout(() => {
244
+ reset();
245
+ });
246
+ }, [reset, setFalse]);
247
+ const add = useCallback(({
248
+ parent
249
+ } = {}, cb = () => {}) => {
250
+ state.type = 'add';
251
+ state.isRoot = !parent;
252
+ setValue('parent', parent?.id);
253
+ saveFn.current = params => {
254
+ cb(close, params);
255
+ };
256
+ setTrue();
257
+ }, [close, setTrue, setValue, state]);
258
+ const edit = useCallback((data = {}, cb = () => {}) => {
259
+ const {
260
+ id,
261
+ title,
262
+ icon,
263
+ link,
264
+ parent,
265
+ component,
266
+ role = []
267
+ } = data;
268
+ setValue('id', id);
269
+ setValue('icon', icon);
270
+ if (data.from === 'tmpl') {
271
+ state.linkDisabled = true;
272
+ }
273
+ if (isString(title)) {
274
+ state.formState.title = state.localeList.reduce((resData, localeItem) => {
275
+ resData[localeItem] = title;
276
+ return resData;
277
+ }, {
278
+ [defaultLocale]: title
279
+ });
280
+ } else if (isObject(title)) {
281
+ state.formState.title = cloneDeep(title);
282
+ } else {
283
+ state.formState.title = {};
284
+ }
285
+ if (isString(link)) {
286
+ state.formState.link = state.localeList.reduce((resData, localeItem) => {
287
+ resData[localeItem] = link;
288
+ return resData;
289
+ }, {
290
+ [defaultLocale]: link
291
+ });
292
+ } else if (isObject(link)) {
293
+ state.formState.link = cloneDeep(link);
294
+ } else {
295
+ state.formState.link = {};
296
+ }
297
+ setValue('component', component);
298
+ setValue('parent', parent);
299
+ setValue('role', role || []);
300
+ setTrue();
301
+ state.type = 'edit';
302
+ state.isRoot = !parent;
303
+ saveFn.current = params => {
304
+ const pickData = pick(params, ['id', 'title', 'icon', 'link', 'role']);
305
+ cb(close, pickData);
306
+ };
307
+ }, [close, setTrue, setValue, state]);
308
+ useImperativeHandle(ref, () => {
309
+ return {
310
+ add,
311
+ edit,
312
+ close
313
+ };
314
+ }, [add, close, edit]);
315
+ function validTitle(raw) {
316
+ const value = raw?.trim();
317
+ if (!value) return t('common.requiredErrorText', {
318
+ name: t('navigation.form.title')
319
+ });
320
+ if (value.length > MAX_TITLE_LENGTH) return t('navigation.form.titleTooLong', {
321
+ len: MAX_TITLE_LENGTH
322
+ });
323
+ return true;
324
+ }
325
+ async function validIcon(raw) {
326
+ const value = raw?.trim();
327
+ if (value) {
328
+ try {
329
+ await loadIcon(value);
330
+ } catch {
331
+ return t('navigation.form.invalidIcon');
332
+ }
333
+ }
334
+ return true;
335
+ }
336
+ function validLink(raw) {
337
+ const value = raw?.trim();
338
+ if (!value) {
339
+ if (!state.isRoot) {
340
+ return t('common.requiredErrorText', {
341
+ name: t('navigation.form.link')
342
+ });
343
+ }
344
+ return true;
345
+ }
346
+ if (!checkLink(value)) {
347
+ return t('navigation.form.invalidLink');
348
+ }
349
+ return true;
350
+ }
351
+ const handleChangeLocale = useCallback(currentLocale => {
352
+ state.locale = currentLocale;
353
+ if (!state.formState.title[currentLocale]) {
354
+ state.formState.title[currentLocale] = '';
355
+ }
356
+ if (!state.formState.link[currentLocale]) {
357
+ state.formState.link[currentLocale] = '';
358
+ }
359
+ setTimeout(() => {
360
+ clearErrors();
361
+ });
362
+ }, [clearErrors, state]);
363
+ const checkFormState = useCallback(() => {
364
+ const {
365
+ title,
366
+ link
367
+ } = state.formState;
368
+ for (const key of Object.keys(title)) {
369
+ const validRes = validTitle(title[key]);
370
+ if (validRes !== true) {
371
+ return validRes;
372
+ }
373
+ }
374
+ for (const key of Object.keys(link)) {
375
+ const validRes = validLink(link[key]);
376
+ if (validRes !== true) {
377
+ return validRes;
378
+ }
379
+ }
380
+ return true;
381
+ // eslint-disable-next-line react-hooks/exhaustive-deps
382
+ }, [state.formState]);
383
+ const handleFormSubmit = useCallback(params => {
384
+ const checkRes = checkFormState();
385
+ if (checkRes === true) {
386
+ saveFn.current(patchFormValues(params));
387
+ } else {
388
+ Toast.error(checkRes);
389
+ }
390
+ }, [checkFormState, patchFormValues]);
391
+ const handleRemoveLocale = useCallback(currentLocale => {
392
+ state.formState.title = omit(state.formState.title, currentLocale);
393
+ state.formState.link = omit(state.formState.link, currentLocale);
394
+ }, [state.formState]);
395
+ const handleAddLocale = useCallback(newLocale => {
396
+ state.locale = newLocale;
397
+ state.formState.title[newLocale] = state.formState.title?.[defaultLocale];
398
+ state.formState.link[newLocale] = state.formState.link?.[defaultLocale];
399
+ setTimeout(() => {
400
+ clearErrors();
401
+ });
402
+ }, [clearErrors, state]);
403
+ return /*#__PURE__*/_jsxs(Dialog, {
404
+ open: show,
405
+ title: name,
406
+ onClose: close,
407
+ actions: /*#__PURE__*/_jsx(Button, {
408
+ onClick: handleSubmit(handleFormSubmit),
409
+ color: "primary",
410
+ autoFocus: true,
411
+ variant: "contained",
412
+ children: t('common.confirm')
413
+ }),
414
+ children: [/*#__PURE__*/_jsx(LocaleTabs, {
415
+ sx: {
416
+ mb: 1
417
+ },
418
+ onAdd: handleAddLocale,
419
+ onChange: handleChangeLocale,
420
+ onRemoveLocale: handleRemoveLocale,
421
+ localeMap: localeMap,
422
+ locales: state.localeList
423
+ }), /*#__PURE__*/_jsxs("form", {
424
+ noValidate: true,
425
+ autoComplete: "off",
426
+ children: [/*#__PURE__*/_jsx(Controller, {
427
+ name: "title",
428
+ control: control,
429
+ rules: {
430
+ validate: validTitle
431
+ },
432
+ render: ({
433
+ field
434
+ }) => /*#__PURE__*/_jsx(TextField, {
435
+ fullWidth: true,
436
+ variant: "outlined",
437
+ margin: "dense",
438
+ required: true,
439
+ placeholder: t('navigation.form.titlePlaceholder'),
440
+ label: t('navigation.form.title'),
441
+ disabled: state.isEdit,
442
+ error: !!errors?.title?.message,
443
+ helperText: errors?.title?.message || ' ',
444
+ ...field
445
+ })
446
+ }), /*#__PURE__*/_jsx(Controller, {
447
+ name: "icon",
448
+ control: control,
449
+ rules: {
450
+ validate: validIcon
451
+ },
452
+ render: ({
453
+ field
454
+ }) => /*#__PURE__*/_jsx(TextField, {
455
+ fullWidth: true,
456
+ variant: "outlined",
457
+ margin: "dense",
458
+ placeholder: t('navigation.form.iconPlaceholder'),
459
+ label: t('navigation.form.icon'),
460
+ error: !!errors?.icon?.message,
461
+ disabled: state.locale !== defaultLocale,
462
+ helperText: errors?.icon?.message || /*#__PURE__*/_jsx(Box, {
463
+ display: "flex",
464
+ children: /*#__PURE__*/_jsxs(Box, {
465
+ component: "a",
466
+ href: "https://icones.js.org",
467
+ target: "_blank",
468
+ display: "flex",
469
+ alignItems: "center",
470
+ children: [t('navigation.form.findMoreIcon'), ' ', /*#__PURE__*/_jsx(Icon, {
471
+ style: {
472
+ marginLeft: 4
473
+ },
474
+ icon: "radix-icons:external-link"
475
+ })]
476
+ })
477
+ }),
478
+ ...field,
479
+ InputProps: {
480
+ endAdornment: /*#__PURE__*/_jsx(InputAdornment, {
481
+ position: "end",
482
+ children: /*#__PURE__*/_jsx(IconButton, {
483
+ sx: {
484
+ cursor: 'default'
485
+ },
486
+ disableFocusRipple: true,
487
+ disableRipple: true,
488
+ children: watchIcon && /*#__PURE__*/_jsx(IconSuffix, {
489
+ icon: watchIcon
490
+ })
491
+ })
492
+ })
493
+ }
494
+ })
495
+ }), state.isRoot && /*#__PURE__*/_jsx(Controller, {
496
+ name: "component",
497
+ control: control,
498
+ render: ({
499
+ field
500
+ }) => /*#__PURE__*/_jsx(SimpleSelect, {
501
+ fullWidth: true,
502
+ margin: "dense",
503
+ disabled: state.type === 'edit' || state.locale !== defaultLocale,
504
+ label: t('navigation.form.component'),
505
+ placeholer: t('navigation.form.componentPlaceholder'),
506
+ options: components.map(item => ({
507
+ title: item.title,
508
+ value: item.name,
509
+ description: item.link
510
+ })),
511
+ error: !!errors?.component?.message,
512
+ helperText: errors?.component?.message || ' ',
513
+ ...omit(field, 'ref')
514
+ })
515
+ }), /*#__PURE__*/_jsx(Controller, {
516
+ name: "link",
517
+ control: control,
518
+ rules: {
519
+ validate: validLink
520
+ },
521
+ render: ({
522
+ field
523
+ }) => /*#__PURE__*/_jsx(FormControl, {
524
+ fullWidth: true,
525
+ margin: "dense",
526
+ children: /*#__PURE__*/_jsx(Autocomplete, {
527
+ disablePortal: true,
528
+ freeSolo: true,
529
+ blurOnSelect: true,
530
+ autoSelect: true,
531
+ fullWidth: true,
532
+ disabled: state.linkDisabled,
533
+ isOptionEqualToValue: option => option.label,
534
+ options: autocompleteOptions,
535
+ renderInput: params => {
536
+ return /*#__PURE__*/_jsx(TextField, {
537
+ ...params,
538
+ placeholder: t('navigation.form.linkPlaceholder'),
539
+ label: t('navigation.form.link'),
540
+ error: !!errors?.link?.message,
541
+ helperText: errors?.link?.message || '/abc/bcd or /abc or https://arcblock.io'
542
+ // FIXME: 添加了 startAdornment 后,autocomplete 选项无法显示,之后换成 antd 的 autocomplete 可以解决这个问题
543
+ ,
544
+ InputProps: {
545
+ startAdornment: linkPrefix ? /*#__PURE__*/_jsx(InputAdornment, {
546
+ position: "start",
547
+ sx: {
548
+ textDecoration: isAbsoluteUrl(watchLink || '') ? 'line-through' : ''
549
+ },
550
+ children: linkPrefix
551
+ }) : null
552
+ }
553
+ });
554
+ },
555
+ renderOption: (props, option) => /*#__PURE__*/_jsxs(Box, {
556
+ component: "li",
557
+ ...props,
558
+ children: [option.label, /*#__PURE__*/_jsx(Typography, {
559
+ marginLeft: 1,
560
+ component: "span",
561
+ variant: "body2",
562
+ color: "text.secondary",
563
+ children: option.title
564
+ })]
565
+ }),
566
+ margin: "dense",
567
+ ...field,
568
+ onChange: () => {},
569
+ onInputChange: (e, value) => {
570
+ field.onChange(value);
571
+ }
572
+ })
573
+ })
574
+ }), ['dashboard', 'sessionManager'].includes(section) && /*#__PURE__*/_jsx(Controller, {
575
+ name: "role",
576
+ control: control,
577
+ render: ({
578
+ field
579
+ }) => /*#__PURE__*/_jsx(SimpleSelect, {
580
+ fullWidth: true,
581
+ multiple: true,
582
+ margin: "dense",
583
+ label: t('navigation.form.role'),
584
+ placeholer: t('navigation.form.rolePlaceholder'),
585
+ options: roles.map(role => ({
586
+ title: role.title,
587
+ value: role.name
588
+ })),
589
+ error: !!errors?.role?.message,
590
+ helperText: errors?.role?.message || ' ',
591
+ ...omit(field, 'ref')
592
+ })
593
+ })]
594
+ })]
595
+ });
596
+ });
597
+ NavigationDialog.propTypes = {
598
+ section: PropTypes.string,
599
+ components: PropTypes.array,
600
+ rawNavigations: PropTypes.array
601
+ };
602
+ NavigationDialog.defaultProps = {
603
+ section: '',
604
+ components: [],
605
+ rawNavigations: []
606
+ };
607
+ export default NavigationDialog;
@@ -0,0 +1,101 @@
1
+ import PropTypes from 'prop-types';
2
+ import Header from '@blocklet/ui-react/lib/Header';
3
+ import Footer from '@blocklet/ui-react/lib/Footer';
4
+ import Dashboard from '@blocklet/ui-react/lib/Dashboard';
5
+ import LinkBlocker from '@blocklet/ui-react/lib/common/link-blocker';
6
+ import Box from '@mui/material/Box';
7
+ import Grid from '@mui/material/Grid';
8
+ import Skeleton from '@mui/material/Skeleton';
9
+ import styled from '@emotion/styled';
10
+ import { useBlockletContext } from '../../../contexts/blocklet';
11
+ import useAppLogo from '../../../hooks/use-app-logo';
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { jsxs as _jsxs } from "react/jsx-runtime";
14
+ function NavigationPreview({
15
+ className,
16
+ navigation
17
+ }) {
18
+ const {
19
+ blocklet
20
+ } = useBlockletContext();
21
+ const {
22
+ logoUrl
23
+ } = useAppLogo({
24
+ blocklet
25
+ });
26
+ const blockletInfo = {
27
+ appId: blocklet.appDid,
28
+ appLogo: logoUrl,
29
+ appName: blocklet.meta.title,
30
+ enableConnect: true,
31
+ enableLocale: false,
32
+ navigation
33
+ };
34
+ return /*#__PURE__*/_jsx(LinkBlocker, {
35
+ children: /*#__PURE__*/_jsxs(Box, {
36
+ className: className,
37
+ children: [/*#__PURE__*/_jsx(Header, {
38
+ meta: blockletInfo
39
+ }), /*#__PURE__*/_jsx(Box, {
40
+ children: /*#__PURE__*/_jsx(Dashboard, {
41
+ meta: blockletInfo,
42
+ invalidPathFallback: () => {},
43
+ headerProps: {
44
+ style: {
45
+ display: 'none'
46
+ }
47
+ },
48
+ children: /*#__PURE__*/_jsx(Grid, {
49
+ container: true,
50
+ spacing: 2,
51
+ children: new Array(6).fill().map((item, index) => {
52
+ return (
53
+ /*#__PURE__*/
54
+ // eslint-disable-next-line react/no-array-index-key
55
+ _jsxs(Grid, {
56
+ item: true,
57
+ xs: 4,
58
+ children: [/*#__PURE__*/_jsx(Skeleton, {
59
+ animation: false,
60
+ variant: "rectangular",
61
+ width: "100%",
62
+ height: 120
63
+ }), /*#__PURE__*/_jsxs(Box, {
64
+ sx: {
65
+ pt: 0.5
66
+ },
67
+ children: [/*#__PURE__*/_jsx(Skeleton, {
68
+ animation: false
69
+ }), /*#__PURE__*/_jsx(Skeleton, {
70
+ width: "60%",
71
+ animation: false
72
+ })]
73
+ })]
74
+ }, index)
75
+ );
76
+ })
77
+ })
78
+ })
79
+ }), /*#__PURE__*/_jsx(Footer, {
80
+ meta: blockletInfo
81
+ })]
82
+ })
83
+ });
84
+ }
85
+ NavigationPreview.propTypes = {
86
+ className: PropTypes.string,
87
+ navigation: PropTypes.array
88
+ };
89
+ NavigationPreview.defaultProps = {
90
+ className: '',
91
+ navigation: []
92
+ };
93
+ const StyledNavigationPreview = styled(NavigationPreview)`
94
+ .dashboard {
95
+ height: auto !important;
96
+ }
97
+ .dashboard-content + div {
98
+ display: none;
99
+ }
100
+ `;
101
+ export default StyledNavigationPreview;