bi-sdk-react 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/es/css/bi-sdk.css +1 -1
  2. package/dist/es/js/bi-sdk.es.js +296 -63
  3. package/dist/types/components/PageDesigner.d.ts +9 -1
  4. package/dist/types/components/context/DesignerContext.d.ts +5 -2
  5. package/dist/types/components/context/EnvContext.d.ts +2 -1
  6. package/dist/types/components/icon/IconFont.d.ts +2 -1
  7. package/dist/types/components/layout/PageCanvas.d.ts +2 -0
  8. package/dist/types/components/panel/AiPanel.d.ts +4 -0
  9. package/dist/types/components/panel/ChatInput.d.ts +13 -6
  10. package/dist/types/components/panel/DatasetPanel.d.ts +11 -0
  11. package/dist/types/components/panel/PaneHeader.d.ts +1 -0
  12. package/dist/types/components/panel/PropertiesPanel.d.ts +3 -1
  13. package/dist/types/components/plugins/@antd/item-props/EchartsProps.d.ts +2 -2
  14. package/dist/types/components/plugins/@antd/item-props/TextProps.d.ts +1 -0
  15. package/dist/types/components/plugins/@antd/items/TableRender.d.ts +1 -0
  16. package/dist/types/components/plugins/@antd/items/TextRender.d.ts +1 -0
  17. package/dist/types/components/typing.d.ts +102 -2
  18. package/dist/types/components/utils.d.ts +1 -0
  19. package/dist/umd/css/bi-sdk.css +1 -1
  20. package/dist/umd/js/bi-sdk.umd.min.js +300 -67
  21. package/package.json +3 -2
  22. package/src/components/PageDesigner.tsx +231 -37
  23. package/src/components/context/DesignerContext.tsx +15 -3
  24. package/src/components/context/EnvContext.tsx +4 -1
  25. package/src/components/icon/IconFont.tsx +15 -11
  26. package/src/components/layout/PageCanvas.tsx +4 -2
  27. package/src/components/layout/PageItem.tsx +1 -1
  28. package/src/components/panel/AiPanel.tsx +656 -43
  29. package/src/components/panel/ChatInput.tsx +259 -147
  30. package/src/components/panel/DatasetPanel.tsx +65 -0
  31. package/src/components/panel/PaneHeader.tsx +3 -2
  32. package/src/components/panel/PropertiesPanel.tsx +332 -125
  33. package/src/components/plugins/@antd/index.ts +12 -8
  34. package/src/components/plugins/@antd/item-props/EchartsProps.tsx +52 -22
  35. package/src/components/plugins/@antd/item-props/HtmlProps.tsx +8 -9
  36. package/src/components/plugins/@antd/item-props/TextProps.tsx +13 -1
  37. package/src/components/plugins/@antd/items/EchartsRender.tsx +9 -1
  38. package/src/components/plugins/@antd/items/HtmlRender.tsx +13 -1
  39. package/src/components/plugins/@antd/items/ListRender.tsx +18 -1
  40. package/src/components/plugins/@antd/items/TableRender.tsx +16 -1
  41. package/src/components/plugins/@antd/items/TextRender.tsx +3 -1
  42. package/src/components/styles.css +20 -0
  43. package/src/components/typing.ts +117 -2
  44. package/src/components/utils.ts +40 -0
  45. package/src/example.tsx +344 -13
@@ -2,6 +2,7 @@ import React, { useRef } from "react";
2
2
  import { Form } from "antd";
3
3
  import Editor from "@monaco-editor/react";
4
4
  import type { PropEditorProps } from "./types";
5
+ import { IconFont } from "../../../icon/IconFont";
5
6
 
6
7
  export type HtmlModel = { template: string };
7
8
 
@@ -21,16 +22,14 @@ export const HtmlProps: React.FC<PropEditorProps<HtmlModel>> = ({
21
22
  <Form layout="vertical">
22
23
  <Form.Item
23
24
  label={
24
- <div
25
- style={{
26
- display: "flex",
27
- alignItems: "center",
28
- justifyContent: "space-between",
29
- }}
30
- >
31
- 模板 <a onClick={format}>格式化</a>
32
- </div>
25
+ <>
26
+ 模板
27
+ <a onClick={format}>
28
+ <IconFont type="icon-formate" /> 格式化
29
+ </a>
30
+ </>
33
31
  }
32
+ className="ant-form-item-label-space"
34
33
  >
35
34
  <div
36
35
  style={{
@@ -2,7 +2,11 @@ import React from "react";
2
2
  import { Form, Input, Select, Button, Space, ColorPicker } from "antd";
3
3
  import type { PropEditorProps } from "./types";
4
4
 
5
- export type TextModel = { text?: string; customStyle?: React.CSSProperties };
5
+ export type TextModel = {
6
+ text?: string;
7
+ customStyle?: React.CSSProperties;
8
+ classNames?: string[];
9
+ };
6
10
 
7
11
  export const TextProps: React.FC<PropEditorProps<TextModel>> = ({
8
12
  model,
@@ -23,6 +27,14 @@ export const TextProps: React.FC<PropEditorProps<TextModel>> = ({
23
27
  onChange={(e) => triggerModel("text", e.target.value)}
24
28
  />
25
29
  </Form.Item>
30
+ <Form.Item label="类名">
31
+ <Select
32
+ size="small"
33
+ value={model.classNames}
34
+ mode="tags"
35
+ onChange={(value) => triggerModel("classNames", value)}
36
+ />
37
+ </Form.Item>
26
38
  <div
27
39
  style={{
28
40
  display: "flex",
@@ -1,7 +1,9 @@
1
- import React, { useEffect, useRef, useState } from "react";
1
+ import React, { useContext, useEffect, useRef, useState } from "react";
2
2
  import * as echarts from "echarts";
3
3
  import { HtmlBaseProps } from "../../../typing";
4
4
  import { useDatasource } from "../../../hooks/datasource";
5
+ import { EnvContext } from "../../../context/EnvContext";
6
+ import { getVars } from "../../../utils";
5
7
 
6
8
  export type EchartsRenderProps = {
7
9
  item: any;
@@ -19,6 +21,7 @@ export const EchartsRender: React.FC<EchartsRenderProps> = ({
19
21
  style,
20
22
  className,
21
23
  }) => {
24
+ const { initCallback, env } = useContext(EnvContext);
22
25
  const chartRef = useRef<HTMLDivElement | null>(null);
23
26
  const [chart, setChart] = useState<echarts.ECharts | null>(null);
24
27
  const datasource = useDatasource(id, item.datasource);
@@ -68,12 +71,17 @@ export const EchartsRender: React.FC<EchartsRenderProps> = ({
68
71
  }
69
72
  }
70
73
  };
74
+ const callback = () => {
75
+ const vars = getVars(env, item);
76
+ console.log("callback echarts", vars);
77
+ };
71
78
  useEffect(() => {
72
79
  if (!chartRef.current) return;
73
80
  const next = echarts.init(chartRef.current);
74
81
  setChart(next);
75
82
  const onResize = () => next.resize();
76
83
  window.addEventListener("resize", onResize);
84
+ initCallback({ id: item.id, callback });
77
85
  return () => {
78
86
  window.removeEventListener("resize", onResize);
79
87
  next.dispose();
@@ -1,6 +1,8 @@
1
- import React, { useMemo } from "react";
1
+ import React, { useContext, useEffect, useMemo } from "react";
2
2
  import { HtmlBaseProps } from "../../../typing";
3
3
  import { useDatasource } from "../../../hooks/datasource";
4
+ import { getVars } from "../../../utils";
5
+ import { EnvContext } from "../../../context/EnvContext";
4
6
 
5
7
  export type HtmlRenderProps = {
6
8
  dataSource?: Record<string, any>;
@@ -27,6 +29,7 @@ export const HtmlRender: React.FC<HtmlRenderProps> = ({
27
29
  style,
28
30
  className,
29
31
  }) => {
32
+ const { env, initCallback } = useContext(EnvContext);
30
33
  const datasource = useDatasource(id, item.datasource);
31
34
  const keys = useMemo(() => Object.keys(datasource || {}), [datasource]);
32
35
  const func = (path: string) =>
@@ -63,6 +66,15 @@ export const HtmlRender: React.FC<HtmlRenderProps> = ({
63
66
  [template, args]
64
67
  );
65
68
 
69
+ const callback = () => {
70
+ const vars = getVars(env, item);
71
+ console.log("callback html", vars);
72
+ };
73
+
74
+ useEffect(() => {
75
+ initCallback({ id: item.id, callback });
76
+ }, []);
77
+
66
78
  return (
67
79
  <div
68
80
  id={id}
@@ -1,8 +1,15 @@
1
- import React, { MouseEventHandler, useMemo } from "react";
1
+ import React, {
2
+ MouseEventHandler,
3
+ useContext,
4
+ useEffect,
5
+ useMemo,
6
+ } from "react";
2
7
  import { Avatar, Pagination } from "antd";
3
8
  import styled, { css } from "styled-components";
4
9
  import { HtmlBaseProps } from "../../../typing";
5
10
  import { useDatasource } from "../../../hooks/datasource";
11
+ import { getVars } from "../../../utils";
12
+ import { EnvContext } from "../../../context/EnvContext";
6
13
 
7
14
  type DataItem = {
8
15
  title?: string;
@@ -184,6 +191,7 @@ export const ListRender: React.FC<ListRenderProps> = ({
184
191
  style = {},
185
192
  className,
186
193
  }) => {
194
+ const { env, initCallback } = useContext(EnvContext);
187
195
  const datasource = useDatasource(id, item.datasource);
188
196
  const list = datasource || [];
189
197
  const pagination = useMemo(() => {
@@ -208,6 +216,15 @@ export const ListRender: React.FC<ListRenderProps> = ({
208
216
  bordered ? "p-list--bordered" : undefined,
209
217
  className,
210
218
  ];
219
+
220
+ const callback = () => {
221
+ const vars = getVars(env, item);
222
+ console.log("callback list", vars);
223
+ };
224
+
225
+ useEffect(() => {
226
+ initCallback({ id: item.id, callback });
227
+ }, []);
211
228
  return (
212
229
  <div
213
230
  id={id}
@@ -1,6 +1,8 @@
1
- import React from "react";
1
+ import React, { useContext, useEffect } from "react";
2
2
  import { Table, type TableProps } from "antd";
3
3
  import { HtmlBaseProps } from "../../../typing";
4
+ import { getVars } from "../../../utils";
5
+ import { EnvContext } from "../../../context/EnvContext";
4
6
 
5
7
  export type TableRenderProps = {
6
8
  dataSource?: any[];
@@ -9,10 +11,12 @@ export type TableRenderProps = {
9
11
  bordered?: boolean;
10
12
  size?: TableProps["size"];
11
13
  showHeader?: boolean;
14
+ item: any;
12
15
  } & HtmlBaseProps;
13
16
 
14
17
  export const TableRender: React.FC<TableRenderProps> = ({
15
18
  id,
19
+ item,
16
20
  dataSource = [],
17
21
  columns = [],
18
22
  pageSize = 10,
@@ -22,6 +26,7 @@ export const TableRender: React.FC<TableRenderProps> = ({
22
26
  style = {},
23
27
  className,
24
28
  }) => {
29
+ const { env, initCallback } = useContext(EnvContext);
25
30
  const pagination =
26
31
  !pageSize || pageSize <= dataSource.length
27
32
  ? false
@@ -82,6 +87,16 @@ export const TableRender: React.FC<TableRenderProps> = ({
82
87
  );
83
88
  },
84
89
  }));
90
+
91
+ const callback = () => {
92
+ const vars = getVars(env, item);
93
+ console.log("callback table", vars);
94
+ };
95
+
96
+ useEffect(() => {
97
+ initCallback({ id: item.id, callback });
98
+ }, []);
99
+
85
100
  return (
86
101
  <Table
87
102
  id={id}
@@ -5,6 +5,7 @@ export type TextRenderProps = {
5
5
  text?: string;
6
6
  customStyle?: React.CSSProperties;
7
7
  item?: { style?: React.CSSProperties };
8
+ classNames?: string[];
8
9
  } & HtmlBaseProps;
9
10
 
10
11
  export const TextRender: React.FC<TextRenderProps> = ({
@@ -14,6 +15,7 @@ export const TextRender: React.FC<TextRenderProps> = ({
14
15
  style = {},
15
16
  customStyle = {},
16
17
  className,
18
+ classNames = [],
17
19
  }) => {
18
20
  const actualStyle = useMemo(
19
21
  () => ({
@@ -24,7 +26,7 @@ export const TextRender: React.FC<TextRenderProps> = ({
24
26
  [item, customStyle, style]
25
27
  );
26
28
  return (
27
- <span id={id} style={actualStyle} className={className}>
29
+ <span id={id} style={actualStyle} className={(classNames || []).join(" ") + (" " + className || "")}>
28
30
  {text}
29
31
  </span>
30
32
  );
@@ -10,3 +10,23 @@ a.toolbar {
10
10
  color: var(--ant-color-primary);
11
11
  }
12
12
  }
13
+
14
+ .ant-form-compact .ant-form-item {
15
+ margin-bottom: 8px;
16
+ }
17
+
18
+ .ant-form-item-label label {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ }
22
+
23
+ .ant-form-item.ant-form-item-label-space .ant-form-item-label label {
24
+ width: 100%;
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+
29
+ &::after {
30
+ content: none;
31
+ }
32
+ }
@@ -1,4 +1,89 @@
1
- import { MouseEventHandler } from "react";
1
+ import React, { MouseEventHandler } from "react";
2
+
3
+ export type ChatRequestType = {
4
+ message: string;
5
+ files?: { id: string; name: string; extension: string }[] | null;
6
+ agents?: { id: string | number; name: string }[] | null;
7
+ page?: PageSchema | null;
8
+ pageItems?: SchemaItemType[] | null;
9
+ };
10
+
11
+ export type ChatResponseAnswerEffectType = {
12
+ datasets?: DataSetType[] | null;
13
+ schema?: PageSchema;
14
+ pageItems?: SchemaItemType[] | null;
15
+ };
16
+
17
+ export type ChatResponseAnswerPlanType = {
18
+ name: string;
19
+ description: string;
20
+ };
21
+
22
+ export type ChatResponseAnswerType = {
23
+ answer: string;
24
+ plans?: ChatResponseAnswerPlanType[] | null;
25
+ effect?: ChatResponseAnswerEffectType | null;
26
+ extra?:
27
+ | { id: string; element: string; action: string; area: string }[]
28
+ | null;
29
+ };
30
+
31
+ export type ChatResponseType = {
32
+ id: string;
33
+ answer: ChatResponseAnswerType;
34
+ createdAt: string;
35
+ conversation?: ChatConversationType | null;
36
+ };
37
+
38
+ export type ChatConversationType = {
39
+ id: string;
40
+ name: string;
41
+ createdAt: string;
42
+ isActived: boolean;
43
+ };
44
+
45
+ export type ChatMessageType = {
46
+ id: string;
47
+ conversationId: string | null;
48
+ question: string;
49
+ answer: ChatResponseAnswerType;
50
+ files: { id: string; name: string; extension: string }[];
51
+ agents: { id: string | number; name: string }[];
52
+ createdAt: string;
53
+ sending?: boolean;
54
+ };
55
+
56
+ export type FetchType = {
57
+ upload?: (file: File) => Promise<{ id: string; name: string }>;
58
+ ai?: {
59
+ chat: (
60
+ bizType: string,
61
+ bizId: string,
62
+ conversationId: string | null,
63
+ request: ChatRequestType
64
+ ) => Promise<ChatResponseType>;
65
+ conversationList: (
66
+ bizType: string,
67
+ bizId: string
68
+ ) => Promise<ChatConversationType[]>;
69
+ messageList: (
70
+ bizType: string,
71
+ bizId: string,
72
+ conversationId?: string | null
73
+ ) => Promise<ChatMessageType[]>;
74
+ removeConversation: (
75
+ bizType: string,
76
+ bizId: string,
77
+ conversationId: string
78
+ ) => Promise<boolean>;
79
+ removeMessage: (
80
+ bizType: string,
81
+ bizId: string,
82
+ messageId: string
83
+ ) => Promise<boolean>;
84
+ };
85
+ dataset?: (dataSetId: string, params: Record<string, any>) => Promise<any>;
86
+ };
2
87
 
3
88
  export type HtmlBaseProps = {
4
89
  id?: string;
@@ -17,10 +102,11 @@ export type SchemaItemType = {
17
102
  cascadeIds?: string[];
18
103
  children?: SchemaItemType[] | Record<string, SchemaItemType[]>;
19
104
  datasource?: {
20
- source?: "custom" | "define";
105
+ source?: "custom" | "define" | "dataset";
21
106
  datasourceId?: string | null;
22
107
  scriptId?: string | null;
23
108
  custom?: string | null;
109
+ dataset?: DataSetType;
24
110
  };
25
111
  };
26
112
 
@@ -58,6 +144,31 @@ export type SqlType = {
58
144
  query: string;
59
145
  };
60
146
 
147
+ export enum FieldType {
148
+ STRING = "STRING",
149
+ NUMBER = "NUMBER",
150
+ BOOLEAN = "BOOLEAN",
151
+ OBJECT = "OBJECT",
152
+ ARRAY = "ARRAY",
153
+ }
154
+
155
+ export type DataSetOutputField = {
156
+ key?: string;
157
+ name?: string;
158
+ type?: FieldType;
159
+ schema?: DataSetOutput;
160
+ };
161
+
162
+ export type DataSetOutput = {
163
+ fields?: DataSetOutputField[];
164
+ };
165
+
166
+ export type DataSetType = {
167
+ id: string;
168
+ name: string;
169
+ output: DataSetOutput;
170
+ };
171
+
61
172
  export type PageInfo = {
62
173
  name?: string;
63
174
  description?: string;
@@ -78,3 +189,7 @@ export type EnvType = {
78
189
  };
79
190
 
80
191
  export type CallbacksType = Record<string, (v: any) => void>;
192
+
193
+ export type DatasetSelectorFunction = (
194
+ onSelect: (dataset: DataSetType) => void
195
+ ) => React.ReactNode;
@@ -35,3 +35,43 @@ export const handleCallback = (
35
35
  };
36
36
 
37
37
  export const uuid = () => v4();
38
+
39
+
40
+
41
+ export const formatTime = (dateStr: string) => {
42
+ if (!dateStr) return "";
43
+ const date = new Date(dateStr);
44
+ const now = new Date();
45
+ const diff = now.getTime() - date.getTime();
46
+
47
+ if (diff < 60 * 1000) {
48
+ return "刚刚";
49
+ }
50
+ if (diff < 60 * 60 * 1000) {
51
+ return `${Math.floor(diff / (60 * 1000))}分钟前`;
52
+ }
53
+
54
+ const pad = (n: number) => n.toString().padStart(2, "0");
55
+ const HH = pad(date.getHours());
56
+ const mm = pad(date.getMinutes());
57
+
58
+ const isToday =
59
+ date.getDate() === now.getDate() &&
60
+ date.getMonth() === now.getMonth() &&
61
+ date.getFullYear() === now.getFullYear();
62
+
63
+ if (isToday) {
64
+ return `${HH}:${mm}`;
65
+ }
66
+
67
+ const MM = pad(date.getMonth() + 1);
68
+ const DD = pad(date.getDate());
69
+ const isThisYear = date.getFullYear() === now.getFullYear();
70
+
71
+ if (isThisYear) {
72
+ return `${MM}-${DD} ${HH}:${mm}`;
73
+ }
74
+
75
+ const YYYY = date.getFullYear();
76
+ return `${YYYY}-${MM}-${DD} ${HH}:${mm}`;
77
+ };