@arcblock/ux 3.1.47 → 3.1.48
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/OrgTransfer/index.d.ts +5 -0
- package/lib/OrgTransfer/index.js +38 -0
- package/lib/OrgTransfer/locales.d.ts +25 -0
- package/lib/OrgTransfer/locales.js +27 -0
- package/lib/OrgTransfer/selector.d.ts +2 -0
- package/lib/OrgTransfer/selector.js +174 -0
- package/lib/OrgTransfer/type.d.ts +28 -0
- package/lib/OrgTransfer/type.js +1 -0
- package/lib/UserCard/use-follow.d.ts +0 -2
- package/lib/UserCard/use-follow.js +35 -39
- package/lib/Util/client.d.ts +6 -0
- package/lib/Util/client.js +7 -0
- package/lib/Util/index.d.ts +2 -0
- package/lib/Util/index.js +58 -54
- package/lib/package.json.js +1 -1
- package/package.json +7 -7
- package/src/OrgTransfer/index.tsx +53 -0
- package/src/OrgTransfer/locales.ts +25 -0
- package/src/OrgTransfer/selector.tsx +249 -0
- package/src/OrgTransfer/type.ts +31 -0
- package/src/UserCard/use-follow.tsx +1 -10
- package/src/Util/client.ts +9 -0
- package/src/Util/index.ts +11 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
import { jsxs as d, Fragment as g, jsx as i } from "react/jsx-runtime";
|
2
|
+
import { useRef as x, cloneElement as k } from "react";
|
3
|
+
import { Button as C } from "@mui/material";
|
4
|
+
import { useMemoizedFn as O } from "ahooks";
|
5
|
+
import h from "./selector.js";
|
6
|
+
import j from "./locales.js";
|
7
|
+
import { translate as F } from "../Locale/util.js";
|
8
|
+
function T({
|
9
|
+
org: e,
|
10
|
+
onSuccess: f,
|
11
|
+
resourceId: s,
|
12
|
+
buttonProps: n,
|
13
|
+
buttonText: l,
|
14
|
+
locale: t = "en",
|
15
|
+
dialogProps: c,
|
16
|
+
children: o
|
17
|
+
}) {
|
18
|
+
const a = O((u, p = {}) => F(j, u, t, "en", p)), r = x(null), m = () => {
|
19
|
+
r.current && r.current.open({ selectedOrg: e });
|
20
|
+
};
|
21
|
+
return /* @__PURE__ */ d(g, { children: [
|
22
|
+
o ? k(o, { ...n, onClick: m }) : /* @__PURE__ */ i(C, { ...n, onClick: m, children: l || a("transferOrg") }),
|
23
|
+
/* @__PURE__ */ i(
|
24
|
+
h,
|
25
|
+
{
|
26
|
+
locale: t,
|
27
|
+
org: e,
|
28
|
+
ref: r,
|
29
|
+
resourceId: s,
|
30
|
+
onSuccess: f,
|
31
|
+
dialogProps: c
|
32
|
+
}
|
33
|
+
)
|
34
|
+
] });
|
35
|
+
}
|
36
|
+
export {
|
37
|
+
T as default
|
38
|
+
};
|
@@ -0,0 +1,25 @@
|
|
1
|
+
declare const _default: {
|
2
|
+
en: {
|
3
|
+
transferOrg: string;
|
4
|
+
cancel: string;
|
5
|
+
confirm: string;
|
6
|
+
tranferSuccess: string;
|
7
|
+
placeholder: string;
|
8
|
+
loading: string;
|
9
|
+
noResults: string;
|
10
|
+
resourceIdRequired: string;
|
11
|
+
organizationSameAsCurrent: string;
|
12
|
+
};
|
13
|
+
zh: {
|
14
|
+
transferOrg: string;
|
15
|
+
cancel: string;
|
16
|
+
confirm: string;
|
17
|
+
tranferSuccess: string;
|
18
|
+
placeholder: string;
|
19
|
+
loading: string;
|
20
|
+
noResults: string;
|
21
|
+
resourceIdRequired: string;
|
22
|
+
organizationSameAsCurrent: string;
|
23
|
+
};
|
24
|
+
};
|
25
|
+
export default _default;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
const e = {
|
2
|
+
en: {
|
3
|
+
transferOrg: "Transfer to Other Organization",
|
4
|
+
cancel: "Cancel",
|
5
|
+
confirm: "Confirm",
|
6
|
+
tranferSuccess: "Transfer success",
|
7
|
+
placeholder: "Select an organization to transfer",
|
8
|
+
loading: "Loading...",
|
9
|
+
noResults: "No More",
|
10
|
+
resourceIdRequired: "Please select the resource to transfer",
|
11
|
+
organizationSameAsCurrent: "The selected organization is the same as the current organization, please select other organizations"
|
12
|
+
},
|
13
|
+
zh: {
|
14
|
+
transferOrg: "转移至其他组织",
|
15
|
+
cancel: "取消",
|
16
|
+
confirm: "确认",
|
17
|
+
tranferSuccess: "转移成功",
|
18
|
+
placeholder: "请选择要转移的组织",
|
19
|
+
loading: "加载中...",
|
20
|
+
noResults: "没有更多了",
|
21
|
+
resourceIdRequired: "请选择要转移的资源",
|
22
|
+
organizationSameAsCurrent: "选择的组织与当前组织相同,请选择其他组织"
|
23
|
+
}
|
24
|
+
};
|
25
|
+
export {
|
26
|
+
e as default
|
27
|
+
};
|
@@ -0,0 +1,174 @@
|
|
1
|
+
import { jsx as n, jsxs as i, Fragment as O } from "react/jsx-runtime";
|
2
|
+
import { useState as F, useImperativeHandle as _, createElement as y } from "react";
|
3
|
+
import { useMemoizedFn as p, useReactive as q, useDebounce as G, useInfiniteScroll as H } from "ahooks";
|
4
|
+
import { Box as l, Typography as a, Autocomplete as N, CircularProgress as b, TextField as Q, Button as v } from "@mui/material";
|
5
|
+
import w from "../Toast/index.js";
|
6
|
+
import Z from "../Dialog/dialog.js";
|
7
|
+
import "../Dialog/confirm.js";
|
8
|
+
import "lodash/noop";
|
9
|
+
import { OrgQueryType as J, client as T } from "../Util/client.js";
|
10
|
+
import { formatAxiosError as K } from "../Util/index.js";
|
11
|
+
import { translate as U } from "../Locale/util.js";
|
12
|
+
import X from "./locales.js";
|
13
|
+
const I = 20;
|
14
|
+
function ce({
|
15
|
+
ref: C,
|
16
|
+
org: g,
|
17
|
+
onSuccess: S,
|
18
|
+
resourceId: f,
|
19
|
+
locale: E = "en",
|
20
|
+
dialogProps: k
|
21
|
+
}) {
|
22
|
+
const o = p((e, r = {}) => U(X, e, E, "en", r)), [h, c] = F(""), t = q({
|
23
|
+
open: !1,
|
24
|
+
selectedOrg: null
|
25
|
+
}), x = G(h, { wait: 500 }), { data: A, loadMore: W, loadingMore: d, loading: u, reload: z } = H(
|
26
|
+
async (e) => {
|
27
|
+
if (!t.open) return { list: [], total: 0 };
|
28
|
+
const m = { page: e ? Math.ceil(e.list.length / I) + 1 : 1, pageSize: I, search: x, type: J.OWNED }, R = await T.user.getOrgs(m), { orgs: j = [], paging: B } = R || {};
|
29
|
+
return { list: j, total: B?.total || 0 };
|
30
|
+
},
|
31
|
+
{
|
32
|
+
reloadDeps: [x],
|
33
|
+
isNoMore: (e) => e?.list.length ? e.list.length >= e?.total : !0,
|
34
|
+
onError: (e) => {
|
35
|
+
console.error("Get orgs failed", e);
|
36
|
+
},
|
37
|
+
manual: !0
|
38
|
+
// 手动触发,在对话框打开时再加载
|
39
|
+
}
|
40
|
+
), s = p(() => {
|
41
|
+
t.open = !1, t.selectedOrg = null, c("");
|
42
|
+
}), M = p(async () => {
|
43
|
+
try {
|
44
|
+
if (!f)
|
45
|
+
throw new Error(o("resourceIdRequired"));
|
46
|
+
if (!t.selectedOrg)
|
47
|
+
throw new Error(o("placeholder"));
|
48
|
+
if (t.selectedOrg.id === g.id)
|
49
|
+
throw new Error(o("organizationSameAsCurrent"));
|
50
|
+
await T.user.migrateResourceToOrg({ form: g.id, to: t.selectedOrg.id, resourceId: f }), s(), S?.(t.selectedOrg), w.success(o("tranferSuccess"));
|
51
|
+
} catch (e) {
|
52
|
+
console.error("Resource transfer failed", e), w.error(K(e));
|
53
|
+
}
|
54
|
+
});
|
55
|
+
_(C, () => ({
|
56
|
+
open: (e = {}) => {
|
57
|
+
Object.assign(t, { open: !0, selectedOrg: null }, e), setTimeout(() => {
|
58
|
+
t.open && z();
|
59
|
+
}, 0);
|
60
|
+
},
|
61
|
+
close: s
|
62
|
+
}));
|
63
|
+
const D = A?.list || [], { placeholder: L = "", ...P } = k || {};
|
64
|
+
return /* @__PURE__ */ n(
|
65
|
+
Z,
|
66
|
+
{
|
67
|
+
title: o("transferOrg"),
|
68
|
+
fullWidth: !0,
|
69
|
+
maxWidth: "sm",
|
70
|
+
open: t.open,
|
71
|
+
onClose: s,
|
72
|
+
actions: /* @__PURE__ */ i(O, { children: [
|
73
|
+
/* @__PURE__ */ n(v, { onClick: s, color: "secondary", variant: "outlined", children: o("cancel") }),
|
74
|
+
/* @__PURE__ */ n(v, { onClick: M, color: "primary", variant: "contained", disabled: !t.selectedOrg, children: o("confirm") })
|
75
|
+
] }),
|
76
|
+
...P || {},
|
77
|
+
children: /* @__PURE__ */ i(l, { children: [
|
78
|
+
/* @__PURE__ */ n(a, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: L || o("placeholder") }),
|
79
|
+
/* @__PURE__ */ n(
|
80
|
+
N,
|
81
|
+
{
|
82
|
+
options: D,
|
83
|
+
getOptionLabel: (e) => e?.name || "",
|
84
|
+
isOptionEqualToValue: (e, r) => e?.id === r?.id,
|
85
|
+
value: t.selectedOrg,
|
86
|
+
onChange: (e, r) => {
|
87
|
+
if (r?.isLoadingItem && !d) {
|
88
|
+
W();
|
89
|
+
return;
|
90
|
+
}
|
91
|
+
r?.isLoadingItem || (t.selectedOrg = r, r && c(""));
|
92
|
+
},
|
93
|
+
inputValue: t.selectedOrg ? t.selectedOrg.name : h,
|
94
|
+
onInputChange: (e, r, m) => {
|
95
|
+
m === "input" && (t.selectedOrg && (t.selectedOrg = null), c(r));
|
96
|
+
},
|
97
|
+
loading: u,
|
98
|
+
loadingText: o("loading"),
|
99
|
+
noOptionsText: o(u ? "loading" : "noResults"),
|
100
|
+
renderInput: (e) => /* @__PURE__ */ n(
|
101
|
+
Q,
|
102
|
+
{
|
103
|
+
...e,
|
104
|
+
variant: "outlined",
|
105
|
+
fullWidth: !0,
|
106
|
+
InputProps: {
|
107
|
+
...e.InputProps,
|
108
|
+
endAdornment: /* @__PURE__ */ i(O, { children: [
|
109
|
+
u && /* @__PURE__ */ n(b, { color: "inherit", size: 20 }),
|
110
|
+
e.InputProps.endAdornment
|
111
|
+
] })
|
112
|
+
}
|
113
|
+
}
|
114
|
+
),
|
115
|
+
renderOption: (e, r) => r.isLoadingItem ? /* @__PURE__ */ y(l, { component: "li", ...e, key: r.id }, /* @__PURE__ */ i(
|
116
|
+
l,
|
117
|
+
{
|
118
|
+
sx: {
|
119
|
+
display: "flex",
|
120
|
+
alignItems: "center",
|
121
|
+
justifyContent: "center",
|
122
|
+
flex: 1,
|
123
|
+
py: 1,
|
124
|
+
color: "primary.main",
|
125
|
+
cursor: "pointer"
|
126
|
+
},
|
127
|
+
children: [
|
128
|
+
d && /* @__PURE__ */ n(b, { size: 16, sx: { mr: 1 } }),
|
129
|
+
/* @__PURE__ */ n(a, { variant: "body2", sx: { fontStyle: d ? "italic" : "normal" }, children: r.name })
|
130
|
+
]
|
131
|
+
}
|
132
|
+
)) : /* @__PURE__ */ y(l, { component: "li", ...e, key: r.id }, /* @__PURE__ */ i(l, { sx: { display: "flex", flexDirection: "column", flex: 1, minWidth: 0 }, children: [
|
133
|
+
/* @__PURE__ */ n(
|
134
|
+
a,
|
135
|
+
{
|
136
|
+
variant: "body1",
|
137
|
+
sx: {
|
138
|
+
overflow: "hidden",
|
139
|
+
textOverflow: "ellipsis",
|
140
|
+
whiteSpace: "nowrap"
|
141
|
+
},
|
142
|
+
children: r.name
|
143
|
+
}
|
144
|
+
),
|
145
|
+
r.description && /* @__PURE__ */ n(
|
146
|
+
a,
|
147
|
+
{
|
148
|
+
variant: "body2",
|
149
|
+
color: "text.secondary",
|
150
|
+
sx: {
|
151
|
+
display: "-webkit-box",
|
152
|
+
WebkitLineClamp: 3,
|
153
|
+
WebkitBoxOrient: "vertical",
|
154
|
+
overflow: "hidden",
|
155
|
+
textOverflow: "ellipsis"
|
156
|
+
},
|
157
|
+
children: r.description
|
158
|
+
}
|
159
|
+
)
|
160
|
+
] })),
|
161
|
+
sx: {
|
162
|
+
"& .MuiAutocomplete-listbox": {
|
163
|
+
maxHeight: 200
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
)
|
168
|
+
] })
|
169
|
+
}
|
170
|
+
);
|
171
|
+
}
|
172
|
+
export {
|
173
|
+
ce as default
|
174
|
+
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { ComponentProps } from 'react';
|
2
|
+
import { ButtonProps } from '@mui/material';
|
3
|
+
import { default as Dialog } from '../Dialog';
|
4
|
+
export type Org = {
|
5
|
+
id: string;
|
6
|
+
name: string;
|
7
|
+
description?: string;
|
8
|
+
ownerDid: string;
|
9
|
+
metadata?: Record<string, any>;
|
10
|
+
};
|
11
|
+
type DialogProps = ComponentProps<typeof Dialog> & {
|
12
|
+
placeholder?: string;
|
13
|
+
};
|
14
|
+
export type OrgTransferSelectorProps = Omit<OrgTransferProps, 'children' | 'buttonProps' | 'buttonText'> & {
|
15
|
+
ref: React.RefObject<unknown | null>;
|
16
|
+
};
|
17
|
+
export interface OrgTransferProps {
|
18
|
+
resourceId: string;
|
19
|
+
onSuccess?: (org: Org) => void;
|
20
|
+
org?: Org;
|
21
|
+
children?: React.ReactNode;
|
22
|
+
buttonProps?: ButtonProps;
|
23
|
+
buttonText?: string;
|
24
|
+
dialogProps?: DialogProps;
|
25
|
+
locale?: string;
|
26
|
+
[key: string]: any;
|
27
|
+
}
|
28
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -1,67 +1,63 @@
|
|
1
|
-
import { useState as y, useMemo as
|
2
|
-
import { useMemoizedFn as
|
1
|
+
import { useState as y, useMemo as u, useEffect as F } from "react";
|
2
|
+
import { useMemoizedFn as f } from "ahooks";
|
3
3
|
import U from "lodash/isNil";
|
4
|
-
import { BlockletSDK as
|
5
|
-
import
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
user: r,
|
12
|
-
t,
|
13
|
-
isMySelf: n,
|
4
|
+
import { BlockletSDK as D } from "@blocklet/js-sdk";
|
5
|
+
import a from "../Toast/index.js";
|
6
|
+
import { formatAxiosError as d } from "../Util/index.js";
|
7
|
+
function K({
|
8
|
+
user: e,
|
9
|
+
t: w,
|
10
|
+
isMySelf: l,
|
14
11
|
visible: m
|
15
12
|
}) {
|
16
|
-
const [p, c] = y(!1),
|
13
|
+
const [p, c] = y(!1), t = u(() => e?.did, [e]), n = u(() => Object.prototype.hasOwnProperty.call(e, "isFollowing") && !U(e.isFollowing), [e]), r = u(() => {
|
17
14
|
let o = null;
|
18
15
|
try {
|
19
|
-
o = new
|
20
|
-
} catch (
|
21
|
-
console.error("Failed to initialize BlockletSDK:",
|
16
|
+
o = new D();
|
17
|
+
} catch (s) {
|
18
|
+
console.error("Failed to initialize BlockletSDK:", s), o = null;
|
22
19
|
}
|
23
20
|
return o;
|
24
|
-
}, []),
|
25
|
-
if (!
|
21
|
+
}, []), i = f(async () => {
|
22
|
+
if (!r) {
|
26
23
|
c(!1);
|
27
24
|
return;
|
28
25
|
}
|
29
26
|
try {
|
30
|
-
if (
|
27
|
+
if (l) {
|
31
28
|
c(!0);
|
32
29
|
return;
|
33
30
|
}
|
34
|
-
const o = await
|
31
|
+
const o = await r.user.isFollowingUser({ userDid: t });
|
35
32
|
c(o);
|
36
33
|
} catch (o) {
|
37
34
|
console.error(o);
|
38
35
|
}
|
39
|
-
}),
|
40
|
-
if (!(!
|
36
|
+
}), h = f(async (o = t) => {
|
37
|
+
if (!(!r || l && o === t))
|
41
38
|
try {
|
42
|
-
await
|
43
|
-
} catch (
|
44
|
-
console.error(
|
39
|
+
await r.user.followUser({ userDid: o }), a.success(w("follow_success")), i();
|
40
|
+
} catch (s) {
|
41
|
+
console.error(s), a.error(d(s));
|
45
42
|
}
|
46
|
-
}),
|
47
|
-
if (!(!
|
43
|
+
}), g = f(async (o = t) => {
|
44
|
+
if (!(!r || l && o === t))
|
48
45
|
try {
|
49
|
-
await
|
50
|
-
} catch (
|
51
|
-
console.error(
|
46
|
+
await r.user.unfollowUser({ userDid: o }), a.success(w("unfollow_success")), i();
|
47
|
+
} catch (s) {
|
48
|
+
console.error(s), a.error(d(s));
|
52
49
|
}
|
53
50
|
});
|
54
|
-
return
|
55
|
-
m &&
|
56
|
-
}, [
|
57
|
-
|
58
|
-
}, [
|
51
|
+
return F(() => {
|
52
|
+
m && t && !l && r && !n && i();
|
53
|
+
}, [i, t, l, r, n, m]), F(() => {
|
54
|
+
n && c(e?.isFollowing || !1);
|
55
|
+
}, [n, e]), {
|
59
56
|
followed: p,
|
60
|
-
followUser:
|
61
|
-
unfollowUser:
|
57
|
+
followUser: h,
|
58
|
+
unfollowUser: g
|
62
59
|
};
|
63
60
|
}
|
64
61
|
export {
|
65
|
-
|
66
|
-
F as formatAxiosError
|
62
|
+
K as default
|
67
63
|
};
|
package/lib/Util/index.d.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import { mergeAllThemeOptions } from '@blocklet/theme';
|
2
2
|
import { default as Cookies } from 'js-cookie';
|
3
|
+
import { AxiosError } from 'axios';
|
3
4
|
import { $TSFixMe, Locale } from '../type';
|
4
5
|
declare let dateTool: $TSFixMe | null;
|
5
6
|
/** @deprecated for compatibility, please use `import { mergeAllThemeOptions } from '@blocklet/theme'` instead */
|
@@ -121,3 +122,4 @@ export declare const compareVersions: (version1: string, version2: string) => bo
|
|
121
122
|
* 通过 server 的版本和 ux 的版本共同决定
|
122
123
|
*/
|
123
124
|
export declare const isSupportFollow: () => boolean;
|
125
|
+
export declare const formatAxiosError: (err: AxiosError) => string;
|
package/lib/Util/index.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { lazy as
|
1
|
+
import { lazy as T } from "react";
|
2
2
|
import l from "lodash/padStart";
|
3
|
-
import { colors as w, getDIDMotifInfo as
|
3
|
+
import { colors as w, getDIDMotifInfo as j } from "@arcblock/did-motif";
|
4
4
|
import { mergeAllThemeOptions as Ke } from "@blocklet/theme";
|
5
5
|
import I from "lodash/isNil";
|
6
6
|
import E from "lodash/omitBy";
|
@@ -10,23 +10,23 @@ import O from "color-convert";
|
|
10
10
|
import a from "dayjs";
|
11
11
|
import "dayjs/locale/zh-cn";
|
12
12
|
import U from "dayjs/plugin/utc";
|
13
|
-
import
|
14
|
-
import
|
15
|
-
import
|
16
|
-
import
|
13
|
+
import A from "dayjs/plugin/timezone";
|
14
|
+
import F from "dayjs/plugin/relativeTime";
|
15
|
+
import R from "dayjs/plugin/updateLocale";
|
16
|
+
import P from "dayjs/plugin/localizedFormat";
|
17
17
|
import W from "semver";
|
18
18
|
import { DID_PREFIX as L, BLOCKLET_SERVICE_PATH_PREFIX as C } from "./constant.js";
|
19
19
|
import b from "../package.json.js";
|
20
20
|
import { getFederatedEnabled as M } from "./federated.js";
|
21
21
|
let u = null;
|
22
|
-
const _ = /^(\d{1,3}\.){3}\d{1,3}(:\d+)?$/,
|
22
|
+
const _ = /^(\d{1,3}\.){3}\d{1,3}(:\d+)?$/, N = /* @__PURE__ */ new Set(["co", "com", "net", "org", "gov", "edu", "ac"]), z = /* @__PURE__ */ new Set(["uk", "au", "cn", "nz", "za", "in", "br", "mx", "fr", "it", "ca"]);
|
23
23
|
function B(e) {
|
24
24
|
if (!e)
|
25
25
|
return !1;
|
26
26
|
const t = e.split(".");
|
27
27
|
if (t.length < 2) return !1;
|
28
28
|
const o = t[t.length - 2], r = t[t.length - 1];
|
29
|
-
return
|
29
|
+
return N.has(o) && z.has(r);
|
30
30
|
}
|
31
31
|
function ye() {
|
32
32
|
const { host: e } = window.location;
|
@@ -51,7 +51,7 @@ function Ie(e) {
|
|
51
51
|
function be(e = {}) {
|
52
52
|
return new URLSearchParams(e).toString();
|
53
53
|
}
|
54
|
-
function
|
54
|
+
function Se(e = 1) {
|
55
55
|
let t = e;
|
56
56
|
typeof t == "number" && (t = { expireInDays: t }), t.path === void 0 && (t.path = "/"), t.expireInDays || (t.expireInDays = 1);
|
57
57
|
const o = {
|
@@ -64,7 +64,7 @@ function De(e = 1) {
|
|
64
64
|
};
|
65
65
|
return (typeof window > "u" || t.domain || t.returnDomain === !1) && t.returnDomain === !1 && delete o.domain, o;
|
66
66
|
}
|
67
|
-
const
|
67
|
+
const De = (e) => e.color ? e.color : e.dark ? e.theme.palette.common.white : e.theme.palette.text.primary, $e = (e) => e.background ? e.background : e.dark ? e.theme.palette.common.black : e.theme.palette.common.white;
|
68
68
|
function ke(e, t, o = []) {
|
69
69
|
const r = Object.assign({}, e), i = t.defaultProps || {};
|
70
70
|
return Object.keys(i).forEach((n) => {
|
@@ -79,11 +79,11 @@ function ke(e, t, o = []) {
|
|
79
79
|
typeof r[n] == "string" && r[n].indexOf("::prop::") === 0 && (r[n] = "");
|
80
80
|
}), r;
|
81
81
|
}
|
82
|
-
function
|
82
|
+
function Ve(e = 2017) {
|
83
83
|
const t = (/* @__PURE__ */ new Date()).getFullYear();
|
84
84
|
return `${t}` == `${e}` ? `© ArcBlock ${t}` : `© ArcBlock ${e} - ${t}`;
|
85
85
|
}
|
86
|
-
const
|
86
|
+
const xe = () => typeof Intl == "object" && typeof Intl.DateTimeFormat == "function" && typeof Intl.DateTimeFormat().resolvedOptions == "function" ? Intl.DateTimeFormat().resolvedOptions().timeZone : "", Te = (e) => {
|
87
87
|
let t = 0;
|
88
88
|
for (let r = 0; r < e.length; r++)
|
89
89
|
t = e.charCodeAt(r) + ((t << 5) - t);
|
@@ -93,7 +93,7 @@ const Te = () => typeof Intl == "object" && typeof Intl.DateTimeFormat == "funct
|
|
93
93
|
o += `00${i.toString(16)}`.substr(-2);
|
94
94
|
}
|
95
95
|
return o;
|
96
|
-
},
|
96
|
+
}, je = (e) => {
|
97
97
|
const t = Math.round(e / 1e3), o = Math.floor(t / 3600), r = Math.floor((t - o * 3600) / 60), i = t % 60;
|
98
98
|
return `${l(o, 2, "0")}:${l(r, 2, "0")}:${l(i, 2, "0")}`;
|
99
99
|
};
|
@@ -103,8 +103,8 @@ function X(e) {
|
|
103
103
|
function Ee() {
|
104
104
|
return u;
|
105
105
|
}
|
106
|
-
const
|
107
|
-
if (u === null && (a.extend(
|
106
|
+
const S = (e) => (t, { locale: o, tz: r, isUtc: i } = {}) => {
|
107
|
+
if (u === null && (a.extend(P), a.extend(U), a.extend(A), a.extend(R), a.extend(F), a.updateLocale("zh-cn", {
|
108
108
|
// copy with https://github.com/iamkun/dayjs/blob/dev/src/locale/zh-cn.js
|
109
109
|
relativeTime: {
|
110
110
|
future: "%s后",
|
@@ -127,7 +127,7 @@ const D = (e) => (t, { locale: o, tz: r, isUtc: i } = {}) => {
|
|
127
127
|
return r && (n = n.tz(r)), i && (n = n.utc()), typeof o < "u" && (n = n.locale(o)), n.format(e);
|
128
128
|
};
|
129
129
|
function ve(e, { locale: t = "en", tz: o } = {}) {
|
130
|
-
return
|
130
|
+
return S("ll")(e, { locale: t, tz: o });
|
131
131
|
}
|
132
132
|
function Oe(e, {
|
133
133
|
locale: t = "en",
|
@@ -135,9 +135,9 @@ function Oe(e, {
|
|
135
135
|
isUtc: r = !1,
|
136
136
|
format: i = "lll"
|
137
137
|
} = {}) {
|
138
|
-
return
|
138
|
+
return S(i)(e, { locale: t, tz: o, isUtc: r });
|
139
139
|
}
|
140
|
-
function
|
140
|
+
function J() {
|
141
141
|
const e = window?.ABT_DEV || window.ABT;
|
142
142
|
return e && typeof e.open == "function" ? e : null;
|
143
143
|
}
|
@@ -150,7 +150,7 @@ function Ue({
|
|
150
150
|
appInfo: n,
|
151
151
|
memberAppInfo: f
|
152
152
|
}) {
|
153
|
-
const h =
|
153
|
+
const h = J();
|
154
154
|
if (h)
|
155
155
|
return h.open({
|
156
156
|
action: t,
|
@@ -163,7 +163,7 @@ function Ue({
|
|
163
163
|
...f
|
164
164
|
}
|
165
165
|
}), { type: "extension" };
|
166
|
-
const
|
166
|
+
const D = {
|
167
167
|
toolbar: "no",
|
168
168
|
location: "no",
|
169
169
|
status: "no",
|
@@ -173,19 +173,19 @@ function Ue({
|
|
173
173
|
// iphone 8plus size
|
174
174
|
width: 414,
|
175
175
|
height: 736
|
176
|
-
},
|
176
|
+
}, $ = `${e}?action=${t}&locale=${o}&url=${encodeURIComponent(r)}`, c = Object.assign({}, D, i), k = (s) => s.innerWidth || s.document.documentElement.clientWidth || s.document.body.clientWidth;
|
177
177
|
if (!("left" in c)) {
|
178
|
-
const s = k(window.top || window),
|
179
|
-
c.left = s +
|
178
|
+
const s = k(window.top || window), x = window.screenLeft || window.screenX;
|
179
|
+
c.left = s + x - c.width;
|
180
180
|
}
|
181
181
|
if (!("top" in c)) {
|
182
182
|
const s = window.screenTop || window.screenY;
|
183
183
|
c.top = s;
|
184
184
|
}
|
185
|
-
const
|
186
|
-
return window.open(
|
185
|
+
const V = Object.keys(c).map((s) => `${s}=${c[s]}`).join(",");
|
186
|
+
return window.open($, "targetWindow", V), { type: "web" };
|
187
187
|
}
|
188
|
-
const
|
188
|
+
const Ae = (e) => e && Number(e) >= 12 ? `${Number(e)}px` : "inherit", K = (e) => {
|
189
189
|
const t = e.replace(L, "");
|
190
190
|
return !!/^(0x)?[0-9a-f]{40}$/i.test(t);
|
191
191
|
}, Q = (e, t) => {
|
@@ -199,15 +199,15 @@ const Fe = (e) => e && Number(e) >= 12 ? `${Number(e)}px` : "inherit", J = (e) =
|
|
199
199
|
} catch {
|
200
200
|
return e;
|
201
201
|
}
|
202
|
-
},
|
202
|
+
}, Fe = (e, t = 48) => e && (e.indexOf(C) >= 0 ? Q(e, {
|
203
203
|
imageFilter: "resize",
|
204
204
|
w: t,
|
205
205
|
h: t
|
206
|
-
}) : e),
|
206
|
+
}) : e), Re = (e = 0) => new Promise((t) => {
|
207
207
|
setTimeout(() => {
|
208
208
|
t();
|
209
209
|
}, e);
|
210
|
-
}),
|
210
|
+
}), Pe = (e) => /^https?:\/\//.test(e), p = "vid", g = "__visitor_id", Y = () => m.get(p) || localStorage.getItem(g), y = (e) => {
|
211
211
|
e === null ? m.remove(p, {
|
212
212
|
sameSite: "None",
|
213
213
|
secure: !0
|
@@ -245,14 +245,14 @@ const Fe = (e) => e && Number(e) >= 12 ? `${Number(e)}px` : "inherit", J = (e) =
|
|
245
245
|
e && y(e);
|
246
246
|
}
|
247
247
|
}, Le = (e) => {
|
248
|
-
if (
|
248
|
+
if (K(e)) {
|
249
249
|
const t = Uint8Array.from(
|
250
250
|
e.slice(2).match(/.{1,2}/g).map((o) => parseInt(o, 16))
|
251
251
|
).slice(0, 8).reduce((o, r) => o + r, 0) % w.length;
|
252
252
|
return w[t];
|
253
253
|
}
|
254
254
|
try {
|
255
|
-
return
|
255
|
+
return j(e)?.color;
|
256
256
|
} catch {
|
257
257
|
return null;
|
258
258
|
}
|
@@ -262,7 +262,7 @@ const Fe = (e) => e && Number(e) >= 12 ? `${Number(e)}px` : "inherit", J = (e) =
|
|
262
262
|
return e;
|
263
263
|
let n;
|
264
264
|
return t && (n = e[t]), (!n || typeof n != "string") && (n = e[r]), (!n || typeof n != "string") && (n = i), n;
|
265
|
-
}, Me = (e) =>
|
265
|
+
}, Me = (e) => T(
|
266
266
|
() => v(
|
267
267
|
async () => {
|
268
268
|
try {
|
@@ -275,11 +275,11 @@ const Fe = (e) => e && Number(e) >= 12 ? `${Number(e)}px` : "inherit", J = (e) =
|
|
275
275
|
{ retries: 2 }
|
276
276
|
)
|
277
277
|
), _e = (e) => E(e, I);
|
278
|
-
function
|
278
|
+
function Ne(e, t = 1) {
|
279
279
|
const [o, r, i] = O.hex.rgb(e);
|
280
280
|
return `rgba(${o}, ${r}, ${i}, ${t})`;
|
281
281
|
}
|
282
|
-
const
|
282
|
+
const q = () => window.blocklet?.serverVersion || window.env?.serverVersion || "", G = () => b.version, H = () => (b.dependencies?.["@blocklet/js-sdk"]).replace(/^[\^~>=<]+/, ""), d = (e, t) => {
|
283
283
|
const o = (n) => {
|
284
284
|
const f = n.match(/^(\d+\.\d+\.\d+(?:-[^-]+?-\d{8}))/);
|
285
285
|
return f ? f[1] : n;
|
@@ -294,44 +294,48 @@ const G = () => window.blocklet?.serverVersion || window.env?.serverVersion || "
|
|
294
294
|
} catch {
|
295
295
|
return !1;
|
296
296
|
}
|
297
|
-
},
|
297
|
+
}, ze = () => {
|
298
298
|
if (process.env.NODE_ENV === "development")
|
299
299
|
return !0;
|
300
|
-
const e =
|
300
|
+
const e = q(), t = G(), o = H();
|
301
301
|
if (!e || !t || !o)
|
302
302
|
return !1;
|
303
303
|
const r = d(t, "3.1.29"), i = d(e, "1.16.49-beta-20250822-070545-6d3344cc"), n = d(o, "1.16.49-beta-20250822-070545-6d3344cc");
|
304
304
|
return r && i && n;
|
305
|
+
}, Be = (e) => {
|
306
|
+
const { response: t } = e;
|
307
|
+
return t ? `Request failed: ${t.status} ${t.statusText}: ${JSON.stringify(t.data)}` : e.message || "Unknown error occurred";
|
305
308
|
};
|
306
309
|
export {
|
307
310
|
Q as appendParams,
|
308
311
|
_e as cleanedObj,
|
309
312
|
d as compareVersions,
|
310
313
|
Ke as deepmergeAll,
|
311
|
-
|
314
|
+
J as detectWalletExtension,
|
312
315
|
We as ensureVisitorId,
|
316
|
+
Be as formatAxiosError,
|
313
317
|
ve as formatToDate,
|
314
318
|
Oe as formatToDatetime,
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
319
|
+
je as formatUptime,
|
320
|
+
$e as getBackground,
|
321
|
+
De as getColor,
|
322
|
+
Se as getCookieOptions,
|
323
|
+
Ve as getCopyright,
|
320
324
|
Le as getDIDColor,
|
321
325
|
Ee as getDateTool,
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
+
Ae as getFontSize,
|
327
|
+
H as getJsSdkVersion,
|
328
|
+
q as getServerVersion,
|
329
|
+
xe as getTimezone,
|
326
330
|
Ce as getTranslation,
|
327
|
-
|
328
|
-
|
331
|
+
Fe as getUserAvatar,
|
332
|
+
G as getUxPackageVersion,
|
329
333
|
Y as getVisitorId,
|
330
|
-
|
331
|
-
|
332
|
-
|
334
|
+
Ne as hexToRgba,
|
335
|
+
K as isEthereumDid,
|
336
|
+
ze as isSupportFollow,
|
333
337
|
B as isTwoSegmentTLD,
|
334
|
-
|
338
|
+
Pe as isUrl,
|
335
339
|
Me as lazyRetry,
|
336
340
|
ke as mergeProps,
|
337
341
|
Ue as openWebWallet,
|
@@ -339,7 +343,7 @@ export {
|
|
339
343
|
ye as resolveRootDomain,
|
340
344
|
X as setDateTool,
|
341
345
|
y as setVisitorId,
|
342
|
-
|
343
|
-
|
346
|
+
Re as sleep,
|
347
|
+
Te as str2color,
|
344
348
|
be as stringifyQuery
|
345
349
|
};
|
package/lib/package.json.js
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "3.1.
|
3
|
+
"version": "3.1.48",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -68,16 +68,16 @@
|
|
68
68
|
"react": "^19.0.0",
|
69
69
|
"react-router-dom": "^6.22.3"
|
70
70
|
},
|
71
|
-
"gitHead": "
|
71
|
+
"gitHead": "49a6dabae8a06667e517c6811f5f7939ff907ce1",
|
72
72
|
"dependencies": {
|
73
|
-
"@arcblock/bridge": "3.1.
|
73
|
+
"@arcblock/bridge": "3.1.48",
|
74
74
|
"@arcblock/did": "^1.25.6",
|
75
75
|
"@arcblock/did-motif": "^1.1.14",
|
76
|
-
"@arcblock/icons": "3.1.
|
77
|
-
"@arcblock/nft-display": "3.1.
|
78
|
-
"@arcblock/react-hooks": "3.1.
|
76
|
+
"@arcblock/icons": "3.1.48",
|
77
|
+
"@arcblock/nft-display": "3.1.48",
|
78
|
+
"@arcblock/react-hooks": "3.1.48",
|
79
79
|
"@blocklet/js-sdk": "1.16.52",
|
80
|
-
"@blocklet/theme": "3.1.
|
80
|
+
"@blocklet/theme": "3.1.48",
|
81
81
|
"@fontsource/roboto": "~5.1.1",
|
82
82
|
"@fontsource/ubuntu-mono": "^5.2.6",
|
83
83
|
"@iconify-icons/logos": "^1.2.36",
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { useRef, cloneElement } from 'react';
|
2
|
+
import { Button } from '@mui/material';
|
3
|
+
import { useMemoizedFn } from 'ahooks';
|
4
|
+
import OrgTransferSelector from './selector';
|
5
|
+
import { OrgTransferProps } from './type';
|
6
|
+
import translations from './locales';
|
7
|
+
import { translate } from '../Locale/util';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* org transfer 弹框
|
11
|
+
*/
|
12
|
+
export default function Index({
|
13
|
+
org,
|
14
|
+
onSuccess,
|
15
|
+
resourceId,
|
16
|
+
buttonProps,
|
17
|
+
buttonText,
|
18
|
+
locale = 'en',
|
19
|
+
dialogProps,
|
20
|
+
children,
|
21
|
+
}: OrgTransferProps) {
|
22
|
+
const t = useMemoizedFn((key, data = {}) => {
|
23
|
+
return translate(translations, key, locale, 'en', data);
|
24
|
+
});
|
25
|
+
const dialogRef = useRef(null);
|
26
|
+
|
27
|
+
const handleClick = () => {
|
28
|
+
if (dialogRef.current) {
|
29
|
+
(dialogRef.current as any).open({ selectedOrg: org });
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
return (
|
34
|
+
<>
|
35
|
+
{children ? (
|
36
|
+
cloneElement(children as React.ReactElement, { ...buttonProps, onClick: handleClick } as any)
|
37
|
+
) : (
|
38
|
+
<Button {...buttonProps} onClick={handleClick}>
|
39
|
+
{buttonText || t('transferOrg')}
|
40
|
+
</Button>
|
41
|
+
)}
|
42
|
+
|
43
|
+
<OrgTransferSelector
|
44
|
+
locale={locale}
|
45
|
+
org={org}
|
46
|
+
ref={dialogRef}
|
47
|
+
resourceId={resourceId}
|
48
|
+
onSuccess={onSuccess}
|
49
|
+
dialogProps={dialogProps}
|
50
|
+
/>
|
51
|
+
</>
|
52
|
+
);
|
53
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export default {
|
2
|
+
en: {
|
3
|
+
transferOrg: 'Transfer to Other Organization',
|
4
|
+
cancel: 'Cancel',
|
5
|
+
confirm: 'Confirm',
|
6
|
+
tranferSuccess: 'Transfer success',
|
7
|
+
placeholder: 'Select an organization to transfer',
|
8
|
+
loading: 'Loading...',
|
9
|
+
noResults: 'No More',
|
10
|
+
resourceIdRequired: 'Please select the resource to transfer',
|
11
|
+
organizationSameAsCurrent:
|
12
|
+
'The selected organization is the same as the current organization, please select other organizations',
|
13
|
+
},
|
14
|
+
zh: {
|
15
|
+
transferOrg: '转移至其他组织',
|
16
|
+
cancel: '取消',
|
17
|
+
confirm: '确认',
|
18
|
+
tranferSuccess: '转移成功',
|
19
|
+
placeholder: '请选择要转移的组织',
|
20
|
+
loading: '加载中...',
|
21
|
+
noResults: '没有更多了',
|
22
|
+
resourceIdRequired: '请选择要转移的资源',
|
23
|
+
organizationSameAsCurrent: '选择的组织与当前组织相同,请选择其他组织',
|
24
|
+
},
|
25
|
+
};
|
@@ -0,0 +1,249 @@
|
|
1
|
+
/**
|
2
|
+
* Org transfer selector
|
3
|
+
*/
|
4
|
+
import { useImperativeHandle, useState } from 'react';
|
5
|
+
import { useReactive, useDebounce, useInfiniteScroll, useMemoizedFn } from 'ahooks';
|
6
|
+
import { Button, Typography, Box, Autocomplete, TextField, CircularProgress } from '@mui/material';
|
7
|
+
import { AxiosError } from 'axios';
|
8
|
+
import Toast from '../Toast';
|
9
|
+
import Dialog from '../Dialog';
|
10
|
+
import { Org, OrgTransferSelectorProps } from './type';
|
11
|
+
import { client, OrgQueryType } from '../Util/client';
|
12
|
+
import { formatAxiosError } from '../Util';
|
13
|
+
import { translate } from '../Locale/util';
|
14
|
+
import translations from './locales';
|
15
|
+
|
16
|
+
const PAGE_SIZE = 20;
|
17
|
+
|
18
|
+
export default function OrgTransferSelector({
|
19
|
+
ref,
|
20
|
+
org,
|
21
|
+
onSuccess,
|
22
|
+
resourceId,
|
23
|
+
locale = 'en',
|
24
|
+
dialogProps,
|
25
|
+
}: OrgTransferSelectorProps) {
|
26
|
+
const t = useMemoizedFn((key, data = {}) => {
|
27
|
+
return translate(translations, key, locale, 'en', data);
|
28
|
+
});
|
29
|
+
const [searchText, setSearchText] = useState('');
|
30
|
+
|
31
|
+
const state = useReactive<{
|
32
|
+
open: boolean;
|
33
|
+
selectedOrg: Org | null;
|
34
|
+
}>({
|
35
|
+
open: false,
|
36
|
+
selectedOrg: null,
|
37
|
+
});
|
38
|
+
|
39
|
+
const debouncedSearchText = useDebounce(searchText, { wait: 500 });
|
40
|
+
|
41
|
+
const { data, loadMore, loadingMore, loading, reload } = useInfiniteScroll(
|
42
|
+
async (d) => {
|
43
|
+
// 只有对话框打开时才发起请求
|
44
|
+
if (!state.open) return { list: [], total: 0 };
|
45
|
+
|
46
|
+
const page = d ? Math.ceil(d.list.length / PAGE_SIZE) + 1 : 1;
|
47
|
+
const params = { page, pageSize: PAGE_SIZE, search: debouncedSearchText, type: OrgQueryType.OWNED };
|
48
|
+
const response = await client.user.getOrgs(params);
|
49
|
+
|
50
|
+
const { orgs: resultOrgs = [], paging } = response || {};
|
51
|
+
return { list: resultOrgs, total: paging?.total || 0 };
|
52
|
+
},
|
53
|
+
{
|
54
|
+
reloadDeps: [debouncedSearchText],
|
55
|
+
isNoMore: (d) => {
|
56
|
+
if (!d?.list.length) return true;
|
57
|
+
return d.list.length >= d?.total;
|
58
|
+
},
|
59
|
+
onError: (error) => {
|
60
|
+
// eslint-disable-next-line no-console
|
61
|
+
console.error('Get orgs failed', error);
|
62
|
+
},
|
63
|
+
manual: true, // 手动触发,在对话框打开时再加载
|
64
|
+
}
|
65
|
+
);
|
66
|
+
|
67
|
+
const handleClose = useMemoizedFn(() => {
|
68
|
+
state.open = false;
|
69
|
+
state.selectedOrg = null;
|
70
|
+
setSearchText(''); // 关闭时重置搜索
|
71
|
+
});
|
72
|
+
|
73
|
+
const handleConfirm = useMemoizedFn(async () => {
|
74
|
+
try {
|
75
|
+
if (!resourceId) {
|
76
|
+
throw new Error(t('resourceIdRequired'));
|
77
|
+
}
|
78
|
+
if (!state.selectedOrg) {
|
79
|
+
throw new Error(t('placeholder'));
|
80
|
+
}
|
81
|
+
if (state.selectedOrg.id === org.id) {
|
82
|
+
throw new Error(t('organizationSameAsCurrent'));
|
83
|
+
}
|
84
|
+
await client.user.migrateResourceToOrg({ form: org.id, to: state.selectedOrg.id, resourceId });
|
85
|
+
handleClose();
|
86
|
+
onSuccess?.(state.selectedOrg);
|
87
|
+
Toast.success(t('tranferSuccess'));
|
88
|
+
} catch (error) {
|
89
|
+
console.error('Resource transfer failed', error);
|
90
|
+
Toast.error(formatAxiosError(error as AxiosError));
|
91
|
+
}
|
92
|
+
});
|
93
|
+
|
94
|
+
useImperativeHandle(ref, () => ({
|
95
|
+
open: (options = {}) => {
|
96
|
+
Object.assign(state, { open: true, selectedOrg: null }, options);
|
97
|
+
// 对话框打开时重新加载数据
|
98
|
+
setTimeout(() => {
|
99
|
+
if (state.open) {
|
100
|
+
reload();
|
101
|
+
}
|
102
|
+
}, 0);
|
103
|
+
},
|
104
|
+
close: handleClose,
|
105
|
+
}));
|
106
|
+
|
107
|
+
const organizations = data?.list || [];
|
108
|
+
// const hasMore = data ? data.list.length < data.total : false;
|
109
|
+
|
110
|
+
const { placeholder = '', ...rest } = dialogProps || {};
|
111
|
+
return (
|
112
|
+
<Dialog
|
113
|
+
title={t('transferOrg')}
|
114
|
+
fullWidth
|
115
|
+
maxWidth="sm"
|
116
|
+
open={state.open}
|
117
|
+
onClose={handleClose}
|
118
|
+
actions={
|
119
|
+
<>
|
120
|
+
<Button onClick={handleClose} color="secondary" variant="outlined">
|
121
|
+
{t('cancel')}
|
122
|
+
</Button>
|
123
|
+
<Button onClick={handleConfirm} color="primary" variant="contained" disabled={!state.selectedOrg}>
|
124
|
+
{t('confirm')}
|
125
|
+
</Button>
|
126
|
+
</>
|
127
|
+
}
|
128
|
+
{...(rest || {})}>
|
129
|
+
<Box>
|
130
|
+
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
|
131
|
+
{placeholder || t('placeholder')}
|
132
|
+
</Typography>
|
133
|
+
|
134
|
+
<Autocomplete
|
135
|
+
options={organizations}
|
136
|
+
getOptionLabel={(option) => option?.name || ''}
|
137
|
+
isOptionEqualToValue={(option, value) => option?.id === value?.id}
|
138
|
+
value={state.selectedOrg}
|
139
|
+
onChange={(_, newValue) => {
|
140
|
+
// 如果点击的是加载项,触发加载更多
|
141
|
+
if (newValue?.isLoadingItem && !loadingMore) {
|
142
|
+
loadMore();
|
143
|
+
return;
|
144
|
+
}
|
145
|
+
// 忽略加载项的选择
|
146
|
+
if (newValue?.isLoadingItem) {
|
147
|
+
return;
|
148
|
+
}
|
149
|
+
state.selectedOrg = newValue;
|
150
|
+
// 选择选项后清空搜索文本
|
151
|
+
if (newValue) {
|
152
|
+
setSearchText('');
|
153
|
+
}
|
154
|
+
}}
|
155
|
+
inputValue={state.selectedOrg ? state.selectedOrg.name : searchText}
|
156
|
+
onInputChange={(_, newInputValue, reason) => {
|
157
|
+
// 只有用户键盘输入时才更新搜索文本
|
158
|
+
if (reason === 'input') {
|
159
|
+
// 用户开始输入时,清除当前选中的组织,进入搜索模式
|
160
|
+
if (state.selectedOrg) {
|
161
|
+
state.selectedOrg = null;
|
162
|
+
}
|
163
|
+
setSearchText(newInputValue);
|
164
|
+
}
|
165
|
+
}}
|
166
|
+
loading={loading}
|
167
|
+
loadingText={t('loading')}
|
168
|
+
noOptionsText={loading ? t('loading') : t('noResults')}
|
169
|
+
renderInput={(params) => (
|
170
|
+
<TextField
|
171
|
+
{...params}
|
172
|
+
variant="outlined"
|
173
|
+
fullWidth
|
174
|
+
InputProps={{
|
175
|
+
...params.InputProps,
|
176
|
+
endAdornment: (
|
177
|
+
<>
|
178
|
+
{loading && <CircularProgress color="inherit" size={20} />}
|
179
|
+
{params.InputProps.endAdornment}
|
180
|
+
</>
|
181
|
+
),
|
182
|
+
}}
|
183
|
+
/>
|
184
|
+
)}
|
185
|
+
renderOption={(props, option) => {
|
186
|
+
// 特殊处理加载项
|
187
|
+
if (option.isLoadingItem) {
|
188
|
+
return (
|
189
|
+
<Box component="li" {...props} key={option.id}>
|
190
|
+
<Box
|
191
|
+
sx={{
|
192
|
+
display: 'flex',
|
193
|
+
alignItems: 'center',
|
194
|
+
justifyContent: 'center',
|
195
|
+
flex: 1,
|
196
|
+
py: 1,
|
197
|
+
color: 'primary.main',
|
198
|
+
cursor: 'pointer',
|
199
|
+
}}>
|
200
|
+
{loadingMore && <CircularProgress size={16} sx={{ mr: 1 }} />}
|
201
|
+
<Typography variant="body2" sx={{ fontStyle: loadingMore ? 'italic' : 'normal' }}>
|
202
|
+
{option.name}
|
203
|
+
</Typography>
|
204
|
+
</Box>
|
205
|
+
</Box>
|
206
|
+
);
|
207
|
+
}
|
208
|
+
|
209
|
+
// 正常组织项的渲染
|
210
|
+
return (
|
211
|
+
<Box component="li" {...props} key={option.id}>
|
212
|
+
<Box sx={{ display: 'flex', flexDirection: 'column', flex: 1, minWidth: 0 }}>
|
213
|
+
<Typography
|
214
|
+
variant="body1"
|
215
|
+
sx={{
|
216
|
+
overflow: 'hidden',
|
217
|
+
textOverflow: 'ellipsis',
|
218
|
+
whiteSpace: 'nowrap',
|
219
|
+
}}>
|
220
|
+
{option.name}
|
221
|
+
</Typography>
|
222
|
+
{option.description && (
|
223
|
+
<Typography
|
224
|
+
variant="body2"
|
225
|
+
color="text.secondary"
|
226
|
+
sx={{
|
227
|
+
display: '-webkit-box',
|
228
|
+
WebkitLineClamp: 3,
|
229
|
+
WebkitBoxOrient: 'vertical',
|
230
|
+
overflow: 'hidden',
|
231
|
+
textOverflow: 'ellipsis',
|
232
|
+
}}>
|
233
|
+
{option.description}
|
234
|
+
</Typography>
|
235
|
+
)}
|
236
|
+
</Box>
|
237
|
+
</Box>
|
238
|
+
);
|
239
|
+
}}
|
240
|
+
sx={{
|
241
|
+
'& .MuiAutocomplete-listbox': {
|
242
|
+
maxHeight: 200,
|
243
|
+
},
|
244
|
+
}}
|
245
|
+
/>
|
246
|
+
</Box>
|
247
|
+
</Dialog>
|
248
|
+
);
|
249
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import type { ComponentProps } from 'react';
|
2
|
+
import { ButtonProps } from '@mui/material';
|
3
|
+
import Dialog from '../Dialog';
|
4
|
+
|
5
|
+
export type Org = {
|
6
|
+
id: string;
|
7
|
+
name: string;
|
8
|
+
description?: string;
|
9
|
+
ownerDid: string;
|
10
|
+
metadata?: Record<string, any>;
|
11
|
+
};
|
12
|
+
|
13
|
+
type DialogProps = ComponentProps<typeof Dialog> & {
|
14
|
+
placeholder?: string; // 搜索框的 placeholder
|
15
|
+
};
|
16
|
+
|
17
|
+
export type OrgTransferSelectorProps = Omit<OrgTransferProps, 'children' | 'buttonProps' | 'buttonText'> & {
|
18
|
+
ref: React.RefObject<unknown | null>;
|
19
|
+
};
|
20
|
+
|
21
|
+
export interface OrgTransferProps {
|
22
|
+
resourceId: string;
|
23
|
+
onSuccess?: (org: Org) => void;
|
24
|
+
org?: Org; // 当前所在的 Org
|
25
|
+
children?: React.ReactNode;
|
26
|
+
buttonProps?: ButtonProps;
|
27
|
+
buttonText?: string;
|
28
|
+
dialogProps?: DialogProps;
|
29
|
+
locale?: string;
|
30
|
+
[key: string]: any;
|
31
|
+
}
|
@@ -5,18 +5,9 @@ import isNil from 'lodash/isNil';
|
|
5
5
|
import type { AxiosError } from 'axios';
|
6
6
|
import { BlockletSDK } from '@blocklet/js-sdk';
|
7
7
|
import Toast from '../Toast';
|
8
|
+
import { formatAxiosError } from '../Util';
|
8
9
|
import type { User } from './types';
|
9
10
|
|
10
|
-
export const formatAxiosError = (err: AxiosError) => {
|
11
|
-
const { response } = err;
|
12
|
-
|
13
|
-
if (response) {
|
14
|
-
return `Request failed: ${response.status} ${response.statusText}: ${JSON.stringify(response.data)}`;
|
15
|
-
}
|
16
|
-
|
17
|
-
return err.message;
|
18
|
-
};
|
19
|
-
|
20
11
|
/**
|
21
12
|
* 登录用户与当前用户(userDid)的关注关系
|
22
13
|
*/
|
package/src/Util/index.ts
CHANGED
@@ -15,6 +15,7 @@ import timezone from 'dayjs/plugin/timezone';
|
|
15
15
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
16
16
|
import updateLocale from 'dayjs/plugin/updateLocale';
|
17
17
|
import localizedFormat from 'dayjs/plugin/localizedFormat';
|
18
|
+
import type { AxiosError } from 'axios';
|
18
19
|
import semver from 'semver';
|
19
20
|
|
20
21
|
import { DID_PREFIX, BLOCKLET_SERVICE_PATH_PREFIX } from './constant';
|
@@ -737,3 +738,13 @@ export const isSupportFollow = () => {
|
|
737
738
|
const jsSdkVersionSupport = compareVersions(jsSdkVersion, '1.16.49-beta-20250822-070545-6d3344cc');
|
738
739
|
return uxVersionSupport && serverVersionSupport && jsSdkVersionSupport;
|
739
740
|
};
|
741
|
+
|
742
|
+
export const formatAxiosError = (err: AxiosError) => {
|
743
|
+
const { response } = err;
|
744
|
+
|
745
|
+
if (response) {
|
746
|
+
return `Request failed: ${response.status} ${response.statusText}: ${JSON.stringify(response.data)}`;
|
747
|
+
}
|
748
|
+
|
749
|
+
return err.message || 'Unknown error occurred';
|
750
|
+
};
|