bi-sdk-react 0.0.1

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 (146) hide show
  1. package/dist/es/css/bi-sdk.css +1 -0
  2. package/dist/es/js/bi-sdk.es.js +795 -0
  3. package/dist/es/js/bi-sdk.es.js.LICENSE.txt +9 -0
  4. package/dist/types/components/PageDesigner.d.ts +10 -0
  5. package/dist/types/components/context/DesignerContext.d.ts +15 -0
  6. package/dist/types/components/context/EnvContext.d.ts +15 -0
  7. package/dist/types/components/dnd/DropContainer.d.ts +21 -0
  8. package/dist/types/components/example.d.ts +225 -0
  9. package/dist/types/components/hooks/datasource.d.ts +1 -0
  10. package/dist/types/components/hooks/useDeepCompareEffect.d.ts +1 -0
  11. package/dist/types/components/icon/IconFont.d.ts +6 -0
  12. package/dist/types/components/index.d.ts +10 -0
  13. package/dist/types/components/layout/PageCanvas.d.ts +6 -0
  14. package/dist/types/components/layout/PageItem.d.ts +27 -0
  15. package/dist/types/components/panel/AiPanel.d.ts +8 -0
  16. package/dist/types/components/panel/CascadePanel.d.ts +2 -0
  17. package/dist/types/components/panel/ChatInput.d.ts +28 -0
  18. package/dist/types/components/panel/CodePanel.d.ts +2 -0
  19. package/dist/types/components/panel/ComponentPanel.d.ts +2 -0
  20. package/dist/types/components/panel/DatasourcePanel.d.ts +2 -0
  21. package/dist/types/components/panel/LayerPanel.d.ts +2 -0
  22. package/dist/types/components/panel/PaneHeader.d.ts +6 -0
  23. package/dist/types/components/panel/PropertiesPanel.d.ts +2 -0
  24. package/dist/types/components/panel/ScriptPanel.d.ts +2 -0
  25. package/dist/types/components/panel/VariablesPanel.d.ts +2 -0
  26. package/dist/types/components/panel/index.d.ts +9 -0
  27. package/dist/types/components/plugins/@antd/index.d.ts +22 -0
  28. package/dist/types/components/plugins/@antd/item-props/ButtonProps.d.ts +8 -0
  29. package/dist/types/components/plugins/@antd/item-props/CapsuleProps.d.ts +13 -0
  30. package/dist/types/components/plugins/@antd/item-props/CardProps.d.ts +8 -0
  31. package/dist/types/components/plugins/@antd/item-props/CheckboxProps.d.ts +13 -0
  32. package/dist/types/components/plugins/@antd/item-props/ColProps.d.ts +12 -0
  33. package/dist/types/components/plugins/@antd/item-props/DatePickerProps.d.ts +8 -0
  34. package/dist/types/components/plugins/@antd/item-props/EchartsProps.d.ts +6 -0
  35. package/dist/types/components/plugins/@antd/item-props/HtmlProps.d.ts +6 -0
  36. package/dist/types/components/plugins/@antd/item-props/ImageProps.d.ts +10 -0
  37. package/dist/types/components/plugins/@antd/item-props/InputNumberProps.d.ts +9 -0
  38. package/dist/types/components/plugins/@antd/item-props/InputProps.d.ts +10 -0
  39. package/dist/types/components/plugins/@antd/item-props/ListProps.d.ts +10 -0
  40. package/dist/types/components/plugins/@antd/item-props/PageHeaderProps.d.ts +7 -0
  41. package/dist/types/components/plugins/@antd/item-props/RowProps.d.ts +6 -0
  42. package/dist/types/components/plugins/@antd/item-props/SelectProps.d.ts +16 -0
  43. package/dist/types/components/plugins/@antd/item-props/SpaceProps.d.ts +7 -0
  44. package/dist/types/components/plugins/@antd/item-props/SwitchProps.d.ts +6 -0
  45. package/dist/types/components/plugins/@antd/item-props/TableProps.d.ts +15 -0
  46. package/dist/types/components/plugins/@antd/item-props/TextProps.d.ts +6 -0
  47. package/dist/types/components/plugins/@antd/item-props/index.d.ts +19 -0
  48. package/dist/types/components/plugins/@antd/item-props/types.d.ts +5 -0
  49. package/dist/types/components/plugins/@antd/items/ButtonRender.d.ts +14 -0
  50. package/dist/types/components/plugins/@antd/items/CapsuleRender.d.ts +14 -0
  51. package/dist/types/components/plugins/@antd/items/CardRender.d.ts +12 -0
  52. package/dist/types/components/plugins/@antd/items/CheckboxRender.d.ts +14 -0
  53. package/dist/types/components/plugins/@antd/items/ColRender.d.ts +13 -0
  54. package/dist/types/components/plugins/@antd/items/DatePickerRender.d.ts +14 -0
  55. package/dist/types/components/plugins/@antd/items/EchartsRender.d.ts +10 -0
  56. package/dist/types/components/plugins/@antd/items/HtmlRender.d.ts +20 -0
  57. package/dist/types/components/plugins/@antd/items/ImageRender.d.ts +10 -0
  58. package/dist/types/components/plugins/@antd/items/InputNumberRender.d.ts +17 -0
  59. package/dist/types/components/plugins/@antd/items/InputRender.d.ts +17 -0
  60. package/dist/types/components/plugins/@antd/items/ListRender.d.ts +11 -0
  61. package/dist/types/components/plugins/@antd/items/PageHeaderRender.d.ts +8 -0
  62. package/dist/types/components/plugins/@antd/items/RowRender.d.ts +13 -0
  63. package/dist/types/components/plugins/@antd/items/SelectRender.d.ts +18 -0
  64. package/dist/types/components/plugins/@antd/items/SpaceRender.d.ts +10 -0
  65. package/dist/types/components/plugins/@antd/items/SwitchRender.d.ts +14 -0
  66. package/dist/types/components/plugins/@antd/items/TableRender.d.ts +12 -0
  67. package/dist/types/components/plugins/@antd/items/TextRender.d.ts +9 -0
  68. package/dist/types/components/plugins/@antd/items/index.d.ts +19 -0
  69. package/dist/types/components/typing.d.ts +80 -0
  70. package/dist/types/components/utils.d.ts +9 -0
  71. package/dist/types/example.d.ts +2 -0
  72. package/dist/types/index.d.ts +1 -0
  73. package/dist/umd/css/bi-sdk.css +1 -0
  74. package/dist/umd/js/bi-sdk.umd.min.js +795 -0
  75. package/dist/umd/js/bi-sdk.umd.min.js.LICENSE.txt +9 -0
  76. package/package.json +52 -0
  77. package/src/components/PageDesigner.tsx +509 -0
  78. package/src/components/context/DesignerContext.tsx +71 -0
  79. package/src/components/context/EnvContext.tsx +42 -0
  80. package/src/components/dnd/DropContainer.tsx +474 -0
  81. package/src/components/example.ts +577 -0
  82. package/src/components/hooks/datasource.ts +23 -0
  83. package/src/components/hooks/useDeepCompareEffect.ts +12 -0
  84. package/src/components/icon/IconFont.tsx +16 -0
  85. package/src/components/index.ts +29 -0
  86. package/src/components/layout/PageCanvas.tsx +145 -0
  87. package/src/components/layout/PageItem.tsx +182 -0
  88. package/src/components/panel/AiPanel.tsx +116 -0
  89. package/src/components/panel/CascadePanel.tsx +163 -0
  90. package/src/components/panel/ChatInput.tsx +550 -0
  91. package/src/components/panel/CodePanel.tsx +48 -0
  92. package/src/components/panel/ComponentPanel.tsx +119 -0
  93. package/src/components/panel/DatasourcePanel.tsx +419 -0
  94. package/src/components/panel/LayerPanel.tsx +238 -0
  95. package/src/components/panel/PaneHeader.tsx +34 -0
  96. package/src/components/panel/PropertiesPanel.tsx +394 -0
  97. package/src/components/panel/ScriptPanel.tsx +175 -0
  98. package/src/components/panel/VariablesPanel.tsx +153 -0
  99. package/src/components/panel/index.ts +9 -0
  100. package/src/components/plugins/@antd/index.ts +445 -0
  101. package/src/components/plugins/@antd/item-props/ButtonProps.tsx +91 -0
  102. package/src/components/plugins/@antd/item-props/CapsuleProps.tsx +102 -0
  103. package/src/components/plugins/@antd/item-props/CardProps.tsx +58 -0
  104. package/src/components/plugins/@antd/item-props/CheckboxProps.tsx +75 -0
  105. package/src/components/plugins/@antd/item-props/ColProps.tsx +43 -0
  106. package/src/components/plugins/@antd/item-props/DatePickerProps.tsx +72 -0
  107. package/src/components/plugins/@antd/item-props/EchartsProps.tsx +35 -0
  108. package/src/components/plugins/@antd/item-props/HtmlProps.tsx +61 -0
  109. package/src/components/plugins/@antd/item-props/ImageProps.tsx +43 -0
  110. package/src/components/plugins/@antd/item-props/InputNumberProps.tsx +18 -0
  111. package/src/components/plugins/@antd/item-props/InputProps.tsx +89 -0
  112. package/src/components/plugins/@antd/item-props/ListProps.tsx +69 -0
  113. package/src/components/plugins/@antd/item-props/PageHeaderProps.tsx +20 -0
  114. package/src/components/plugins/@antd/item-props/RowProps.tsx +21 -0
  115. package/src/components/plugins/@antd/item-props/SelectProps.tsx +136 -0
  116. package/src/components/plugins/@antd/item-props/SpaceProps.tsx +52 -0
  117. package/src/components/plugins/@antd/item-props/SwitchProps.tsx +17 -0
  118. package/src/components/plugins/@antd/item-props/TableProps.tsx +200 -0
  119. package/src/components/plugins/@antd/item-props/TextProps.tsx +41 -0
  120. package/src/components/plugins/@antd/item-props/index.ts +20 -0
  121. package/src/components/plugins/@antd/item-props/types.ts +6 -0
  122. package/src/components/plugins/@antd/items/ButtonRender.tsx +63 -0
  123. package/src/components/plugins/@antd/items/CapsuleRender.tsx +49 -0
  124. package/src/components/plugins/@antd/items/CardRender.tsx +119 -0
  125. package/src/components/plugins/@antd/items/CheckboxRender.tsx +56 -0
  126. package/src/components/plugins/@antd/items/ColRender.tsx +78 -0
  127. package/src/components/plugins/@antd/items/DatePickerRender.tsx +117 -0
  128. package/src/components/plugins/@antd/items/EchartsRender.tsx +98 -0
  129. package/src/components/plugins/@antd/items/HtmlRender.tsx +74 -0
  130. package/src/components/plugins/@antd/items/ImageRender.tsx +37 -0
  131. package/src/components/plugins/@antd/items/InputNumberRender.tsx +57 -0
  132. package/src/components/plugins/@antd/items/InputRender.tsx +75 -0
  133. package/src/components/plugins/@antd/items/ListRender.tsx +227 -0
  134. package/src/components/plugins/@antd/items/PageHeaderRender.tsx +74 -0
  135. package/src/components/plugins/@antd/items/RowRender.tsx +47 -0
  136. package/src/components/plugins/@antd/items/SelectRender.tsx +53 -0
  137. package/src/components/plugins/@antd/items/SpaceRender.tsx +54 -0
  138. package/src/components/plugins/@antd/items/SwitchRender.tsx +52 -0
  139. package/src/components/plugins/@antd/items/TableRender.tsx +99 -0
  140. package/src/components/plugins/@antd/items/TextRender.tsx +25 -0
  141. package/src/components/plugins/@antd/items/index.ts +20 -0
  142. package/src/components/styles.css +12 -0
  143. package/src/components/typing.ts +80 -0
  144. package/src/components/utils.ts +37 -0
  145. package/src/example.tsx +136 -0
  146. package/src/index.tsx +17 -0
@@ -0,0 +1,102 @@
1
+ import React from "react";
2
+ import { Form, Input, Radio, Table, Button, Space, RadioGroupProps } from "antd";
3
+ import type { PropEditorProps } from "./types";
4
+ import { DeleteOutlined } from "@ant-design/icons";
5
+
6
+ export type CapsuleOption = { label: string; value: any };
7
+ export type CapsuleModel = {
8
+ var?: string;
9
+ size?: RadioGroupProps['size'];
10
+ options: CapsuleOption[];
11
+ };
12
+
13
+ export const CapsuleProps: React.FC<PropEditorProps<CapsuleModel>> = ({
14
+ model,
15
+ onChange,
16
+ }) => {
17
+ const trigger = (key: keyof CapsuleModel, value: any) =>
18
+ onChange && onChange({ ...model, [key]: value });
19
+ const setOption = (index: number, key: keyof CapsuleOption, value: any) => {
20
+ const options = [...(model.options || [])];
21
+ options[index] = { ...options[index], [key]: value };
22
+ trigger("options", options);
23
+ };
24
+ const removeOption = (index: number) => {
25
+ const options = [...(model.options || [])];
26
+ options.splice(index, 1);
27
+ trigger("options", options);
28
+ };
29
+ const addOption = () => {
30
+ trigger("options", [...(model.options || []), { label: "", value: "" }]);
31
+ };
32
+ const columns = [
33
+ {
34
+ title: "选项标签",
35
+ dataIndex: "label",
36
+ render: (_: any, r: CapsuleOption, i: number) => (
37
+ <Input
38
+ size="small"
39
+ value={r.label}
40
+ onChange={(e) => setOption(i, "label", e.target.value)}
41
+ />
42
+ ),
43
+ },
44
+ {
45
+ title: "选项值",
46
+ dataIndex: "value",
47
+ render: (_: any, r: CapsuleOption, i: number) => (
48
+ <Input
49
+ size="small"
50
+ value={r.value}
51
+ onChange={(e) => setOption(i, "value", e.target.value)}
52
+ />
53
+ ),
54
+ },
55
+ {
56
+ title: "操作",
57
+ render: (_: any, r: CapsuleOption, i: number) => (
58
+ <Space>
59
+ <Button danger size="small" onClick={() => removeOption(i)}>
60
+ <DeleteOutlined />
61
+ </Button>
62
+ </Space>
63
+ ),
64
+ },
65
+ ];
66
+ return (
67
+ <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
68
+ <Form.Item label="变量名">
69
+ <Input
70
+ size="small"
71
+ value={model.var}
72
+ onChange={(e) => trigger("var", e.target.value)}
73
+ placeholder="请输入变量名"
74
+ />
75
+ </Form.Item>
76
+ <Form.Item label="大小">
77
+ <Radio.Group
78
+ size="small"
79
+ value={model.size}
80
+ onChange={(e) => trigger("size", e.target.value)}
81
+ >
82
+ <Radio.Button value="small">小</Radio.Button>
83
+ <Radio.Button value="middle">中</Radio.Button>
84
+ <Radio.Button value="large">大</Radio.Button>
85
+ </Radio.Group>
86
+ </Form.Item>
87
+ <Form.Item>
88
+ <Table
89
+ size="small"
90
+ dataSource={model.options}
91
+ columns={columns as any}
92
+ pagination={false}
93
+ rowKey={(_, i) => String(i)}
94
+ bordered
95
+ />
96
+ <Button size="small" block onClick={addOption}>
97
+ 添加选项
98
+ </Button>
99
+ </Form.Item>
100
+ </Form>
101
+ );
102
+ };
@@ -0,0 +1,58 @@
1
+ import React from "react";
2
+ import { Form, Input, Radio, Switch, type CardProps as AntCardProps } from "antd";
3
+ import type { PropEditorProps } from "./types";
4
+
5
+ export type CardModel = {
6
+ title?: string;
7
+ shadow?: boolean;
8
+ } & Pick<AntCardProps, "bordered" | "hoverable" | "size">;
9
+
10
+ export const CardProps: React.FC<PropEditorProps<CardModel>> = ({
11
+ model,
12
+ onChange,
13
+ }) => {
14
+ const trigger = (key: keyof CardModel, value: any) =>
15
+ onChange && onChange({ ...model, [key]: value });
16
+ return (
17
+ <Form labelCol={{ span: 12 }} wrapperCol={{ span: 12 }}>
18
+ <Form.Item label="标题">
19
+ <Input
20
+ size="small"
21
+ value={model.title}
22
+ onChange={(e) => trigger("title", e.target.value)}
23
+ />
24
+ </Form.Item>
25
+ <Form.Item label="边框">
26
+ <Switch
27
+ size="small"
28
+ checked={!!model.bordered}
29
+ onChange={(v) => trigger("bordered", v)}
30
+ />
31
+ </Form.Item>
32
+ <Form.Item label="悬停效果">
33
+ <Switch
34
+ size="small"
35
+ checked={!!model.hoverable}
36
+ onChange={(v) => trigger("hoverable", v)}
37
+ />
38
+ </Form.Item>
39
+ <Form.Item label="阴影">
40
+ <Switch
41
+ size="small"
42
+ checked={!!model.shadow}
43
+ onChange={(v) => trigger("shadow", v)}
44
+ />
45
+ </Form.Item>
46
+ <Form.Item label="大小">
47
+ <Radio.Group
48
+ size="small"
49
+ value={model.size}
50
+ onChange={(e) => trigger("size", e.target.value)}
51
+ >
52
+ <Radio.Button value="default">默认</Radio.Button>
53
+ <Radio.Button value="small">小</Radio.Button>
54
+ </Radio.Group>
55
+ </Form.Item>
56
+ </Form>
57
+ );
58
+ };
@@ -0,0 +1,75 @@
1
+ import React from 'react'
2
+ import { Form, Input, Radio, InputNumber, Table, Button, Space, Switch } from 'antd'
3
+ import type { PropEditorProps } from './types'
4
+ import { DeleteOutlined } from '@ant-design/icons';
5
+
6
+ export type CheckboxOption = { label: string; value: any }
7
+ export type CheckboxModel = {
8
+ var?: string
9
+ layout?: 'horizontal' | 'vertical' | 'grid'
10
+ lineNumber?: number
11
+ options: CheckboxOption[]
12
+ }
13
+
14
+ export const CheckboxProps: React.FC<PropEditorProps<CheckboxModel>> = ({ model, onChange }) => {
15
+ const trigger = (key: keyof CheckboxModel, value: any) => onChange && onChange({ ...model, [key]: value })
16
+ const setOption = (index: number, key: keyof CheckboxOption, value: any) => {
17
+ const options = [...(model.options || [])]
18
+ options[index] = { ...options[index], [key]: value }
19
+ trigger('options', options)
20
+ }
21
+ const removeOption = (index: number) => {
22
+ const options = [...(model.options || [])]
23
+ options.splice(index, 1)
24
+ trigger('options', options)
25
+ }
26
+ const addOption = () => {
27
+ trigger('options', [...(model.options || []), { label: '', value: '' }])
28
+ }
29
+ const columns = [
30
+ {
31
+ title: '选项标签',
32
+ dataIndex: 'label',
33
+ render: (_: any, r: CheckboxOption, i: number) => <Input size="small" value={r.label} onChange={e => setOption(i, 'label', e.target.value)} />
34
+ },
35
+ {
36
+ title: '选项值',
37
+ dataIndex: 'value',
38
+ render: (_: any, r: CheckboxOption, i: number) => <Input size="small" value={r.value} onChange={e => setOption(i, 'value', e.target.value)} />
39
+ },
40
+ {
41
+ title: '操作',
42
+ render: (_: any, r: CheckboxOption, i: number) => (
43
+ <Space>
44
+ <Button danger size="small" onClick={() => removeOption(i)}>
45
+ <DeleteOutlined />
46
+ </Button>
47
+ </Space>
48
+ )
49
+ }
50
+ ]
51
+ return (
52
+ <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
53
+ <Form.Item label="变量名">
54
+ <Input size="small" value={model.var} onChange={e => trigger('var', e.target.value)} placeholder="请输入变量名" />
55
+ </Form.Item>
56
+ <Form.Item label="布局">
57
+ <Radio.Group size="small" value={model.layout} onChange={e => trigger('layout', e.target.value)}>
58
+ <Radio.Button value="horizontal">水平</Radio.Button>
59
+ <Radio.Button value="vertical">垂直</Radio.Button>
60
+ <Radio.Button value="grid">网格</Radio.Button>
61
+ </Radio.Group>
62
+ </Form.Item>
63
+ {model.layout === 'grid' && (
64
+ <Form.Item label="网格行数">
65
+ <InputNumber size="small" value={model.lineNumber} onChange={v => trigger('lineNumber', v)} min={1} max={10} />
66
+ </Form.Item>
67
+ )}
68
+ <Form.Item>
69
+ <Table size="small" dataSource={model.options} columns={columns as any} pagination={false} rowKey={(_, i) => String(i)} bordered />
70
+ <Button size="small" block onClick={addOption}>添加选项</Button>
71
+ </Form.Item>
72
+ </Form>
73
+ )
74
+ }
75
+
@@ -0,0 +1,43 @@
1
+ import React from 'react'
2
+ import { Form, InputNumber, Tooltip } from 'antd'
3
+ import type { PropEditorProps } from './types'
4
+ import { InfoCircleOutlined } from '@ant-design/icons';
5
+ import styled from 'styled-components';
6
+
7
+ const HelpIcon = styled(InfoCircleOutlined)`
8
+ vertical-align: middle;
9
+ margin-left: 2px;
10
+ color: var(--ant-color-text-description);
11
+ `
12
+
13
+ export type ColModel = { span?: number; xs?: number; sm?: number; md?: number; lg?: number; xl?: number; xxl?: number }
14
+
15
+ export const ColProps: React.FC<PropEditorProps<ColModel>> = ({ model, onChange }) => {
16
+ const trigger = (key: keyof ColModel, value: any) => onChange && onChange({ ...model, [key]: value })
17
+ return (
18
+ <Form labelCol={{ span: 12 }} wrapperCol={{ span: 12 }}>
19
+ <Form.Item label="默认列数">
20
+ <InputNumber size="small" value={model.span} min={0} max={24} step={4} onChange={v => trigger('span', v || 0)} />
21
+ </Form.Item>
22
+ <Form.Item label={<>xs <Tooltip title="<576px 响应式栅格"><HelpIcon /></Tooltip></>}>
23
+ <InputNumber size="small" value={model.xs} min={0} max={24} step={4} onChange={v => trigger('xs', v || 0)} />
24
+ </Form.Item>
25
+ <Form.Item label={<>sm <Tooltip title="≥576px 响应式栅格"><HelpIcon /></Tooltip></>}>
26
+ <InputNumber size="small" value={model.sm} min={0} max={24} step={4} onChange={v => trigger('sm', v || 0)} />
27
+ </Form.Item>
28
+ <Form.Item label={<>md <Tooltip title="≥768px 响应式栅格"><HelpIcon /></Tooltip></>}>
29
+ <InputNumber size="small" value={model.md} min={0} max={24} step={4} onChange={v => trigger('md', v || 0)} />
30
+ </Form.Item>
31
+ <Form.Item label={<>lg <Tooltip title="≥992px 响应式栅格"><HelpIcon /></Tooltip></>}>
32
+ <InputNumber size="small" value={model.lg} min={0} max={24} step={4} onChange={v => trigger('lg', v || 0)} />
33
+ </Form.Item>
34
+ <Form.Item label={<>xl <Tooltip title="≥1200px 响应式栅格"><HelpIcon /></Tooltip></>}>
35
+ <InputNumber size="small" value={model.xl} min={0} max={24} step={4} onChange={v => trigger('xl', v || 0)} />
36
+ </Form.Item>
37
+ <Form.Item label={<>xxl <Tooltip title="≥1600px 响应式栅格"><HelpIcon /></Tooltip></>}>
38
+ <InputNumber size="small" value={model.xxl} min={0} max={24} step={4} onChange={v => trigger('xxl', v || 0)} />
39
+ </Form.Item>
40
+ </Form>
41
+ )
42
+ }
43
+
@@ -0,0 +1,72 @@
1
+ import React from "react";
2
+ import {
3
+ Form,
4
+ Input,
5
+ Radio,
6
+ Switch,
7
+ type DatePickerProps as AntDatePickerProps,
8
+ } from "antd";
9
+ import type { PropEditorProps } from "./types";
10
+
11
+ export type DatePickerModel = {
12
+ var?: string;
13
+ type?: "date" | "time" | "month" | "year" | "range";
14
+ } & Pick<AntDatePickerProps, "size" | "allowClear" | "showTime">;
15
+
16
+ export const DatePickerProps: React.FC<PropEditorProps<DatePickerModel>> = ({
17
+ model,
18
+ onChange,
19
+ }) => {
20
+ const trigger = (key: keyof DatePickerModel, value: any) =>
21
+ onChange && onChange({ ...model, [key]: value });
22
+ return (
23
+ <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
24
+ <Form.Item label="变量名">
25
+ <Input
26
+ size="small"
27
+ value={model.var}
28
+ onChange={(e) => trigger("var", e.target.value)}
29
+ placeholder="请输入变量名"
30
+ />
31
+ </Form.Item>
32
+ <Form.Item label="类型">
33
+ <Radio.Group
34
+ size="small"
35
+ value={model.type}
36
+ onChange={(e) => trigger("type", e.target.value)}
37
+ >
38
+ <Radio.Button value="date">日期</Radio.Button>
39
+ <Radio.Button value="time">时间</Radio.Button>
40
+ <Radio.Button value="month">月份</Radio.Button>
41
+ <Radio.Button value="year">年份</Radio.Button>
42
+ <Radio.Button value="range">日期范围</Radio.Button>
43
+ </Radio.Group>
44
+ </Form.Item>
45
+ <Form.Item label="大小">
46
+ <Radio.Group
47
+ size="small"
48
+ value={model.size}
49
+ onChange={(e) => trigger("size", e.target.value)}
50
+ >
51
+ <Radio.Button value="small">小</Radio.Button>
52
+ <Radio.Button value="middle">中</Radio.Button>
53
+ <Radio.Button value="large">大</Radio.Button>
54
+ </Radio.Group>
55
+ </Form.Item>
56
+ <Form.Item label="清除图标">
57
+ <Switch
58
+ size="small"
59
+ checked={!!model.allowClear}
60
+ onChange={(v) => trigger("allowClear", v)}
61
+ />
62
+ </Form.Item>
63
+ <Form.Item label="显示时间">
64
+ <Switch
65
+ size="small"
66
+ checked={!!model.showTime}
67
+ onChange={(v) => trigger("showTime", v)}
68
+ />
69
+ </Form.Item>
70
+ </Form>
71
+ );
72
+ };
@@ -0,0 +1,35 @@
1
+ import React, { useRef } from 'react'
2
+ import { Form } from 'antd'
3
+ import Editor from '@monaco-editor/react'
4
+ import type { PropEditorProps } from './types'
5
+
6
+ export type EchartsModel = { script: string }
7
+
8
+ export const EchartsProps: React.FC<PropEditorProps<EchartsModel>> = ({ model, onChange }) => {
9
+ const ref = useRef<any>(null)
10
+ const setScript = (v?: string) => onChange && onChange({ ...model, script: v || '' })
11
+ const format = () => {
12
+ // Monaco-react does not expose format directly; relying on editor action
13
+ const editor = (ref.current as any)?.editor
14
+ editor?.getAction('editor.action.formatDocument')?.run()
15
+ }
16
+ return (
17
+ <Form labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
18
+ <Form.Item label={<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>Echarts 渲染脚本 <a onClick={format}>格式化</a></div>}>
19
+ <div style={{ border: '1px solid #d9d9d9', borderRadius: 4, textAlign: 'left' }}>
20
+ <div style={{ color: '#0000ff', fontSize: 14, padding: '0 50px' }}>function getOptions(data) {'{'} </div>
21
+ <Editor
22
+ onMount={(editor) => { (ref.current as any) = { editor } }}
23
+ height="400px"
24
+ defaultLanguage="javascript"
25
+ value={model.script}
26
+ onChange={(v) => setScript(v || '')}
27
+ options={{ minimap: { enabled: false }, scrollBeyondLastLine: false, tabSize: 2 }}
28
+ />
29
+ <div style={{ color: '#0000ff', fontSize: 14, padding: '0 50px' }}>{'}'}</div>
30
+ </div>
31
+ </Form.Item>
32
+ </Form>
33
+ )
34
+ }
35
+
@@ -0,0 +1,61 @@
1
+ import React, { useRef } from "react";
2
+ import { Form } from "antd";
3
+ import Editor from "@monaco-editor/react";
4
+ import type { PropEditorProps } from "./types";
5
+
6
+ export type HtmlModel = { template: string };
7
+
8
+ export const HtmlProps: React.FC<PropEditorProps<HtmlModel>> = ({
9
+ model,
10
+ onChange,
11
+ }) => {
12
+ const ref = useRef<any>(null);
13
+ const setTemplate = (v?: string) =>
14
+ onChange && onChange({ ...model, template: v || "" });
15
+ const format = () => {
16
+ const editor = (ref.current as any)?.editor;
17
+ editor?.getAction("editor.action.formatDocument")?.run();
18
+ };
19
+ return (
20
+ <div>
21
+ <Form layout="vertical">
22
+ <Form.Item
23
+ label={
24
+ <div
25
+ style={{
26
+ display: "flex",
27
+ alignItems: "center",
28
+ justifyContent: "space-between",
29
+ }}
30
+ >
31
+ 模板 <a onClick={format}>格式化</a>
32
+ </div>
33
+ }
34
+ >
35
+ <div
36
+ style={{
37
+ border: "1px solid #d9d9d9",
38
+ borderRadius: 4,
39
+ textAlign: "left",
40
+ }}
41
+ >
42
+ <Editor
43
+ onMount={(editor) => {
44
+ (ref.current as any) = { editor };
45
+ }}
46
+ height="300px"
47
+ defaultLanguage="html"
48
+ value={model.template}
49
+ onChange={(v) => setTemplate(v || "")}
50
+ options={{
51
+ minimap: { enabled: false },
52
+ scrollBeyondLastLine: false,
53
+ tabSize: 2,
54
+ }}
55
+ />
56
+ </div>
57
+ </Form.Item>
58
+ </Form>
59
+ </div>
60
+ );
61
+ };
@@ -0,0 +1,43 @@
1
+ import React from 'react'
2
+ import { Form, Input, Upload, Button, message } from 'antd'
3
+ import { UploadOutlined } from '@ant-design/icons'
4
+ import type { PropEditorProps } from './types'
5
+
6
+ export type ImageModel = { src?: string; alt?: string; href?: string; width?: string; height?: string }
7
+
8
+ export const ImageProps: React.FC<PropEditorProps<ImageModel>> = ({ model, onChange }) => {
9
+ const trigger = (key: keyof ImageModel, value: any) => onChange && onChange({ ...model, [key]: value })
10
+ const beforeUpload = (file: File) => {
11
+ const isImage = file.type.startsWith('image/')
12
+ if (!isImage) message.error('上传封面只能是图片文件')
13
+ return isImage
14
+ }
15
+ const handleUpload = (info: any) => {
16
+ if (info.file.status === 'done') {
17
+ trigger('src', info.file.response?.data)
18
+ message.success('上传成功')
19
+ } else if (info.file.status === 'error') {
20
+ message.error('上传失败')
21
+ }
22
+ }
23
+ const headers = { Authorization: `Bearer ${localStorage.getItem('ASKDATA_TOKEN') || ''}` }
24
+ return (
25
+ <Form labelCol={{ span: 24 }} wrapperCol={{ span: 24 }}>
26
+ <Form.Item label={
27
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
28
+ 图片URL
29
+ <Upload name="file" multiple={false} accept=".png,.jpg,.jpeg" headers={headers} action="/api/datareport/upload" showUploadList={false} beforeUpload={beforeUpload} onChange={handleUpload}>
30
+ <Button size="small" type="link" icon={<UploadOutlined />} />
31
+ </Upload>
32
+ </div>
33
+ }>
34
+ <Input size="small" value={model.src} onChange={e => trigger('src', e.target.value)} />
35
+ </Form.Item>
36
+ <Form.Item label="图片替代文本"><Input size="small" value={model.alt} onChange={e => trigger('alt', e.target.value)} /></Form.Item>
37
+ <Form.Item label="图片链接"><Input size="small" value={model.href} onChange={e => trigger('href', e.target.value)} /></Form.Item>
38
+ <Form.Item label="图片宽度"><Input size="small" value={model.width} onChange={e => trigger('width', e.target.value)} /></Form.Item>
39
+ <Form.Item label="图片高度"><Input size="small" value={model.height} onChange={e => trigger('height', e.target.value)} /></Form.Item>
40
+ </Form>
41
+ )
42
+ }
43
+
@@ -0,0 +1,18 @@
1
+ import React from 'react'
2
+ import { Form, InputNumber, Input } from 'antd'
3
+ import type { PropEditorProps } from './types'
4
+
5
+ export type InputNumberModel = { var?: string; min?: number; max?: number; step?: number }
6
+
7
+ export const InputNumberProps: React.FC<PropEditorProps<InputNumberModel>> = ({ model, onChange }) => {
8
+ const trigger = (key: keyof InputNumberModel, value: any) => onChange && onChange({ ...model, [key]: value })
9
+ return (
10
+ <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
11
+ <Form.Item label="变量名"><Input size="small" value={model.var} onChange={e => trigger('var', e.target.value)} /></Form.Item>
12
+ <Form.Item label="最小值"><InputNumber size="small" value={model.min} onChange={v => trigger('min', v)} /></Form.Item>
13
+ <Form.Item label="最大值"><InputNumber size="small" value={model.max} onChange={v => trigger('max', v)} /></Form.Item>
14
+ <Form.Item label="步长"><InputNumber size="small" value={model.step} onChange={v => trigger('step', v)} /></Form.Item>
15
+ </Form>
16
+ )
17
+ }
18
+
@@ -0,0 +1,89 @@
1
+ import React from "react";
2
+ import {
3
+ Form,
4
+ Input,
5
+ Radio,
6
+ Switch,
7
+ type InputProps as AntInputProps,
8
+ } from "antd";
9
+ import type { PropEditorProps } from "./types";
10
+
11
+ export type InputModel = {
12
+ search?: boolean;
13
+ var?: string;
14
+ prefix?: string;
15
+ suffix?: string;
16
+ } & Pick<AntInputProps, "placeholder" | "size" | "allowClear">;
17
+
18
+ export const InputProps: React.FC<PropEditorProps<InputModel>> = ({
19
+ model,
20
+ onChange,
21
+ }) => {
22
+ const trigger = (key: keyof InputModel, value: any) =>
23
+ onChange && onChange({ ...model, [key]: value });
24
+ return (
25
+ <Form labelCol={{ span: 6 }} wrapperCol={{ span: 18 }}>
26
+ <Form.Item label="搜索框">
27
+ <Switch
28
+ size="small"
29
+ checked={!!model.search}
30
+ onChange={(v) => trigger("search", v)}
31
+ />
32
+ </Form.Item>
33
+ <Form.Item label="变量名">
34
+ <Input
35
+ size="small"
36
+ value={model.var}
37
+ onChange={(e) => trigger("var", e.target.value)}
38
+ placeholder="请输入变量名"
39
+ />
40
+ </Form.Item>
41
+ <Form.Item label="占位符">
42
+ <Input
43
+ size="small"
44
+ value={model.placeholder}
45
+ onChange={(e) => trigger("placeholder", e.target.value)}
46
+ placeholder="请输入占位符"
47
+ />
48
+ </Form.Item>
49
+ {!model.search && (
50
+ <>
51
+ <Form.Item label="前缀">
52
+ <Input
53
+ size="small"
54
+ value={model.prefix}
55
+ onChange={(e) => trigger("prefix", e.target.value)}
56
+ placeholder="请输入前缀"
57
+ />
58
+ </Form.Item>
59
+ <Form.Item label="后缀">
60
+ <Input
61
+ size="small"
62
+ value={model.suffix}
63
+ onChange={(e) => trigger("suffix", e.target.value)}
64
+ placeholder="请输入后缀"
65
+ />
66
+ </Form.Item>
67
+ </>
68
+ )}
69
+ <Form.Item label="大小">
70
+ <Radio.Group
71
+ size="small"
72
+ value={model.size}
73
+ onChange={(e) => trigger("size", e.target.value)}
74
+ >
75
+ <Radio.Button value="small">小</Radio.Button>
76
+ <Radio.Button value="middle">中</Radio.Button>
77
+ <Radio.Button value="large">大</Radio.Button>
78
+ </Radio.Group>
79
+ </Form.Item>
80
+ <Form.Item label="清除图标">
81
+ <Switch
82
+ size="small"
83
+ checked={!!model.allowClear}
84
+ onChange={(v) => trigger("allowClear", v)}
85
+ />
86
+ </Form.Item>
87
+ </Form>
88
+ );
89
+ };
@@ -0,0 +1,69 @@
1
+ import React, { useEffect } from 'react'
2
+ import { Form, Radio, Switch, InputNumber } from 'antd'
3
+ import type { PropEditorProps } from './types'
4
+
5
+ export type ListModel = {
6
+ size?: 'default' | 'small' | 'large';
7
+ itemLayout?: 'horizontal' | 'vertical';
8
+ bordered?: boolean;
9
+ split?: boolean;
10
+ pageSize?: number;
11
+ }
12
+
13
+ export const ListProps: React.FC<PropEditorProps<ListModel>> = ({ model, onChange }) => {
14
+ const [form] = Form.useForm();
15
+
16
+ // 当外部 model 更新时同步到 form
17
+ useEffect(() => {
18
+ form.setFieldsValue({
19
+ size: model.size || 'default',
20
+ itemLayout: model.itemLayout || 'horizontal',
21
+ bordered: model.bordered ?? false,
22
+ split: model.split ?? true,
23
+ pageSize: model.pageSize || 10,
24
+ });
25
+ }, [model, form]);
26
+
27
+ const handleValuesChange = (changedValues: any) => {
28
+ onChange?.({
29
+ ...model,
30
+ ...changedValues,
31
+ });
32
+ };
33
+
34
+ return (
35
+ <Form
36
+ form={form}
37
+ labelCol={{ span: 12 }}
38
+ wrapperCol={{ span: 12 }}
39
+ onValuesChange={handleValuesChange}
40
+ >
41
+ <Form.Item label="大小" name="size">
42
+ <Radio.Group size="small" buttonStyle="solid">
43
+ <Radio.Button value="default">默认</Radio.Button>
44
+ <Radio.Button value="small">小</Radio.Button>
45
+ </Radio.Group>
46
+ </Form.Item>
47
+
48
+ <Form.Item label="布局" name="itemLayout">
49
+ <Radio.Group size="small" buttonStyle="solid">
50
+ <Radio.Button value="horizontal">水平</Radio.Button>
51
+ <Radio.Button value="vertical">垂直</Radio.Button>
52
+ </Radio.Group>
53
+ </Form.Item>
54
+
55
+ <Form.Item label="边框" name="bordered" valuePropName="checked">
56
+ <Switch size="small" />
57
+ </Form.Item>
58
+
59
+ <Form.Item label="分割线" name="split" valuePropName="checked">
60
+ <Switch size="small" />
61
+ </Form.Item>
62
+
63
+ <Form.Item label="分页大小" name="pageSize">
64
+ <InputNumber size="small" />
65
+ </Form.Item>
66
+ </Form>
67
+ )
68
+ }
69
+