@lark-apaas/client-toolkit 1.1.11 → 1.1.13-userprofile-test.0

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.
@@ -0,0 +1 @@
1
+ export * from '../../hooks/useTheme';
@@ -0,0 +1 @@
1
+ export * from "../../hooks/useTheme.js";
@@ -1,7 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import type { IUserProfile } from '../../apis/udt-types';
3
3
  export interface UserDisplayProps {
4
- users: IUserProfile[];
4
+ /**
5
+ * 支持传入完整的用户资料(IUserProfile)/ 列表(IUserProfile[])
6
+ * 或仅传入用户 ID(string)/ 列表(string[])。
7
+ * 当传入 user_id 或 user_id[] 时组件会自动拉取用户资料并渲染。
8
+ */
9
+ users: IUserProfile | IUserProfile[] | string | string[];
5
10
  size?: 'small' | 'medium' | 'large';
6
11
  className?: string;
7
12
  style?: React.CSSProperties;
@@ -6,38 +6,82 @@ import { UserProfile } from "./UserProfile/index.js";
6
6
  import { UserWithAvatar } from "./UserWithAvatar.js";
7
7
  import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover.js";
8
8
  const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
9
- const normalizedUsers = useMemo(()=>Array.isArray(users) ? users : [
10
- users
11
- ].filter(Boolean), [
9
+ const normalizedIds = useMemo(()=>{
10
+ if (!users) return [];
11
+ if (Array.isArray(users)) {
12
+ if (0 === users.length) return [];
13
+ const first = users[0];
14
+ const isStringArray = 'string' == typeof first;
15
+ return isStringArray ? users.filter(Boolean).map((id)=>String(id)) : users.map((u)=>String(u.user_id)).filter(Boolean);
16
+ }
17
+ return 'string' == typeof users ? [
18
+ String(users)
19
+ ] : [
20
+ String(users.user_id)
21
+ ].filter(Boolean);
22
+ }, [
23
+ users
24
+ ]);
25
+ const inputProfilesMap = useMemo(()=>{
26
+ const map = new Map();
27
+ if (!users) return map;
28
+ if (Array.isArray(users)) {
29
+ const first = users[0];
30
+ const isStringArray = 'string' == typeof first;
31
+ if (!isStringArray) {
32
+ for (const u of users)if (u?.user_id) map.set(String(u.user_id), {
33
+ user_id: String(u.user_id),
34
+ name: u?.name ?? '',
35
+ avatar: u?.avatar ?? '',
36
+ email: u?.email ?? '',
37
+ status: u?.status ?? 1
38
+ });
39
+ }
40
+ } else if ('string' != typeof users) {
41
+ const u = users;
42
+ if (u?.user_id) map.set(String(u.user_id), {
43
+ user_id: String(u.user_id),
44
+ name: u?.name ?? '',
45
+ avatar: u?.avatar ?? '',
46
+ email: u?.email ?? '',
47
+ status: u?.status ?? 1
48
+ });
49
+ }
50
+ return map;
51
+ }, [
12
52
  users
13
53
  ]);
14
- const [resolvedUsers, setResolvedUsers] = useState(normalizedUsers);
54
+ const [resolvedUsers, setResolvedUsers] = useState(()=>normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
55
+ user_id: id,
56
+ name: '',
57
+ avatar: '',
58
+ email: '',
59
+ status: 1
60
+ }));
15
61
  const [loadingProfiles, setLoadingProfiles] = useState(false);
16
62
  useEffect(()=>{
17
63
  let isCancelled = false;
18
- if (!normalizedUsers.length) {
64
+ if (!normalizedIds.length) {
19
65
  setResolvedUsers([]);
20
66
  setLoadingProfiles(false);
21
67
  return ()=>{
22
68
  isCancelled = true;
23
69
  };
24
70
  }
25
- const usersNeedingDetails = normalizedUsers.filter((user)=>!user?.name?.trim());
26
- if (!usersNeedingDetails.length) {
27
- setResolvedUsers(normalizedUsers);
28
- setLoadingProfiles(false);
29
- return ()=>{
30
- isCancelled = true;
31
- };
32
- }
33
71
  const fetchProfiles = async ()=>{
34
72
  try {
35
73
  setLoadingProfiles(true);
36
74
  const dataloom = await getDataloom();
37
75
  if (!dataloom) throw new Error('dataloom client is unavailable');
38
- const ids = usersNeedingDetails.map((user)=>Number(user.user_id)).filter((id)=>Number.isFinite(id));
76
+ const ids = normalizedIds.map((id)=>Number(id)).filter((id)=>Number.isFinite(id));
39
77
  if (!ids.length) {
40
- setResolvedUsers(normalizedUsers);
78
+ setResolvedUsers(normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
79
+ user_id: id,
80
+ name: '',
81
+ avatar: '',
82
+ email: '',
83
+ status: 1
84
+ }));
41
85
  setLoadingProfiles(false);
42
86
  return;
43
87
  }
@@ -51,28 +95,35 @@ const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
51
95
  user_id: id,
52
96
  name: profile?.name ?? '',
53
97
  avatar: profile?.avatar ?? '',
54
- email: profile?.email,
55
- status: profile?.status,
56
- ...profile
98
+ email: profile?.email ?? '',
99
+ status: profile?.status ?? 1
57
100
  });
58
101
  });
59
- const mergedUsers = normalizedUsers.map((user)=>{
60
- const id = String(user.user_id);
102
+ const mergedUsers = normalizedIds.map((id)=>{
61
103
  const fetched = fetchedMap.get(id);
62
- if (!fetched) return user;
104
+ const given = inputProfilesMap.get(id);
105
+ const name = given?.name?.trim() ? given.name : fetched?.name ?? '';
106
+ const avatar = given?.avatar || fetched?.avatar || '';
107
+ const email = given?.email || fetched?.email || '';
108
+ const status = given?.status ?? fetched?.status ?? 1;
63
109
  return {
64
- ...fetched,
65
- ...user,
66
- name: user?.name?.trim() ? user.name : fetched.name,
67
- avatar: user.avatar || fetched.avatar,
68
- email: user.email || fetched.email,
69
- status: user.status ?? fetched.status
110
+ user_id: id,
111
+ name,
112
+ avatar,
113
+ email,
114
+ status
70
115
  };
71
116
  });
72
117
  if (!isCancelled) setResolvedUsers(mergedUsers);
73
118
  } catch (error) {
74
119
  console.error('Failed to resolve user profiles:', error);
75
- if (!isCancelled) setResolvedUsers(normalizedUsers);
120
+ if (!isCancelled) setResolvedUsers(normalizedIds.map((id)=>inputProfilesMap.get(id) ?? {
121
+ user_id: id,
122
+ name: '',
123
+ avatar: '',
124
+ email: '',
125
+ status: 1
126
+ }));
76
127
  } finally{
77
128
  if (!isCancelled) setLoadingProfiles(false);
78
129
  }
@@ -82,7 +133,7 @@ const UserDisplay = ({ users, size, className, style, showLabel = true })=>{
82
133
  isCancelled = true;
83
134
  };
84
135
  }, [
85
- normalizedUsers.length
136
+ normalizedIds
86
137
  ]);
87
138
  if (!resolvedUsers.length || loadingProfiles) return null;
88
139
  return /*#__PURE__*/ jsx("div", {
@@ -0,0 +1,4 @@
1
+ export declare function useTheme(): {
2
+ theme: string;
3
+ setTheme: import("react").Dispatch<import("react").SetStateAction<string>>;
4
+ };
@@ -0,0 +1,9 @@
1
+ import { useState } from "react";
2
+ function useTheme() {
3
+ const [theme, setTheme] = useState('system');
4
+ return {
5
+ theme,
6
+ setTheme
7
+ };
8
+ }
9
+ export { useTheme };
@@ -17,10 +17,11 @@ function interceptErrors() {
17
17
  const originalMethod = window.console[method];
18
18
  window.console[method] = (...args)=>{
19
19
  originalMethod(...args);
20
+ const level = 'log' === method ? 'info' : method;
20
21
  const log = args[0];
21
- if ('string' == typeof log && log.startsWith('[Dataloom]') && levelSchema.safeParse(method).success) {
22
+ if ('string' == typeof log && log.startsWith('[Dataloom]') && levelSchema.safeParse(level).success) {
22
23
  logger.log({
23
- level: method,
24
+ level: level,
24
25
  args
25
26
  });
26
27
  postMessage({
@@ -28,10 +28,10 @@ export declare const logStackFrameSchema: z.ZodObject<{
28
28
  }, z.core.$strip>;
29
29
  export declare const levelSchema: z.ZodEnum<{
30
30
  success: "success";
31
+ debug: "debug";
31
32
  info: "info";
32
33
  warn: "warn";
33
34
  error: "error";
34
- debug: "debug";
35
35
  }>;
36
36
  export declare const logMeta: z.ZodObject<{
37
37
  stacktrace: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -45,15 +45,18 @@ export declare const logMeta: z.ZodObject<{
45
45
  noStacktrace: z.ZodOptional<z.ZodBoolean>;
46
46
  repairMessage: z.ZodOptional<z.ZodString>;
47
47
  type: z.ZodOptional<z.ZodString>;
48
+ isDuplicate: z.ZodOptional<z.ZodBoolean>;
49
+ duplicateCount: z.ZodOptional<z.ZodNumber>;
50
+ duplicateOfId: z.ZodOptional<z.ZodString>;
48
51
  }, z.core.$strip>;
49
52
  export declare const selectedLogSchema: z.ZodObject<{
50
53
  type: z.ZodLiteral<"typedLogV2">;
51
54
  level: z.ZodEnum<{
52
55
  success: "success";
56
+ debug: "debug";
53
57
  info: "info";
54
58
  warn: "warn";
55
59
  error: "error";
56
- debug: "debug";
57
60
  }>;
58
61
  id: z.ZodString;
59
62
  args: z.ZodArray<z.ZodUnknown>;
@@ -69,16 +72,19 @@ export declare const selectedLogSchema: z.ZodObject<{
69
72
  noStacktrace: z.ZodOptional<z.ZodBoolean>;
70
73
  repairMessage: z.ZodOptional<z.ZodString>;
71
74
  type: z.ZodOptional<z.ZodString>;
75
+ isDuplicate: z.ZodOptional<z.ZodBoolean>;
76
+ duplicateCount: z.ZodOptional<z.ZodNumber>;
77
+ duplicateOfId: z.ZodOptional<z.ZodString>;
72
78
  }, z.core.$strip>;
73
79
  }, z.core.$strip>;
74
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'success';
80
+ export type LogLevel = z.infer<typeof levelSchema>;
75
81
  export declare const logWithMetaSchema: z.ZodObject<{
76
82
  level: z.ZodEnum<{
77
83
  success: "success";
84
+ debug: "debug";
78
85
  info: "info";
79
86
  warn: "warn";
80
87
  error: "error";
81
- debug: "debug";
82
88
  }>;
83
89
  args: z.ZodArray<z.ZodUnknown>;
84
90
  meta: z.ZodOptional<z.ZodObject<{
@@ -93,6 +99,9 @@ export declare const logWithMetaSchema: z.ZodObject<{
93
99
  noStacktrace: z.ZodOptional<z.ZodBoolean>;
94
100
  repairMessage: z.ZodOptional<z.ZodString>;
95
101
  type: z.ZodOptional<z.ZodString>;
102
+ isDuplicate: z.ZodOptional<z.ZodBoolean>;
103
+ duplicateCount: z.ZodOptional<z.ZodNumber>;
104
+ duplicateOfId: z.ZodOptional<z.ZodString>;
96
105
  }, z.core.$strip>>;
97
106
  }, z.core.$strip>;
98
107
  export type LogStackFrame = z.infer<typeof logStackFrameSchema>;
@@ -27,10 +27,10 @@ const logStackFrameSchema = zod.object({
27
27
  columnNumber: zod.number()
28
28
  });
29
29
  const levelSchema = zod["enum"]([
30
+ 'debug',
30
31
  'info',
31
32
  'warn',
32
33
  'error',
33
- 'debug',
34
34
  'success'
35
35
  ]);
36
36
  const logMeta = zod.object({
@@ -39,7 +39,10 @@ const logMeta = zod.object({
39
39
  skipFrame: zod.optional(zod.number()),
40
40
  noStacktrace: zod.optional(zod.boolean()),
41
41
  repairMessage: zod.optional(zod.string()),
42
- type: zod.optional(zod.string())
42
+ type: zod.optional(zod.string()),
43
+ isDuplicate: zod.optional(zod.boolean()),
44
+ duplicateCount: zod.optional(zod.number()),
45
+ duplicateOfId: zod.optional(zod.string())
43
46
  });
44
47
  const selectedLogSchema = zod.object({
45
48
  type: zod.literal('typedLogV2'),
@@ -40,7 +40,17 @@ async function sendSelectedLog(logWithoutID) {
40
40
  if (!log.meta.stacktrace) try {
41
41
  const stacktrace = await stacktrace_js.fromError(error);
42
42
  log.meta.stacktrace = mapStacktrace(stacktrace);
43
- } catch (e) {}
43
+ } catch (e) {
44
+ if (window.parent !== window) try {
45
+ window.parent.postMessage({
46
+ type: 'STACKTRACE_PARSE_ERROR',
47
+ payload: {
48
+ error: e instanceof Error ? e.message : String(e),
49
+ context: 'StackTrace.fromError'
50
+ }
51
+ }, '*');
52
+ } catch (postError) {}
53
+ }
44
54
  newParts.push(newError.message, newError);
45
55
  } else newParts.push(log.args[i]);
46
56
  log.args = newParts;
@@ -49,11 +59,46 @@ async function sendSelectedLog(logWithoutID) {
49
59
  const firstFrameIndex = frames.findIndex((frame)=>!frame.fileName.includes('node_modules/@lark-apaas/client-toolkit/lib/logger'));
50
60
  frames = -1 === firstFrameIndex ? [] : frames.slice(firstFrameIndex);
51
61
  log.meta.stacktrace = frames;
52
- } catch (e) {}
62
+ } catch (e) {
63
+ if (window.parent !== window) try {
64
+ window.parent.postMessage({
65
+ type: 'STACKTRACE_PARSE_ERROR',
66
+ payload: {
67
+ error: e instanceof Error ? e.message : String(e),
68
+ context: 'getStacktrace'
69
+ }
70
+ }, '*');
71
+ } catch (postError) {}
72
+ }
53
73
  if (void 0 === log.meta.skipFrame) log.meta.skipFrame = 2;
54
74
  const logJSON = JSON.stringify(log);
55
- console.log(JSON.parse(logJSON));
56
- console.log(logJSON);
75
+ const logForDedup = {
76
+ ...log
77
+ };
78
+ delete logForDedup.id;
79
+ const logContentForDedup = JSON.stringify(logForDedup);
80
+ if (lastLogInfo && lastLogInfo.content === logContentForDedup) {
81
+ lastLogInfo.count++;
82
+ log.meta.isDuplicate = true;
83
+ log.meta.duplicateCount = lastLogInfo.count;
84
+ log.meta.duplicateOfId = lastLogInfo.id;
85
+ const updatedLogJSON = JSON.stringify(log);
86
+ try {
87
+ batchLogInfo('info', updatedLogJSON);
88
+ } catch (e) {}
89
+ if (window.parent !== window) try {
90
+ window.parent.postMessage({
91
+ type: 'SELECTED_LOG',
92
+ payload: updatedLogJSON
93
+ }, '*');
94
+ } catch (e) {}
95
+ return;
96
+ }
97
+ lastLogInfo = {
98
+ content: logContentForDedup,
99
+ id: log.id,
100
+ count: 1
101
+ };
57
102
  try {
58
103
  batchLogInfo('info', logJSON);
59
104
  } catch (e) {}
@@ -70,6 +115,7 @@ async function getStacktrace() {
70
115
  const frames = mapStacktrace(stacktrace);
71
116
  return frames;
72
117
  }
118
+ let lastLogInfo = null;
73
119
  async function sendTypedLogV2(logWithMeta) {
74
120
  sendSelectedLog({
75
121
  type: 'typedLogV2',
@@ -84,7 +130,7 @@ const typedLogInterceptor = (logger)=>({
84
130
  logger.debug(message, ...args);
85
131
  } catch (e) {}
86
132
  sendTypedLogV2({
87
- level: 'debug',
133
+ level: 'info',
88
134
  args: [
89
135
  message,
90
136
  ...args
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/client-toolkit",
3
- "version": "1.1.11",
3
+ "version": "1.1.13-userprofile-test.0",
4
4
  "types": "./lib/index.d.ts",
5
5
  "main": "./lib/index.js",
6
6
  "files": [