@blocklet/ui-react 3.0.38 → 3.0.39
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/lib/Dashboard/index.js +52 -53
- package/lib/Header/index.d.ts +0 -1
- package/lib/Header/index.js +56 -58
- package/lib/common/header-addons.d.ts +1 -3
- package/lib/common/header-addons.js +51 -112
- package/lib/common/wizard-modal.d.ts +3 -1
- package/lib/common/wizard-modal.js +61 -52
- package/package.json +5 -5
- package/src/Dashboard/index.jsx +0 -1
- package/src/Header/index.tsx +0 -3
- package/src/common/header-addons.jsx +8 -78
- package/src/common/wizard-modal.jsx +12 -3
- package/src/common/wizard-example.md +0 -168
package/lib/Dashboard/index.js
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
import { jsx as i } from "react/jsx-runtime";
|
|
2
2
|
import "iconify-icon";
|
|
3
|
-
import { use as I, useMemo as
|
|
3
|
+
import { use as I, useMemo as v, useLayoutEffect as w } from "react";
|
|
4
4
|
import t from "prop-types";
|
|
5
5
|
import { SessionContext as R } from "@arcblock/did-connect/lib/Session";
|
|
6
6
|
import { useLocaleContext as T } from "@arcblock/ux/lib/Locale/context";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import { SessionManagerProps as
|
|
11
|
-
import { mapRecursive as
|
|
12
|
-
import { formatBlockletInfo as
|
|
13
|
-
import
|
|
14
|
-
import { useWalletHiddenTopbar as
|
|
15
|
-
function
|
|
7
|
+
import z from "@arcblock/ux/lib/Img";
|
|
8
|
+
import A from "@arcblock/ux/lib/Layout/dashboard";
|
|
9
|
+
import C from "@arcblock/ux/lib/hooks/use-blocklet-logo";
|
|
10
|
+
import { SessionManagerProps as D, BlockletMetaProps as M } from "../types.js";
|
|
11
|
+
import { mapRecursive as O, flatRecursive as j, matchPaths as H } from "../utils.js";
|
|
12
|
+
import { formatBlockletInfo as S, getLocalizedNavigation as _, filterNavByRole as E, publicPath as m } from "../blocklets.js";
|
|
13
|
+
import U from "../common/header-addons.js";
|
|
14
|
+
import { useWalletHiddenTopbar as q } from "../common/wallet-hidden-topbar.js";
|
|
15
|
+
function F({
|
|
16
16
|
meta: s = {},
|
|
17
|
-
fallbackUrl: a =
|
|
17
|
+
fallbackUrl: a = m,
|
|
18
18
|
invalidPathFallback: l = null,
|
|
19
19
|
headerAddons: k = void 0,
|
|
20
20
|
sessionManagerProps: L = {
|
|
21
21
|
showRole: !0,
|
|
22
22
|
// dashboard 默认退出登录行为: 跳转到 (root) blocklet 首页
|
|
23
23
|
onLogout: () => {
|
|
24
|
-
window.location.href =
|
|
24
|
+
window.location.href = m;
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
links: c = [],
|
|
28
|
-
showDomainWarningDialog:
|
|
29
|
-
...
|
|
28
|
+
showDomainWarningDialog: N = !0,
|
|
29
|
+
...h
|
|
30
30
|
}) {
|
|
31
|
-
|
|
32
|
-
const
|
|
31
|
+
q();
|
|
32
|
+
const d = I(R)?.session?.user, g = d?.role, { locale: x } = T() || {}, r = v(() => {
|
|
33
33
|
const e = Object.assign({}, window.blocklet, s);
|
|
34
34
|
try {
|
|
35
|
-
return
|
|
35
|
+
return S(e);
|
|
36
36
|
} catch (n) {
|
|
37
37
|
return console.error("Failed to format blocklet info", n, e), e;
|
|
38
38
|
}
|
|
39
|
-
}, [s]), { localizedNav:
|
|
40
|
-
let e =
|
|
41
|
-
e =
|
|
39
|
+
}, [s]), { localizedNav: y, flattened: f, matchedIndex: b } = v(() => {
|
|
40
|
+
let e = _(r?.navigation?.dashboard, x) || [];
|
|
41
|
+
e = E(e, g), e = O(
|
|
42
42
|
e,
|
|
43
43
|
(o) => {
|
|
44
|
-
let
|
|
45
|
-
return o.icon && (o.icon.startsWith("http") || o.icon.startsWith("data:") ?
|
|
44
|
+
let u = null;
|
|
45
|
+
return o.icon && (o.icon.startsWith("http") || o.icon.startsWith("data:") ? u = /* @__PURE__ */ i(z, { src: o.icon }) : u = /* @__PURE__ */ i("iconify-icon", { height: "100%", width: "100%", icon: o.icon })), {
|
|
46
46
|
id: o.id,
|
|
47
47
|
title: o.title,
|
|
48
48
|
url: o.link,
|
|
49
|
-
icon:
|
|
49
|
+
icon: u,
|
|
50
50
|
// https://github.com/ArcBlock/ux/issues/755#issuecomment-1208692620
|
|
51
51
|
external: !0,
|
|
52
52
|
children: o.items
|
|
@@ -54,56 +54,55 @@ function G({
|
|
|
54
54
|
},
|
|
55
55
|
"items"
|
|
56
56
|
);
|
|
57
|
-
const n =
|
|
58
|
-
return
|
|
59
|
-
}, [r, x, g]),
|
|
57
|
+
const n = j(e).filter((o) => !!o.url), p = H(n.map((o) => o.url));
|
|
58
|
+
return p !== -1 && (n[p].active = !0), { localizedNav: e, flattened: n, matchedIndex: p };
|
|
59
|
+
}, [r, x, g]), P = typeof c == "function" ? c(y) : [...y, ...c], W = C({
|
|
60
60
|
meta: s
|
|
61
61
|
});
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
}, [a]),
|
|
65
|
-
|
|
66
|
-
}, [l,
|
|
62
|
+
if (w(() => {
|
|
63
|
+
d && !f?.length && a && (window.location.href = a);
|
|
64
|
+
}, [a]), w(() => {
|
|
65
|
+
d && f?.length && b === -1 && l && l();
|
|
66
|
+
}, [l, f, b]), !r.appName)
|
|
67
67
|
return null;
|
|
68
|
-
const { appName:
|
|
69
|
-
q,
|
|
70
|
-
{
|
|
71
|
-
formattedBlocklet: r,
|
|
72
|
-
addons: k,
|
|
73
|
-
sessionManagerProps: L,
|
|
74
|
-
showDomainWarningDialog: P,
|
|
75
|
-
showWizard: d.headerProps?.showWizard
|
|
76
|
-
}
|
|
77
|
-
);
|
|
68
|
+
const { appName: B } = r;
|
|
78
69
|
return /* @__PURE__ */ i(
|
|
79
|
-
|
|
70
|
+
A,
|
|
80
71
|
{
|
|
81
|
-
title:
|
|
72
|
+
title: B,
|
|
82
73
|
fullWidth: !0,
|
|
83
74
|
sidebarWidth: 128,
|
|
84
75
|
legacy: !1,
|
|
85
|
-
links:
|
|
86
|
-
...
|
|
76
|
+
links: P,
|
|
77
|
+
...h,
|
|
87
78
|
headerProps: {
|
|
88
|
-
homeLink:
|
|
89
|
-
logo: /* @__PURE__ */ i("img", { src:
|
|
90
|
-
addons:
|
|
91
|
-
|
|
79
|
+
homeLink: m,
|
|
80
|
+
logo: /* @__PURE__ */ i("img", { src: W, alt: "logo" }),
|
|
81
|
+
addons: /* @__PURE__ */ i(
|
|
82
|
+
U,
|
|
83
|
+
{
|
|
84
|
+
formattedBlocklet: r,
|
|
85
|
+
addons: k,
|
|
86
|
+
sessionManagerProps: L,
|
|
87
|
+
showDomainWarningDialog: N
|
|
88
|
+
}
|
|
89
|
+
),
|
|
90
|
+
...h.headerProps
|
|
92
91
|
}
|
|
93
92
|
}
|
|
94
93
|
);
|
|
95
94
|
}
|
|
96
|
-
|
|
97
|
-
meta:
|
|
95
|
+
F.propTypes = {
|
|
96
|
+
meta: M,
|
|
98
97
|
// 如果当前用户没有权限访问任何导航菜单, 则自动跳转到 fallbackUrl, 默认值为 publicPath, 设置为 null 表示禁用自动跳转
|
|
99
98
|
fallbackUrl: t.string,
|
|
100
99
|
// 当前路径未匹配任何 nav links 时的 fallback, 默认行为跳转到首个可用的 nav link
|
|
101
100
|
invalidPathFallback: t.func,
|
|
102
101
|
headerAddons: t.oneOfType([t.func, t.node]),
|
|
103
|
-
sessionManagerProps:
|
|
102
|
+
sessionManagerProps: D,
|
|
104
103
|
links: t.oneOfType([t.array, t.func]),
|
|
105
104
|
showDomainWarningDialog: t.bool
|
|
106
105
|
};
|
|
107
106
|
export {
|
|
108
|
-
|
|
107
|
+
F as default
|
|
109
108
|
};
|
package/lib/Header/index.d.ts
CHANGED
|
@@ -18,7 +18,6 @@ type HeaderProps = {
|
|
|
18
18
|
align?: 'left' | 'right';
|
|
19
19
|
maxWidth?: false | Breakpoint;
|
|
20
20
|
showDomainWarningDialog?: boolean;
|
|
21
|
-
showWizard?: boolean;
|
|
22
21
|
};
|
|
23
22
|
declare const _default: import('react').ComponentType<HeaderProps & Omit<BoxProps, keyof HeaderProps>>;
|
|
24
23
|
export default _default;
|
package/lib/Header/index.js
CHANGED
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
import { jsx as n } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo as
|
|
3
|
-
import { useMemoizedFn as
|
|
4
|
-
import { withErrorBoundary as
|
|
5
|
-
import { ErrorFallback as
|
|
6
|
-
import { styled as
|
|
7
|
-
import { ResponsiveHeader as
|
|
8
|
-
import
|
|
9
|
-
import { useLocaleContext as
|
|
10
|
-
import { translate as
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import { mapRecursive as
|
|
17
|
-
import { formatBlockletInfo as
|
|
18
|
-
import
|
|
19
|
-
import { useWalletHiddenTopbar as
|
|
20
|
-
import
|
|
21
|
-
const
|
|
2
|
+
import { useMemo as k } from "react";
|
|
3
|
+
import { useMemoizedFn as $ } from "ahooks";
|
|
4
|
+
import { withErrorBoundary as N } from "react-error-boundary";
|
|
5
|
+
import { ErrorFallback as H } from "@arcblock/ux/lib/ErrorBoundary";
|
|
6
|
+
import { styled as y, useTheme as C, deepmerge as T, ThemeProvider as _ } from "@arcblock/ux/lib/Theme";
|
|
7
|
+
import { ResponsiveHeader as E } from "@arcblock/ux/lib/Header";
|
|
8
|
+
import B, { Products as F } from "@arcblock/ux/lib/NavMenu";
|
|
9
|
+
import { useLocaleContext as L } from "@arcblock/ux/lib/Locale/context";
|
|
10
|
+
import { translate as P } from "@arcblock/ux/lib/Locale/util";
|
|
11
|
+
import R from "@arcblock/ux/lib/hooks/use-blocklet-logo";
|
|
12
|
+
import z from "lodash/omit";
|
|
13
|
+
import A from "lodash/isFinite";
|
|
14
|
+
import M from "clsx";
|
|
15
|
+
import W from "../Icon/index.js";
|
|
16
|
+
import { mapRecursive as j, flatRecursive as S, matchPaths as U } from "../utils.js";
|
|
17
|
+
import { formatBlockletInfo as K, getLocalizedNavigation as O, publicPath as q } from "../blocklets.js";
|
|
18
|
+
import D from "../common/header-addons.js";
|
|
19
|
+
import { useWalletHiddenTopbar as G } from "../common/wallet-hidden-topbar.js";
|
|
20
|
+
import J from "../libs/with-hide-when-embed.js";
|
|
21
|
+
const Q = {
|
|
22
22
|
en: {
|
|
23
23
|
products: "Products"
|
|
24
24
|
},
|
|
25
25
|
zh: {
|
|
26
26
|
products: "产品"
|
|
27
27
|
}
|
|
28
|
-
},
|
|
28
|
+
}, V = (e) => {
|
|
29
29
|
if (!e?.length)
|
|
30
30
|
return { navItems: [], activeId: null };
|
|
31
31
|
let r = 1;
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
const s = j(e, (o) => {
|
|
33
|
+
const i = o.icon ? /* @__PURE__ */ n(W, { icon: o.icon }) : null;
|
|
34
34
|
if (o.items)
|
|
35
35
|
return {
|
|
36
36
|
id: `${r++}`,
|
|
37
37
|
label: o.title,
|
|
38
|
-
icon:
|
|
38
|
+
icon: i,
|
|
39
39
|
children: o.items
|
|
40
40
|
};
|
|
41
41
|
let l = {};
|
|
@@ -45,74 +45,72 @@ const V = {
|
|
|
45
45
|
}), {
|
|
46
46
|
id: `${r++}`,
|
|
47
47
|
label: /* @__PURE__ */ n("a", { href: o.link, ...l, children: o.title }),
|
|
48
|
-
icon:
|
|
48
|
+
icon: i,
|
|
49
49
|
description: o.description,
|
|
50
50
|
link: o.link
|
|
51
51
|
};
|
|
52
|
-
}, "items"), a =
|
|
53
|
-
return { navItems:
|
|
52
|
+
}, "items"), a = S(s), d = U(a.map((o) => o.link));
|
|
53
|
+
return { navItems: s, activeId: d >= 0 ? a[d].id : null };
|
|
54
54
|
};
|
|
55
|
-
function
|
|
55
|
+
function X({
|
|
56
56
|
meta: e = {},
|
|
57
57
|
addons: r = void 0,
|
|
58
58
|
sessionManagerProps: u = {
|
|
59
59
|
showRole: !0
|
|
60
60
|
},
|
|
61
|
-
homeLink:
|
|
61
|
+
homeLink: s = q,
|
|
62
62
|
theme: a = void 0,
|
|
63
|
-
hideNavMenu:
|
|
63
|
+
hideNavMenu: d = !1,
|
|
64
64
|
showDomainWarningDialog: o = !0,
|
|
65
|
-
|
|
66
|
-
...l
|
|
65
|
+
...i
|
|
67
66
|
}) {
|
|
68
|
-
|
|
69
|
-
const
|
|
67
|
+
G();
|
|
68
|
+
const l = C(), { locale: h } = L() || {}, v = $((t, f = {}) => P(Q, t, h, "en", f)), m = k(() => {
|
|
70
69
|
const t = Object.assign({}, window.blocklet, e);
|
|
71
70
|
try {
|
|
72
|
-
return
|
|
71
|
+
return K(t);
|
|
73
72
|
} catch (f) {
|
|
74
73
|
return console.error("Failed to format blocklet info", f, t), t;
|
|
75
74
|
}
|
|
76
|
-
}, [e]), c =
|
|
75
|
+
}, [e]), c = k(() => T(l, a), [l, a]), x = R({
|
|
77
76
|
meta: e,
|
|
78
77
|
theme: a
|
|
79
78
|
});
|
|
80
79
|
if (!m.appName)
|
|
81
80
|
return null;
|
|
82
|
-
const
|
|
83
|
-
return
|
|
84
|
-
label:
|
|
81
|
+
const I = O(m?.navigation?.header, h), b = V(I), { navItems: p, activeId: w } = b, g = parseInt(window.blocklet?.USE_ARCBLOCK_THEME, 10);
|
|
82
|
+
return A(g) && p.splice(g, 0, {
|
|
83
|
+
label: v("products"),
|
|
85
84
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
86
|
-
children: ({ isOpen: t }) => /* @__PURE__ */ n(
|
|
87
|
-
}), /* @__PURE__ */ n(
|
|
88
|
-
|
|
85
|
+
children: ({ isOpen: t }) => /* @__PURE__ */ n(F, { isOpen: t })
|
|
86
|
+
}), /* @__PURE__ */ n(_, { theme: c, children: /* @__PURE__ */ n(
|
|
87
|
+
Y,
|
|
89
88
|
{
|
|
90
|
-
homeLink:
|
|
91
|
-
logo: /* @__PURE__ */ n("img", { src:
|
|
89
|
+
homeLink: s,
|
|
90
|
+
logo: /* @__PURE__ */ n("img", { src: x, alt: "logo" }),
|
|
92
91
|
addons: (
|
|
93
92
|
// @ts-ignore
|
|
94
93
|
/* @__PURE__ */ n(
|
|
95
|
-
|
|
94
|
+
D,
|
|
96
95
|
{
|
|
97
96
|
formattedBlocklet: m,
|
|
98
|
-
addons: typeof r == "function" ? (t) => r(t, { navigation:
|
|
97
|
+
addons: typeof r == "function" ? (t) => r(t, { navigation: b }) : r,
|
|
99
98
|
sessionManagerProps: u,
|
|
100
|
-
showDomainWarningDialog: o
|
|
101
|
-
showWizard: d
|
|
99
|
+
showDomainWarningDialog: o
|
|
102
100
|
}
|
|
103
101
|
)
|
|
104
102
|
),
|
|
105
|
-
...
|
|
106
|
-
$bordered:
|
|
103
|
+
...z(i, ["bordered"]),
|
|
104
|
+
$bordered: i?.bordered,
|
|
107
105
|
$bgcolor: c.palette.background.default,
|
|
108
|
-
className:
|
|
109
|
-
children:
|
|
106
|
+
className: M("blocklet__header", i.className),
|
|
107
|
+
children: d || !p?.length ? null : ({ isMobile: t }) => (
|
|
110
108
|
// @ts-ignore
|
|
111
109
|
/* @__PURE__ */ n(
|
|
112
|
-
|
|
110
|
+
B,
|
|
113
111
|
{
|
|
114
112
|
mode: t ? "inline" : "horizontal",
|
|
115
|
-
activeId:
|
|
113
|
+
activeId: w,
|
|
116
114
|
items: p,
|
|
117
115
|
className: "header-nav",
|
|
118
116
|
bgColor: "transparent",
|
|
@@ -124,7 +122,7 @@ function Y({
|
|
|
124
122
|
}
|
|
125
123
|
) });
|
|
126
124
|
}
|
|
127
|
-
const
|
|
125
|
+
const Y = y(E)`
|
|
128
126
|
${({ $bgcolor: e }) => `background-color: ${e || "#fff"};`}
|
|
129
127
|
.header-logo {
|
|
130
128
|
min-width: 44px;
|
|
@@ -135,9 +133,9 @@ const Z = C(B)`
|
|
|
135
133
|
min-width: 32px;
|
|
136
134
|
}
|
|
137
135
|
}
|
|
138
|
-
`,
|
|
139
|
-
FallbackComponent:
|
|
136
|
+
`, wo = N(J(X), {
|
|
137
|
+
FallbackComponent: H
|
|
140
138
|
});
|
|
141
139
|
export {
|
|
142
|
-
|
|
140
|
+
wo as default
|
|
143
141
|
};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { default as PropTypes } from 'prop-types';
|
|
2
2
|
import { SessionManagerProps } from '../types';
|
|
3
|
-
declare function HeaderAddons({ formattedBlocklet, addons, showDomainWarningDialog, sessionManagerProps,
|
|
3
|
+
declare function HeaderAddons({ formattedBlocklet, addons, showDomainWarningDialog, sessionManagerProps, }: {
|
|
4
4
|
formattedBlocklet: any;
|
|
5
5
|
addons?: null | undefined;
|
|
6
6
|
showDomainWarningDialog?: boolean | undefined;
|
|
7
7
|
sessionManagerProps?: {
|
|
8
8
|
showRole: boolean;
|
|
9
9
|
} | undefined;
|
|
10
|
-
showWizard?: boolean | undefined;
|
|
11
10
|
}): import('react').FunctionComponentElement<import('react').FragmentProps>;
|
|
12
11
|
declare namespace HeaderAddons {
|
|
13
12
|
namespace propTypes {
|
|
@@ -15,7 +14,6 @@ declare namespace HeaderAddons {
|
|
|
15
14
|
export let addons: PropTypes.Requireable<NonNullable<((...args: any[]) => any) | PropTypes.ReactNodeLike>>;
|
|
16
15
|
export { SessionManagerProps as sessionManagerProps };
|
|
17
16
|
export let showDomainWarningDialog: PropTypes.Requireable<boolean>;
|
|
18
|
-
export let showWizard: PropTypes.Requireable<boolean>;
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
export default HeaderAddons;
|
|
@@ -1,132 +1,71 @@
|
|
|
1
|
-
import { jsx as
|
|
1
|
+
import { jsx as s, Fragment as v } from "react/jsx-runtime";
|
|
2
2
|
import "iconify-icon";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
addons: i = null,
|
|
22
|
-
showDomainWarningDialog: y = !0,
|
|
23
|
-
sessionManagerProps: w = { showRole: !0 },
|
|
24
|
-
showWizard: T = !1
|
|
3
|
+
import r from "prop-types";
|
|
4
|
+
import { use as b, createElement as k } from "react";
|
|
5
|
+
import { SessionContext as w } from "@arcblock/did-connect/lib/Session";
|
|
6
|
+
import L from "@arcblock/ux/lib/Config/theme-mode-toggle";
|
|
7
|
+
import { useLocaleContext as N } from "@arcblock/ux/lib/Locale/context";
|
|
8
|
+
import T from "@arcblock/ux/lib/Locale/selector";
|
|
9
|
+
import C from "@arcblock/ux/lib/SessionBlocklet";
|
|
10
|
+
import R from "@arcblock/ux/lib/SessionUser";
|
|
11
|
+
import { getLocalizedNavigation as S, filterNavByRole as M } from "../blocklets.js";
|
|
12
|
+
import { SessionManagerProps as B } from "../types.js";
|
|
13
|
+
import D from "./domain-warning.js";
|
|
14
|
+
import P from "./notification-addon.js";
|
|
15
|
+
const j = () => !!(window?.blocklet?.navigation ?? []).find((o) => o.id === "/userCenter/notification");
|
|
16
|
+
function x({
|
|
17
|
+
formattedBlocklet: l,
|
|
18
|
+
addons: o = null,
|
|
19
|
+
showDomainWarningDialog: m = !0,
|
|
20
|
+
sessionManagerProps: u = { showRole: !0 }
|
|
25
21
|
}) {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (i && typeof i != "function")
|
|
40
|
-
return Array.isArray(i) ? i : [i];
|
|
41
|
-
let o = [];
|
|
42
|
-
if ($() && o.push(/* @__PURE__ */ e(H, { session: n.session }, "notification-addon")), k && r && z.length > 1 && o.push(/* @__PURE__ */ e(P, { showText: !1 }, "locale-selector")), o.push(/* @__PURE__ */ e(j, {}, "theme-mode-toggle")), T && o.push(
|
|
43
|
-
/* @__PURE__ */ e(
|
|
44
|
-
M,
|
|
45
|
-
{
|
|
46
|
-
title: b("setup.wizardTooltip"),
|
|
47
|
-
open: t,
|
|
48
|
-
placement: "bottom",
|
|
49
|
-
arrow: !0,
|
|
50
|
-
children: /* @__PURE__ */ e(
|
|
51
|
-
R,
|
|
52
|
-
{
|
|
53
|
-
size: "small",
|
|
54
|
-
onClick: () => {
|
|
55
|
-
p(!0), c(!1);
|
|
56
|
-
},
|
|
57
|
-
sx: {
|
|
58
|
-
display: { xs: "none", md: "flex" },
|
|
59
|
-
color: "text.secondary",
|
|
60
|
-
...t && {
|
|
61
|
-
backgroundColor: "action.hover",
|
|
62
|
-
"@keyframes pulse": {
|
|
63
|
-
"0%": { opacity: 0.8 },
|
|
64
|
-
"50%": { opacity: 0.5 },
|
|
65
|
-
"100%": { opacity: 0.8 }
|
|
66
|
-
},
|
|
67
|
-
animation: "pulse 2s infinite"
|
|
68
|
-
}
|
|
69
|
-
},
|
|
70
|
-
children: /* @__PURE__ */ e("iconify-icon", { icon: B, height: 20 })
|
|
71
|
-
}
|
|
72
|
-
)
|
|
73
|
-
},
|
|
74
|
-
`wizard-toggle-${t}`
|
|
75
|
-
),
|
|
76
|
-
/* @__PURE__ */ e(
|
|
77
|
-
V,
|
|
78
|
-
{
|
|
79
|
-
show: d,
|
|
80
|
-
onChangeVisible: (a) => {
|
|
81
|
-
p(a), !a && d && c(!0);
|
|
82
|
-
},
|
|
83
|
-
onFinished: () => {
|
|
84
|
-
p(!1), c(!1);
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
"wizard-modal"
|
|
88
|
-
)
|
|
89
|
-
), A && n) {
|
|
90
|
-
const a = [];
|
|
91
|
-
v && (f ? f.slice(0, 5) : []).forEach((l) => {
|
|
92
|
-
a.push({
|
|
93
|
-
label: l.title,
|
|
94
|
-
icon: l.icon ? /* @__PURE__ */ e("iconify-icon", { icon: l.icon, height: 24, style: { marginRight: 8 } }) : null,
|
|
22
|
+
const n = b(w), { locale: i, languages: p } = N() || {}, { enableConnect: g = !0, enableLocale: d = !0 } = l, h = !!n?.session?.user;
|
|
23
|
+
let a = S(l?.navigation?.sessionManager, i) || [];
|
|
24
|
+
a = M(a, n?.session?.user?.role);
|
|
25
|
+
const c = (() => {
|
|
26
|
+
if (o && typeof o != "function")
|
|
27
|
+
return Array.isArray(o) ? o : [o];
|
|
28
|
+
let e = [];
|
|
29
|
+
if (j() && e.push(/* @__PURE__ */ s(P, { session: n.session }, "notification-addon")), d && i && p.length > 1 && e.push(/* @__PURE__ */ s(T, { showText: !1 }, "locale-selector")), e.push(/* @__PURE__ */ s(L, {}, "theme-mode-toggle")), g && n) {
|
|
30
|
+
const f = [];
|
|
31
|
+
h && (a ? a.slice(0, 5) : []).forEach((t) => {
|
|
32
|
+
f.push({
|
|
33
|
+
label: t.title,
|
|
34
|
+
icon: t.icon ? /* @__PURE__ */ s("iconify-icon", { icon: t.icon, height: 24, style: { marginRight: 8 } }) : null,
|
|
95
35
|
component: "a",
|
|
96
|
-
href:
|
|
97
|
-
key:
|
|
36
|
+
href: t.link,
|
|
37
|
+
key: t.link
|
|
98
38
|
});
|
|
99
|
-
}),
|
|
100
|
-
/* @__PURE__ */
|
|
101
|
-
|
|
39
|
+
}), e.push(/* @__PURE__ */ s(C, { session: n.session, locale: i }, "session-blocklet")), e.push(
|
|
40
|
+
/* @__PURE__ */ s(
|
|
41
|
+
R,
|
|
102
42
|
{
|
|
103
43
|
session: n.session,
|
|
104
|
-
locale:
|
|
105
|
-
menu:
|
|
44
|
+
locale: i,
|
|
45
|
+
menu: f,
|
|
106
46
|
showRole: !0,
|
|
107
|
-
...
|
|
47
|
+
...u
|
|
108
48
|
},
|
|
109
49
|
"session-user"
|
|
110
50
|
)
|
|
111
51
|
);
|
|
112
52
|
}
|
|
113
|
-
return typeof
|
|
114
|
-
})(),
|
|
115
|
-
|
|
116
|
-
...
|
|
53
|
+
return typeof o == "function" && (e = o(e) || []), e;
|
|
54
|
+
})(), y = Array.isArray(c) ? c : [c], A = [
|
|
55
|
+
m ? /* @__PURE__ */ s(D, { session: n?.session, locale: i }) : null,
|
|
56
|
+
...y
|
|
117
57
|
].filter(Boolean);
|
|
118
|
-
return
|
|
58
|
+
return k(v, null, ...A);
|
|
119
59
|
}
|
|
120
|
-
|
|
121
|
-
formattedBlocklet:
|
|
60
|
+
x.propTypes = {
|
|
61
|
+
formattedBlocklet: r.object.isRequired,
|
|
122
62
|
// 需要考虑 定制的 addons 与内置的 连接钱包/选择语言 addons 共存的情况
|
|
123
63
|
// - PropTypes.func: 可以把自定义 addons 插在 session-manager 或 locale-selector (如果存在的话) 前/中/后
|
|
124
64
|
// - PropTypes.node: 将 addons 原样传给 UX Header 组件
|
|
125
|
-
addons:
|
|
126
|
-
sessionManagerProps:
|
|
127
|
-
showDomainWarningDialog:
|
|
128
|
-
showWizard: s.bool
|
|
65
|
+
addons: r.oneOfType([r.func, r.node]),
|
|
66
|
+
sessionManagerProps: B,
|
|
67
|
+
showDomainWarningDialog: r.bool
|
|
129
68
|
};
|
|
130
69
|
export {
|
|
131
|
-
|
|
70
|
+
x as default
|
|
132
71
|
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { default as PropTypes } from 'prop-types';
|
|
2
|
-
declare function WizardModal({ onFinished, show, onChangeVisible }: {
|
|
2
|
+
declare function WizardModal({ onFinished, show, onChangeVisible, loadingText, }: {
|
|
3
3
|
onFinished?: (() => void) | undefined;
|
|
4
4
|
show?: boolean | undefined;
|
|
5
5
|
onChangeVisible?: (() => void) | undefined;
|
|
6
|
+
loadingText?: string | undefined;
|
|
6
7
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
7
8
|
declare namespace WizardModal {
|
|
8
9
|
namespace propTypes {
|
|
9
10
|
let onFinished: PropTypes.Requireable<(...args: any[]) => any>;
|
|
10
11
|
let show: PropTypes.Requireable<boolean>;
|
|
11
12
|
let onChangeVisible: PropTypes.Requireable<(...args: any[]) => any>;
|
|
13
|
+
let loadingText: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
12
14
|
}
|
|
13
15
|
}
|
|
14
16
|
export default WizardModal;
|
|
@@ -1,46 +1,51 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useLocaleContext as
|
|
3
|
-
import { useTheme as
|
|
4
|
-
import
|
|
5
|
-
import { useState as
|
|
6
|
-
import { withQuery as
|
|
7
|
-
const
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { jsxs as x, jsx as i } from "react/jsx-runtime";
|
|
2
|
+
import { useLocaleContext as P } from "@arcblock/ux/lib/Locale/context";
|
|
3
|
+
import { useTheme as T, useMediaQuery as j, Dialog as D, Box as R, CircularProgress as E, Typography as M } from "@mui/material";
|
|
4
|
+
import a from "prop-types";
|
|
5
|
+
import { useState as g, useRef as h, useEffect as s } from "react";
|
|
6
|
+
import { withQuery as A, joinURL as F } from "ufo";
|
|
7
|
+
const b = "/.well-known/service/wizard/bind-account";
|
|
8
|
+
function B({
|
|
9
|
+
onFinished: y = () => {
|
|
10
|
+
},
|
|
11
|
+
show: o = !1,
|
|
12
|
+
onChangeVisible: v = () => {
|
|
13
|
+
},
|
|
14
|
+
loadingText: l = ""
|
|
15
|
+
}) {
|
|
16
|
+
const [r, n] = g(o), [c, d] = g(!1), [C, u] = g(() => localStorage.getItem("wizard-current-url") || b), z = h(y), f = h(), m = h(null), { locale: I } = P(), L = T(), p = j(L.breakpoints.down("sm"));
|
|
17
|
+
if (z.current = y, f.current = () => {
|
|
18
|
+
if (m.current?.contentWindow)
|
|
14
19
|
try {
|
|
15
|
-
const t = new URL(
|
|
16
|
-
localStorage.setItem("wizard-current-url", t),
|
|
20
|
+
const t = new URL(m.current.contentWindow.location.href).pathname;
|
|
21
|
+
localStorage.setItem("wizard-current-url", t), u(t);
|
|
17
22
|
} catch (e) {
|
|
18
|
-
|
|
23
|
+
u(b), console.warn("Failed to save wizard URL:", e);
|
|
19
24
|
}
|
|
20
|
-
localStorage.setItem("wizard-completed", "true"), n(!1),
|
|
21
|
-
},
|
|
25
|
+
localStorage.setItem("wizard-completed", "true"), n(!1), v(!1);
|
|
26
|
+
}, s(() => {
|
|
22
27
|
o !== r && n(o);
|
|
23
|
-
}, [o]),
|
|
24
|
-
!r &&
|
|
25
|
-
}, [r]),
|
|
28
|
+
}, [o]), s(() => {
|
|
29
|
+
!r && c && d(!1);
|
|
30
|
+
}, [r]), s(() => {
|
|
26
31
|
const e = (t) => {
|
|
27
32
|
if (t.origin !== window.location.origin)
|
|
28
33
|
return;
|
|
29
|
-
const { type:
|
|
30
|
-
switch (
|
|
34
|
+
const { type: k, data: U } = t.data || {};
|
|
35
|
+
switch (k) {
|
|
31
36
|
case "wizard.loaded":
|
|
32
|
-
|
|
37
|
+
d(!0);
|
|
33
38
|
break;
|
|
34
39
|
case "wizard.finished": {
|
|
35
|
-
n(!1),
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}) :
|
|
40
|
+
n(!1), u(b), localStorage.removeItem("wizard-current-url"), localStorage.setItem("wizard-completed", "true");
|
|
41
|
+
const w = z.current?.(U);
|
|
42
|
+
w instanceof Promise ? w.then((W) => {
|
|
43
|
+
W !== !1 && window.location.reload();
|
|
44
|
+
}) : w !== !1 && window.location.reload();
|
|
40
45
|
break;
|
|
41
46
|
}
|
|
42
47
|
case "wizard.close": {
|
|
43
|
-
|
|
48
|
+
f.current();
|
|
44
49
|
break;
|
|
45
50
|
}
|
|
46
51
|
}
|
|
@@ -48,21 +53,21 @@ function D({ onFinished: b = () => {
|
|
|
48
53
|
return window.addEventListener("message", e), () => {
|
|
49
54
|
window.removeEventListener("message", e);
|
|
50
55
|
};
|
|
51
|
-
}, []),
|
|
56
|
+
}, []), s(() => {
|
|
52
57
|
localStorage.getItem("wizard-completed") || n(!0);
|
|
53
58
|
}, []), !r)
|
|
54
59
|
return null;
|
|
55
|
-
const
|
|
56
|
-
locale:
|
|
60
|
+
const S = A(F(window.location.origin, C), {
|
|
61
|
+
locale: I
|
|
57
62
|
});
|
|
58
|
-
return /* @__PURE__ */
|
|
59
|
-
|
|
63
|
+
return /* @__PURE__ */ x(
|
|
64
|
+
D,
|
|
60
65
|
{
|
|
61
66
|
open: r,
|
|
62
|
-
onClose: () =>
|
|
67
|
+
onClose: () => f.current(),
|
|
63
68
|
fullWidth: !0,
|
|
64
|
-
maxWidth:
|
|
65
|
-
fullScreen:
|
|
69
|
+
maxWidth: p ? !1 : "md",
|
|
70
|
+
fullScreen: p,
|
|
66
71
|
slotProps: {
|
|
67
72
|
paper: {
|
|
68
73
|
sx: {
|
|
@@ -70,7 +75,7 @@ function D({ onFinished: b = () => {
|
|
|
70
75
|
borderRadius: 0,
|
|
71
76
|
position: "relative",
|
|
72
77
|
overflow: "hidden",
|
|
73
|
-
...
|
|
78
|
+
...p ? { borderRadius: 0 } : {
|
|
74
79
|
borderRadius: 1,
|
|
75
80
|
height: "max(800px, 80vh)"
|
|
76
81
|
}
|
|
@@ -83,11 +88,11 @@ function D({ onFinished: b = () => {
|
|
|
83
88
|
}
|
|
84
89
|
},
|
|
85
90
|
children: [
|
|
86
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ i(
|
|
87
92
|
"iframe",
|
|
88
93
|
{
|
|
89
|
-
ref:
|
|
90
|
-
src:
|
|
94
|
+
ref: m,
|
|
95
|
+
src: S,
|
|
91
96
|
title: "Setup Wizard",
|
|
92
97
|
style: {
|
|
93
98
|
width: "100%",
|
|
@@ -95,14 +100,14 @@ function D({ onFinished: b = () => {
|
|
|
95
100
|
border: 0,
|
|
96
101
|
padding: 0,
|
|
97
102
|
margin: 0,
|
|
98
|
-
opacity:
|
|
103
|
+
opacity: c ? 1 : 0,
|
|
99
104
|
transition: "opacity 0.3s ease-in-out"
|
|
100
105
|
},
|
|
101
|
-
onLoad: () =>
|
|
106
|
+
onLoad: () => d(!0)
|
|
102
107
|
}
|
|
103
108
|
),
|
|
104
|
-
|
|
105
|
-
|
|
109
|
+
c ? null : /* @__PURE__ */ i(
|
|
110
|
+
R,
|
|
106
111
|
{
|
|
107
112
|
sx: {
|
|
108
113
|
position: "absolute",
|
|
@@ -115,18 +120,22 @@ function D({ onFinished: b = () => {
|
|
|
115
120
|
alignItems: "center",
|
|
116
121
|
bgcolor: "background.paper"
|
|
117
122
|
},
|
|
118
|
-
children: /* @__PURE__ */
|
|
123
|
+
children: /* @__PURE__ */ x(R, { sx: { display: "flex", alignItems: "center", flexDirection: "column", gap: 1 }, children: [
|
|
124
|
+
/* @__PURE__ */ i(E, {}),
|
|
125
|
+
typeof l == "string" ? /* @__PURE__ */ i(M, { variant: "body1", children: l }) : l
|
|
126
|
+
] })
|
|
119
127
|
}
|
|
120
128
|
)
|
|
121
129
|
]
|
|
122
130
|
}
|
|
123
131
|
);
|
|
124
132
|
}
|
|
125
|
-
|
|
126
|
-
onFinished:
|
|
127
|
-
show:
|
|
128
|
-
onChangeVisible:
|
|
133
|
+
B.propTypes = {
|
|
134
|
+
onFinished: a.func,
|
|
135
|
+
show: a.bool,
|
|
136
|
+
onChangeVisible: a.func,
|
|
137
|
+
loadingText: a.node
|
|
129
138
|
};
|
|
130
139
|
export {
|
|
131
|
-
|
|
140
|
+
B as default
|
|
132
141
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/ui-react",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.39",
|
|
4
4
|
"description": "Some useful front-end web components that can be used in Blocklets.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@abtnode/constant": "^1.16.46",
|
|
37
37
|
"@abtnode/util": "^1.16.46",
|
|
38
|
-
"@arcblock/bridge": "3.0.
|
|
39
|
-
"@arcblock/icons": "3.0.
|
|
40
|
-
"@arcblock/react-hooks": "3.0.
|
|
38
|
+
"@arcblock/bridge": "3.0.39",
|
|
39
|
+
"@arcblock/icons": "3.0.39",
|
|
40
|
+
"@arcblock/react-hooks": "3.0.39",
|
|
41
41
|
"@arcblock/ws": "^1.21.0",
|
|
42
42
|
"@blocklet/constant": "^1.16.46",
|
|
43
43
|
"@blocklet/did-space-react": "^1.1.11",
|
|
@@ -91,5 +91,5 @@
|
|
|
91
91
|
"jest": "^29.7.0",
|
|
92
92
|
"unbuild": "^2.0.0"
|
|
93
93
|
},
|
|
94
|
-
"gitHead": "
|
|
94
|
+
"gitHead": "0b0937b6a161c7332622ae0001849a7d3b2904f1"
|
|
95
95
|
}
|
package/src/Dashboard/index.jsx
CHANGED
package/src/Header/index.tsx
CHANGED
|
@@ -93,7 +93,6 @@ type HeaderProps = {
|
|
|
93
93
|
align?: 'left' | 'right';
|
|
94
94
|
maxWidth?: false | Breakpoint;
|
|
95
95
|
showDomainWarningDialog?: boolean;
|
|
96
|
-
showWizard?: boolean;
|
|
97
96
|
};
|
|
98
97
|
|
|
99
98
|
/**
|
|
@@ -111,7 +110,6 @@ function Header({
|
|
|
111
110
|
theme: themeOverrides = undefined,
|
|
112
111
|
hideNavMenu = false,
|
|
113
112
|
showDomainWarningDialog = true,
|
|
114
|
-
showWizard = false,
|
|
115
113
|
...rest
|
|
116
114
|
}: HeaderProps & Omit<BoxProps, keyof HeaderProps>) {
|
|
117
115
|
useWalletHiddenTopbar();
|
|
@@ -166,7 +164,6 @@ function Header({
|
|
|
166
164
|
// @ts-ignore
|
|
167
165
|
sessionManagerProps={sessionManagerProps}
|
|
168
166
|
showDomainWarningDialog={showDomainWarningDialog}
|
|
169
|
-
showWizard={showWizard}
|
|
170
167
|
/>
|
|
171
168
|
);
|
|
172
169
|
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import 'iconify-icon';
|
|
2
2
|
|
|
3
|
-
import { use, createElement, useState, useEffect } from 'react';
|
|
4
3
|
import PropTypes from 'prop-types';
|
|
5
|
-
import {
|
|
6
|
-
import WandIcon from '@iconify-icons/tabler/wand';
|
|
4
|
+
import { createElement, use } from 'react';
|
|
7
5
|
|
|
8
6
|
// FIXME: 直接从 react 中 import Fragment 可能会在 vite 下出错,先暂时从 react/jsx-runtime 导入 Fragment 来跳过这个问题
|
|
9
|
-
import { Fragment } from 'react/jsx-runtime';
|
|
10
7
|
import { SessionContext } from '@arcblock/did-connect/lib/Session';
|
|
11
|
-
import SessionUser from '@arcblock/ux/lib/SessionUser';
|
|
12
|
-
import SessionBlocklet from '@arcblock/ux/lib/SessionBlocklet';
|
|
13
|
-
import LocaleSelector from '@arcblock/ux/lib/Locale/selector';
|
|
14
|
-
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
15
8
|
import ThemeModeToggle from '@arcblock/ux/lib/Config/theme-mode-toggle';
|
|
9
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
10
|
+
import LocaleSelector from '@arcblock/ux/lib/Locale/selector';
|
|
11
|
+
import SessionBlocklet from '@arcblock/ux/lib/SessionBlocklet';
|
|
12
|
+
import SessionUser from '@arcblock/ux/lib/SessionUser';
|
|
13
|
+
import { Fragment } from 'react/jsx-runtime';
|
|
16
14
|
|
|
15
|
+
import { filterNavByRole, getLocalizedNavigation } from '../blocklets';
|
|
17
16
|
import { SessionManagerProps } from '../types';
|
|
18
|
-
import { getLocalizedNavigation, filterNavByRole } from '../blocklets';
|
|
19
|
-
import NotificationAddon from './notification-addon';
|
|
20
17
|
import DomainWarning from './domain-warning';
|
|
21
|
-
import
|
|
18
|
+
import NotificationAddon from './notification-addon';
|
|
22
19
|
|
|
23
20
|
const hasNotification = () => {
|
|
24
21
|
const navigations = window?.blocklet?.navigation ?? [];
|
|
@@ -31,25 +28,7 @@ export default function HeaderAddons({
|
|
|
31
28
|
addons = null,
|
|
32
29
|
showDomainWarningDialog = true,
|
|
33
30
|
sessionManagerProps = { showRole: true },
|
|
34
|
-
showWizard = false,
|
|
35
31
|
}) {
|
|
36
|
-
const [wizardOpen, setWizardOpen] = useState(false);
|
|
37
|
-
const [showTooltip, setShowTooltip] = useState(false);
|
|
38
|
-
const { t } = useLocaleContext();
|
|
39
|
-
|
|
40
|
-
// 处理 tooltip 倒计时
|
|
41
|
-
useEffect(() => {
|
|
42
|
-
let timer;
|
|
43
|
-
if (showTooltip) {
|
|
44
|
-
timer = setTimeout(() => {
|
|
45
|
-
setShowTooltip(false);
|
|
46
|
-
}, 3000); // 3秒后自动隐藏
|
|
47
|
-
}
|
|
48
|
-
return () => {
|
|
49
|
-
if (timer) clearTimeout(timer);
|
|
50
|
-
};
|
|
51
|
-
}, [showTooltip]);
|
|
52
|
-
|
|
53
32
|
const sessionCtx = use(SessionContext);
|
|
54
33
|
const { locale, languages } = useLocaleContext() || {};
|
|
55
34
|
const { enableConnect = true, enableLocale = true } = formattedBlocklet;
|
|
@@ -77,54 +56,6 @@ export default function HeaderAddons({
|
|
|
77
56
|
// 切换明暗主题
|
|
78
57
|
addonsArray.push(<ThemeModeToggle key="theme-mode-toggle" />);
|
|
79
58
|
|
|
80
|
-
// Wizard 开关
|
|
81
|
-
if (showWizard) {
|
|
82
|
-
addonsArray.push(
|
|
83
|
-
<Tooltip
|
|
84
|
-
key={`wizard-toggle-${showTooltip}`}
|
|
85
|
-
title={t('setup.wizardTooltip')}
|
|
86
|
-
open={showTooltip}
|
|
87
|
-
placement="bottom"
|
|
88
|
-
arrow>
|
|
89
|
-
<IconButton
|
|
90
|
-
size="small"
|
|
91
|
-
onClick={() => {
|
|
92
|
-
setWizardOpen(true);
|
|
93
|
-
setShowTooltip(false); // 点击后隐藏 tooltip
|
|
94
|
-
}}
|
|
95
|
-
sx={{
|
|
96
|
-
display: { xs: 'none', md: 'flex' },
|
|
97
|
-
color: 'text.secondary',
|
|
98
|
-
...(showTooltip && {
|
|
99
|
-
backgroundColor: 'action.hover',
|
|
100
|
-
'@keyframes pulse': {
|
|
101
|
-
'0%': { opacity: 0.8 },
|
|
102
|
-
'50%': { opacity: 0.5 },
|
|
103
|
-
'100%': { opacity: 0.8 },
|
|
104
|
-
},
|
|
105
|
-
animation: 'pulse 2s infinite',
|
|
106
|
-
}),
|
|
107
|
-
}}>
|
|
108
|
-
<iconify-icon icon={WandIcon} height={20} />
|
|
109
|
-
</IconButton>
|
|
110
|
-
</Tooltip>,
|
|
111
|
-
<WizardModal
|
|
112
|
-
key="wizard-modal"
|
|
113
|
-
show={wizardOpen}
|
|
114
|
-
onChangeVisible={(visible) => {
|
|
115
|
-
setWizardOpen(visible);
|
|
116
|
-
if (!visible && wizardOpen) {
|
|
117
|
-
setShowTooltip(true);
|
|
118
|
-
}
|
|
119
|
-
}}
|
|
120
|
-
onFinished={() => {
|
|
121
|
-
setWizardOpen(false);
|
|
122
|
-
setShowTooltip(false);
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
59
|
// 启用了连接钱包并且检测到了 session context
|
|
129
60
|
if (enableConnect && sessionCtx) {
|
|
130
61
|
const menu = [];
|
|
@@ -180,5 +111,4 @@ HeaderAddons.propTypes = {
|
|
|
180
111
|
addons: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
|
|
181
112
|
sessionManagerProps: SessionManagerProps,
|
|
182
113
|
showDomainWarningDialog: PropTypes.bool,
|
|
183
|
-
showWizard: PropTypes.bool,
|
|
184
114
|
};
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
-
import { Box, CircularProgress, Dialog, useMediaQuery, useTheme } from '@mui/material';
|
|
2
|
+
import { Box, CircularProgress, Dialog, Typography, useMediaQuery, useTheme } from '@mui/material';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import { useEffect, useRef, useState } from 'react';
|
|
5
5
|
import { joinURL, withQuery } from 'ufo';
|
|
6
6
|
|
|
7
7
|
const DEFAULT_WIZARD_PATH = '/.well-known/service/wizard/bind-account';
|
|
8
8
|
|
|
9
|
-
export default function WizardModal({
|
|
9
|
+
export default function WizardModal({
|
|
10
|
+
onFinished = () => {},
|
|
11
|
+
show = false,
|
|
12
|
+
onChangeVisible = () => {},
|
|
13
|
+
loadingText = '',
|
|
14
|
+
}) {
|
|
10
15
|
const [open, setOpen] = useState(show);
|
|
11
16
|
const [loaded, setLoaded] = useState(false);
|
|
12
17
|
const [currentUrl, setCurrentUrl] = useState(() => {
|
|
@@ -169,7 +174,10 @@ export default function WizardModal({ onFinished = () => {}, show = false, onCha
|
|
|
169
174
|
alignItems: 'center',
|
|
170
175
|
bgcolor: 'background.paper',
|
|
171
176
|
}}>
|
|
172
|
-
<
|
|
177
|
+
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column', gap: 1 }}>
|
|
178
|
+
<CircularProgress />
|
|
179
|
+
{typeof loadingText === 'string' ? <Typography variant="body1">{loadingText}</Typography> : loadingText}
|
|
180
|
+
</Box>
|
|
173
181
|
</Box>
|
|
174
182
|
)}
|
|
175
183
|
</Dialog>
|
|
@@ -180,4 +188,5 @@ WizardModal.propTypes = {
|
|
|
180
188
|
onFinished: PropTypes.func,
|
|
181
189
|
show: PropTypes.bool,
|
|
182
190
|
onChangeVisible: PropTypes.func,
|
|
191
|
+
loadingText: PropTypes.node,
|
|
183
192
|
};
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# WizardModal 使用示例
|
|
2
|
-
|
|
3
|
-
WizardModal 是一个自动弹窗的 iframe 组件,用于在页面加载时显示向导界面。
|
|
4
|
-
|
|
5
|
-
## 基本用法
|
|
6
|
-
|
|
7
|
-
### 在 Header 组件中使用
|
|
8
|
-
|
|
9
|
-
```jsx
|
|
10
|
-
import { Header } from '@arcblock/blocklet-ui-react';
|
|
11
|
-
|
|
12
|
-
function App() {
|
|
13
|
-
return (
|
|
14
|
-
<Header
|
|
15
|
-
meta={blockletMeta}
|
|
16
|
-
// 默认不显示 wizard 按钮,设置为 true 启用
|
|
17
|
-
showWizard={true}
|
|
18
|
-
/>
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### 默认行为
|
|
24
|
-
|
|
25
|
-
```jsx
|
|
26
|
-
// 默认不显示 wizard 按钮
|
|
27
|
-
<Header meta={blockletMeta} />
|
|
28
|
-
|
|
29
|
-
// 显示 wizard 按钮
|
|
30
|
-
<Header meta={blockletMeta} showWizard={true} />
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 重置向导状态
|
|
34
|
-
|
|
35
|
-
```javascript
|
|
36
|
-
// 清除已完成标记,下次刷新页面时会重新显示向导
|
|
37
|
-
localStorage.removeItem('wizard-completed');
|
|
38
|
-
window.location.reload();
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### 启用向导
|
|
42
|
-
|
|
43
|
-
```jsx
|
|
44
|
-
<Header
|
|
45
|
-
meta={blockletMeta}
|
|
46
|
-
showWizard={true} // 设置为 true 显示向导按钮
|
|
47
|
-
/>
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### 自定义向导 URL
|
|
51
|
-
|
|
52
|
-
```jsx
|
|
53
|
-
<Header
|
|
54
|
-
meta={blockletMeta}
|
|
55
|
-
wizardUrl="/.well-known/service/wizard/custom-setup"
|
|
56
|
-
onWizardFinished={(data) => {
|
|
57
|
-
console.log('自定义向导完成:', data);
|
|
58
|
-
}}
|
|
59
|
-
/>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### 使用外部 URL
|
|
63
|
-
|
|
64
|
-
```jsx
|
|
65
|
-
<Header
|
|
66
|
-
meta={blockletMeta}
|
|
67
|
-
wizardUrl="https://external-wizard.example.com/setup"
|
|
68
|
-
onWizardFinished={(data) => {
|
|
69
|
-
console.log('外部向导完成:', data);
|
|
70
|
-
}}
|
|
71
|
-
/>
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## 直接使用 WizardModal 组件
|
|
75
|
-
|
|
76
|
-
```jsx
|
|
77
|
-
import { WizardModal } from '@arcblock/blocklet-ui-react/lib/common/wizard-modal';
|
|
78
|
-
|
|
79
|
-
function MyComponent() {
|
|
80
|
-
const [showWizard, setShowWizard] = useState(false);
|
|
81
|
-
|
|
82
|
-
return (
|
|
83
|
-
<div>
|
|
84
|
-
<button onClick={() => setShowWizard(true)}>打开向导</button>
|
|
85
|
-
|
|
86
|
-
<WizardModal
|
|
87
|
-
open={showWizard}
|
|
88
|
-
wizardUrl="/.well-known/service/wizard/bind-account"
|
|
89
|
-
onFinished={(data) => {
|
|
90
|
-
console.log('向导完成:', data);
|
|
91
|
-
setShowWizard(false);
|
|
92
|
-
}}
|
|
93
|
-
/>
|
|
94
|
-
</div>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## 向导页面消息通信
|
|
100
|
-
|
|
101
|
-
向导页面可以通过 postMessage 与父页面通信:
|
|
102
|
-
|
|
103
|
-
### 向导页面发送消息
|
|
104
|
-
|
|
105
|
-
```javascript
|
|
106
|
-
// 通知父页面向导已加载完成
|
|
107
|
-
window.parent.postMessage(
|
|
108
|
-
{
|
|
109
|
-
type: 'wizard.loaded',
|
|
110
|
-
},
|
|
111
|
-
window.location.origin
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
// 通知父页面向导已完成
|
|
115
|
-
window.parent.postMessage(
|
|
116
|
-
{
|
|
117
|
-
type: 'wizard.finished',
|
|
118
|
-
data: { success: true, result: 'setup-complete' },
|
|
119
|
-
},
|
|
120
|
-
window.location.origin
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
// 通知父页面关闭向导
|
|
124
|
-
window.parent.postMessage(
|
|
125
|
-
{
|
|
126
|
-
type: 'wizard.close',
|
|
127
|
-
},
|
|
128
|
-
window.location.origin
|
|
129
|
-
);
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Props 说明
|
|
133
|
-
|
|
134
|
-
### Header 组件新增 Props
|
|
135
|
-
|
|
136
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
137
|
-
| ---------- | ------- | ------ | ---------------- |
|
|
138
|
-
| showWizard | boolean | false | 是否显示向导按钮 |
|
|
139
|
-
|
|
140
|
-
### WizardModal 组件 Props
|
|
141
|
-
|
|
142
|
-
| 属性 | 类型 | 默认值 | 说明 |
|
|
143
|
-
| --------------- | -------- | --------- | ------------------------------------ |
|
|
144
|
-
| show | boolean | false | 控制弹窗显示状态 |
|
|
145
|
-
| onFinished | function | undefined | 向导完成回调函数 |
|
|
146
|
-
| onChangeVisible | function | undefined | 弹窗显示状态变化回调 |
|
|
147
|
-
| onClose | function | undefined | 弹窗关闭回调(isCompleted: boolean) |
|
|
148
|
-
|
|
149
|
-
## 新增功能特性
|
|
150
|
-
|
|
151
|
-
### 1. 智能提示系统
|
|
152
|
-
|
|
153
|
-
- 点击遮罩关闭时显示 tooltip 提示:"想要再次打开 wizard 可以点击这里"
|
|
154
|
-
- Tooltip 显示 5 秒后自动消失
|
|
155
|
-
- 完成向导后不显示 tooltip
|
|
156
|
-
- 按钮在提示期间有闪烁动画效果
|
|
157
|
-
|
|
158
|
-
### 2. URL 状态保存
|
|
159
|
-
|
|
160
|
-
- 关闭 wizard 时自动保存当前 iframe 的 URL 到 localStorage
|
|
161
|
-
- 下次打开时直接加载上次的位置,继续之前的进度
|
|
162
|
-
- 完成向导后重置为默认 URL
|
|
163
|
-
|
|
164
|
-
### 3. 交互优化
|
|
165
|
-
|
|
166
|
-
- 点击遮罩或 ESC 键可以关闭弹窗
|
|
167
|
-
- 关闭时会保存当前进度
|
|
168
|
-
- 完成后自动清理临时状态
|