@baishuyun/chat-sdk 0.0.8 → 0.0.10

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 (78) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +16 -0
  3. package/dist/chat-sdk.js +20855 -19610
  4. package/dist/chat-sdk.js.map +1 -1
  5. package/dist/chat-sdk.umd.cjs +188 -188
  6. package/dist/chat-sdk.umd.cjs.map +1 -1
  7. package/dist/index.css +1 -1
  8. package/package.json +4 -4
  9. package/src/chat.tsx +16 -6
  10. package/src/components/biz-comp/FakeBotMsg.tsx +6 -1
  11. package/src/components/biz-comp/chat-client.tsx +25 -5
  12. package/src/components/biz-comp/conversation.tsx +24 -45
  13. package/src/components/biz-comp/dash-widget-icon.tsx +17 -0
  14. package/src/components/biz-comp/field-icon.tsx +7 -2
  15. package/src/components/biz-comp/highlight-msg.tsx +3 -0
  16. package/src/components/biz-comp/markdown-part.tsx +42 -18
  17. package/src/components/biz-comp/message-content.tsx +1 -1
  18. package/src/components/biz-comp/messages.tsx +5 -4
  19. package/src/components/biz-comp/multi-modal-input/clear-btn.tsx +1 -0
  20. package/src/components/biz-comp/multi-modal-input/index.tsx +7 -3
  21. package/src/components/biz-comp/preview-message-wrapper.tsx +5 -1
  22. package/src/components/biz-comp/suggestions.tsx +8 -6
  23. package/src/components/bs-ui/border-color-animation.tsx +4 -1
  24. package/src/components/bs-ui/bs-icons.tsx +165 -0
  25. package/src/components/bs-ui/card-field.tsx +23 -0
  26. package/src/components/bs-ui/card.tsx +8 -10
  27. package/src/components/bs-ui/chat-area-header.tsx +14 -3
  28. package/src/components/bs-ui/collapsible-txt-msg.tsx +31 -18
  29. package/src/components/bs-ui/fields-generating-indicator.tsx +76 -31
  30. package/src/components/bs-ui/fields-previewer.tsx +26 -3
  31. package/src/components/bs-ui/form-info-editor.tsx +21 -7
  32. package/src/components/bs-ui/formula-tag.tsx +32 -0
  33. package/src/components/bs-ui/icon-btn.tsx +7 -2
  34. package/src/components/bs-ui/primary-confirm-btn.tsx +14 -7
  35. package/src/components/bs-ui/primary-entry-btn.tsx +14 -4
  36. package/src/components/bs-ui/scroll-to-bottom-btn.tsx +28 -0
  37. package/src/components/bs-ui/split-line.tsx +9 -0
  38. package/src/components/web-comp/fields-previewer-web-component.ts +1 -1
  39. package/src/const/index.ts +26 -2
  40. package/src/hooks/use-chat-preference.ts +9 -0
  41. package/src/hooks/use-draggable.ts +154 -0
  42. package/src/hooks/use-frame-mode.ts +1 -0
  43. package/src/hooks/use-msg-status-broadcast.ts +10 -0
  44. package/src/hooks/use-scroll-to-bottom.ts +127 -0
  45. package/src/index.tsx +2 -4
  46. package/src/lib/utils.ts +22 -0
  47. package/src/plugins/form-filling-plugin/index.ts +1 -1
  48. package/src/plugins/mcp-form-builder-plugin/components/create-form-confirm.tsx +1 -1
  49. package/src/plugins/mcp-form-builder-plugin/index.ts +6 -0
  50. package/src/plugins/report-query-plugin/components/avatar.tsx +12 -0
  51. package/src/plugins/report-query-plugin/components/query-entry-btn.tsx +17 -0
  52. package/src/plugins/report-query-plugin/components/query-msg-part.tsx +57 -0
  53. package/src/plugins/report-query-plugin/components/query-opening-lines.tsx +30 -0
  54. package/src/plugins/report-query-plugin/components/result-cards/DataTableCard.tsx +68 -0
  55. package/src/plugins/report-query-plugin/components/result-cards/DataTableFields.tsx +46 -0
  56. package/src/plugins/report-query-plugin/components/result-cards/FilterCondition.tsx +374 -0
  57. package/src/plugins/report-query-plugin/components/result-cards/FormulaField.tsx +24 -0
  58. package/src/plugins/report-query-plugin/const.ts +1 -0
  59. package/src/plugins/report-query-plugin/index.ts +100 -0
  60. package/src/plugins/report-query-plugin/types.ts +16 -0
  61. package/src/plugins/report-query-plugin/utils/field-enhance.ts +39 -0
  62. package/src/plugins/report-query-plugin/utils/get-field-group.ts +691 -0
  63. package/src/plugins/report-query-plugin/utils/get-field-icon.ts +26 -0
  64. package/src/plugins/report-query-plugin/utils/get-group-rule.ts +21 -0
  65. package/src/plugins/report-query-plugin/utils.tsx +379 -0
  66. package/src/sdk.impl.tsx +7 -0
  67. package/src/store/index.ts +2 -1
  68. package/src/stories/CardField.stories.tsx +87 -0
  69. package/src/stories/DashWidgetIcon.stories.tsx +132 -0
  70. package/src/stories/FormulaField.stories.tsx +145 -0
  71. package/src/stories/FormulaTag.stories.tsx +68 -0
  72. package/src/stories/IconBtn.stories.tsx +14 -8
  73. package/src/stories/{PrimaryConfirmBtn.stories.ts → PrimaryConfirmBtn.stories.tsx} +16 -0
  74. package/src/stories/ScrollToBottom.stories.tsx +24 -0
  75. package/src/stories/SplitLine.stories.tsx +40 -0
  76. package/src/stories/fields-generating.stories.tsx +19 -0
  77. package/src/style.css +5 -2
  78. package/tailwind.config.js +19 -20
@@ -0,0 +1,21 @@
1
+ import { FieldType, IDashWidgetType } from '@baishuyun/types';
2
+
3
+ export type GroupRule = 'year_month' | 'province_city' | undefined;
4
+
5
+ export function getGroupRule(fieldType: FieldType, widgetType: IDashWidgetType): GroupRule {
6
+ switch (fieldType) {
7
+ case 'datetime':
8
+ return 'year_month';
9
+
10
+ case 'address':
11
+ case 'location':
12
+ // 地图组件中地址/位置字段不需要额外分组规则
13
+ if (widgetType === 'map_chart') {
14
+ return undefined;
15
+ }
16
+ return 'province_city';
17
+
18
+ default:
19
+ return undefined;
20
+ }
21
+ }
@@ -0,0 +1,379 @@
1
+ import {
2
+ IQueryResult,
3
+ IQueryResultPreviewerProps,
4
+ IQueryResultCreateParams,
5
+ IDashComponent,
6
+ IDashComponentField,
7
+ IDashComponentFilterCond,
8
+ IFilterField,
9
+ IQueryResultField,
10
+ FieldType,
11
+ } from '@baishuyun/types';
12
+ import { XFieldEnhance, MetricEnhance } from './utils/field-enhance';
13
+ import { getFieldIcon } from './utils/get-field-icon';
14
+
15
+ /** 生成唯一的 widget ID */
16
+ const generateWidgetId = (): string => {
17
+ return `_widget_${Date.now()}`;
18
+ };
19
+
20
+ /** 将 IQueryResultField 转换为 IDashComponentField */
21
+ const convertField = (
22
+ field: IQueryResultField,
23
+ formId: string,
24
+ index: number
25
+ ): IDashComponentField => {
26
+ return {
27
+ id: field.id ?? index,
28
+ name: field.name,
29
+ text: field.title,
30
+ type: field.type,
31
+ title: field.title,
32
+ form: formId,
33
+ isEditable: field.isEditable ?? false,
34
+ icon: getFieldIcon(field.type as FieldType),
35
+ group: field.group || 'dimension',
36
+ formula: '',
37
+ tag: `f_${Date.now() + index}`,
38
+ };
39
+ };
40
+
41
+ /** 将 IFilterField 转换为 IDashComponentFilterCond */
42
+ const convertFilterField = (filter: IFilterField, formId: string): IDashComponentFilterCond => {
43
+ return {
44
+ title: filter.title,
45
+ name: filter.name,
46
+ type: filter.type,
47
+ entryId: formId,
48
+ form: formId,
49
+ field: filter.name,
50
+ method: filter.method,
51
+ value: filter.value ?? [],
52
+ hasEmpty: filter.method !== 'not_empty',
53
+ fieldvalueMode: 'widget',
54
+ fieldvalueName: '',
55
+ };
56
+ };
57
+
58
+ const createLabelField = (formId: string): IDashComponentField => {
59
+ return {
60
+ name: 'label',
61
+ text: '标题',
62
+ type: 'textarea',
63
+ title: '标题',
64
+ form: formId,
65
+ isEditable: true,
66
+ icon: getFieldIcon('textarea'),
67
+ group: 'dimension',
68
+ formula: '',
69
+ tag: `f_${Date.now()}`,
70
+ };
71
+ };
72
+
73
+ /** 创建默认样式配置 */
74
+ const createDefaultStyles = () => ({
75
+ theme: {
76
+ name: 'preset_style_light_1',
77
+ highLightColor: '#0265FF',
78
+ palette: 'preset_1',
79
+ gradation: 'preset_map_1',
80
+ },
81
+ background: {
82
+ type: 'color',
83
+ color: '#F4F6F9',
84
+ },
85
+ widget: {
86
+ theme: {
87
+ color: '#E9E9E9',
88
+ icon: 1,
89
+ cardName: 'preset_metric_1',
90
+ },
91
+ background: {
92
+ type: 'color',
93
+ color: '#FFFFFF',
94
+ },
95
+ fontSetting: {
96
+ titleColor: '#1F2D3D',
97
+ headColor: '#5E6D82',
98
+ textColor: '#1F2D3D',
99
+ textAlign: 'default',
100
+ },
101
+ },
102
+ });
103
+
104
+ /** 创建默认的 attrList 配置 */
105
+ const createDefaultAttrList = () => ({
106
+ title: {
107
+ show: false,
108
+ text: '标题内容',
109
+ textStyle: {
110
+ color: '#333333',
111
+ fontStyle: 'normal',
112
+ fontSize: 16,
113
+ fontWeight: 'normal',
114
+ },
115
+ left: 'left',
116
+ borderColor: 'transparent',
117
+ borderWidth: 2,
118
+ padding: 5,
119
+ onBorderColor: false,
120
+ borderRadius: 0,
121
+ backgroundColor: 'transparent',
122
+ },
123
+ orient: 'vertical',
124
+ legend: {
125
+ textStyle: {
126
+ fontStyle: 'normal',
127
+ fontSize: 10,
128
+ fontWeight: 'normal',
129
+ },
130
+ itemWidth: 12,
131
+ itemHeight: 12,
132
+ position: 'bottom',
133
+ type: 'plain',
134
+ padding: 10,
135
+ },
136
+ itemStyle: {
137
+ opacity: 0.7,
138
+ borderWidth: 2,
139
+ },
140
+ tooltip: {
141
+ show: true,
142
+ triggerOn: 'mousemove',
143
+ position: '0',
144
+ seriesName: '',
145
+ formatter: '1',
146
+ opacity: 1,
147
+ textStyle: {
148
+ color: '#FFFFFF',
149
+ fontStyle: 'normal',
150
+ fontSize: 14,
151
+ fontWeight: 'normal',
152
+ },
153
+ },
154
+ label: {
155
+ fontStyle: 'normal',
156
+ fontWeight: 'normal',
157
+ fontSize: 10,
158
+ position: 'top',
159
+ formatter: '1',
160
+ },
161
+ });
162
+
163
+ /** 将 IQueryResult 转换为 IQueryResultPreviewerProps */
164
+ export const queryResult2previewerProps = (
165
+ result: IQueryResult,
166
+ entryId: string
167
+ ): IQueryResultPreviewerProps => {
168
+ const appId = result.appID || '';
169
+ const widgetId = generateWidgetId();
170
+ const formId = result.formIds?.[0] || '';
171
+ const componentName = result.title || '未命名数据表';
172
+
173
+ // 转换字段
174
+ const fields: IDashComponentField[] =
175
+ result.fields?.map((field, index) => convertField(field, formId, index)) || [];
176
+
177
+ // 转换过滤条件
178
+ const filterConds: IDashComponentFilterCond[] =
179
+ result.filter?.conds?.map((cond) => convertFilterField(cond, formId)) || [];
180
+ const filterRel = result.filter?.rel || 'and';
181
+ // 创建组件配置
182
+ const component: IDashComponent = {
183
+ title: componentName,
184
+ forms: result.formIds || [],
185
+
186
+ hasExport: false,
187
+ widgetId,
188
+ palette: 'default',
189
+ chart_label: { enable: true },
190
+ width: 30,
191
+ height: 20,
192
+ posX: 0,
193
+ posY: 0,
194
+ formulas: result.formulas || [],
195
+ widgetNameAlias: widgetId,
196
+ permission: 'all',
197
+ triggers: [],
198
+ defaultSort: [],
199
+ reportAuth: [],
200
+ enableRowEdit: false,
201
+ attrList: createDefaultAttrList(),
202
+ batchmenu: { enable: true, set: [] },
203
+ itemSeleable: true,
204
+ itemMarekerable: true,
205
+ mapScale: 14,
206
+ itemDataable: true,
207
+ scopefields: [],
208
+ menu: { enable: true, set: [] },
209
+ onSwitchButton: false,
210
+ BtnName: '点击操作',
211
+ FunctionBtn: 'itemManualData',
212
+ dryRun: true,
213
+ DataMode: false,
214
+ mapfields: [],
215
+ tFields: [],
216
+ bgColorFilter: [],
217
+ cardConfig: { widget_id: '{}' },
218
+ cardConfigFields: [],
219
+ selectFields: [],
220
+ mapFields: [],
221
+ selectArg: {},
222
+ thresholds: [],
223
+ guideline: [],
224
+ treeFields: {},
225
+ batchmenuAuth: {},
226
+
227
+ ...result,
228
+
229
+ xFields: (result.xFields || []).map((x, index) => {
230
+ return XFieldEnhance(x, result.type, index);
231
+ }),
232
+
233
+ yFields: (result.yFields || []).map((y, index) => {
234
+ return XFieldEnhance(y, result.type, index);
235
+ }),
236
+
237
+ metrics: (result.metrics || []).map((m, index) => {
238
+ return MetricEnhance(m, result.type, index);
239
+ }),
240
+
241
+ fields,
242
+ filter: {
243
+ cond: filterConds,
244
+ rel: filterRel,
245
+ },
246
+ };
247
+
248
+ console.log(component, result.formIds);
249
+
250
+ const components: Record<string, IDashComponent> = {
251
+ [widgetId]: component,
252
+ };
253
+
254
+ const styles = createDefaultStyles();
255
+
256
+ // 创建 entry 配置(用于 allComponentDash)
257
+ const entry = {
258
+ appId,
259
+ entryId,
260
+ hasLazyLoad: true,
261
+ styles,
262
+ autoLoad: true,
263
+ rel: filterRel,
264
+ cacheFilter: 0,
265
+ isMobileFilteringButton: 0 as const,
266
+ showFilter: 0 as const,
267
+ components,
268
+ mode: 'preview' as const,
269
+ dryRun: true,
270
+ name: result.title || '未命名分析报表',
271
+ };
272
+
273
+ return {
274
+ appId,
275
+ entryId,
276
+ hasLazyLoad: true,
277
+ styles,
278
+ autoLoad: true,
279
+ rel: 'and',
280
+ cacheFilter: 0,
281
+ isMobileFilteringButton: 1,
282
+ showFilter: 0,
283
+ components,
284
+ mode: 'preview',
285
+ showType: 'popup',
286
+ name: result.title || '未命名分析报表',
287
+ allComponentDash: {
288
+ entry,
289
+ },
290
+ };
291
+ };
292
+
293
+ export const queryResult2createParams = (
294
+ result: IQueryResult,
295
+ entryId: string
296
+ ): IQueryResultCreateParams => {
297
+ const appId = result.appID || '';
298
+ const widgetId = generateWidgetId();
299
+ const formId = result.formIds?.[0] || '';
300
+ const componentName = result.title || '未命名数据表';
301
+
302
+ const labelField = createLabelField(formId);
303
+ const fields: IDashComponentField[] = [labelField].concat(
304
+ result.fields?.map((field, index) => convertField(field, formId, index)) || []
305
+ );
306
+
307
+ const filterConds: IDashComponentFilterCond[] =
308
+ result.filter?.conds?.map((cond) => convertFilterField(cond, formId)) || [];
309
+ const filterRel = result.filter?.rel || 'and';
310
+
311
+ const widget: IDashComponent = {
312
+ title: componentName,
313
+ forms: result.formIds || [],
314
+ type: result.type,
315
+ xFields: (result.xFields || []).map((x, index) => {
316
+ return XFieldEnhance(x, result.type, index);
317
+ }),
318
+
319
+ yFields: (result.yFields || []).map((y, index) => {
320
+ return XFieldEnhance(y, result.type, index);
321
+ }),
322
+
323
+ metrics: (result.metrics || []).map((m, index) => {
324
+ return MetricEnhance(m, result.type, index);
325
+ }),
326
+
327
+ hasExport: false,
328
+ widgetId,
329
+ palette: 'default',
330
+ chart_label: { enable: true },
331
+ width: 30,
332
+ height: 20,
333
+ posX: 0,
334
+ posY: 0,
335
+ fields,
336
+ formulas: result.formulas || [],
337
+ widgetNameAlias: widgetId,
338
+ permission: 'all',
339
+ triggers: [],
340
+ filter: {
341
+ cond: filterConds,
342
+ rel: filterRel,
343
+ },
344
+ defaultSort: [],
345
+ reportAuth: [],
346
+ enableRowEdit: false,
347
+ attrList: createDefaultAttrList(),
348
+ batchmenu: { enable: true, set: [] },
349
+ itemSeleable: true,
350
+ itemMarekerable: true,
351
+ mapScale: 14,
352
+ itemDataable: true,
353
+ scopefields: [],
354
+ menu: { enable: true, set: [] },
355
+ onSwitchButton: false,
356
+ BtnName: '点击操作',
357
+ FunctionBtn: 'itemManualData',
358
+ DataMode: false,
359
+ mapfields: [],
360
+ tFields: [],
361
+ bgColorFilter: [],
362
+ cardConfig: { widget_id: {} },
363
+ cardConfigFields: [],
364
+ selectFields: [],
365
+ mapFields: [],
366
+ selectArg: {},
367
+ thresholds: [],
368
+ guideline: [],
369
+ treeFields: {},
370
+ };
371
+
372
+ return {
373
+ appId,
374
+ entryId,
375
+ widget,
376
+ datahelpers_remove: [],
377
+ datahelpers: {},
378
+ };
379
+ };
package/src/sdk.impl.tsx CHANGED
@@ -117,6 +117,13 @@ export class ChatSDK implements IChatSDK {
117
117
  };
118
118
  }
119
119
 
120
+ public setUserId(userId: string) {
121
+ this.options.chatApiHeaders = {
122
+ ...this.options.chatApiHeaders,
123
+ 'X-User-Id': userId,
124
+ };
125
+ }
126
+
120
127
  public getChatStatus() {
121
128
  return this.Store.getState().chatStatus;
122
129
  }
@@ -104,8 +104,9 @@ export const setupStoreSubscriptions = (store: ChatStore, option: IChatSDKOption
104
104
  (status) => {
105
105
  const eventBus = store.getState().eventBus;
106
106
  const visible = status !== 'hide';
107
- eventBus.emit('chat-area-visibility-change', { visible });
108
107
  option.onChatStatusChange?.(status);
108
+ // @deprecated, will be removed in future versions
109
+ eventBus.emit('chat-area-visibility-change', { visible, status });
109
110
  console.log('chat status changed:', status);
110
111
  }
111
112
  );
@@ -0,0 +1,87 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+
3
+ import { CardField } from '@/components/bs-ui/card-field';
4
+
5
+ const meta: Meta<typeof CardField> = {
6
+ title: 'Example/Chat/CardField',
7
+ component: CardField,
8
+ tags: ['autodocs'],
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ args: {},
13
+ decorators: [
14
+ (Story) => (
15
+ <div className="w-[400px]">
16
+ <Story />
17
+ </div>
18
+ ),
19
+ ],
20
+ };
21
+
22
+ export default meta;
23
+ type Story = StoryObj<typeof CardField>;
24
+
25
+ // 基础用法
26
+ export const Base: Story = {
27
+ args: {
28
+ label: '维度(行)',
29
+ children: '仓库、产品名称、产品编码、日期(年-月)',
30
+ },
31
+ };
32
+
33
+ // label 过长省略展示
34
+ export const LongLabel: Story = {
35
+ args: {
36
+ label: '这是一个非常长的标签文字需要省略展示',
37
+ children: '内容区域',
38
+ },
39
+ };
40
+
41
+ // 无 children 时显示「无」
42
+ export const NoChildren: Story = {
43
+ args: {
44
+ label: '空字段',
45
+ },
46
+ };
47
+
48
+ // children 为空字符串
49
+ export const EmptyChildren: Story = {
50
+ args: {
51
+ label: '字段名称',
52
+ children: '',
53
+ },
54
+ };
55
+
56
+ // children 内容较长换行展示
57
+ export const LongContent: Story = {
58
+ args: {
59
+ label: '详细描述',
60
+ children:
61
+ '这是一段很长的内容,用于测试换行效果。内容区域支持自动换行,确保文字不会溢出容器,保持良好的阅读体验。',
62
+ },
63
+ };
64
+
65
+ // 多个 CardField 组合使用
66
+ export const MultipleFields: Story = {
67
+ args: {
68
+ label: '维度(行)',
69
+ children: '仓库、产品名称、产品编码、日期(年-月)',
70
+ },
71
+ render: () => (
72
+ <div className="flex flex-col gap-2">
73
+ <CardField label="维度(行)">仓库、产品名称、产品编码、日期(年-月)</CardField>
74
+ <CardField label="维度(列)">产品类别</CardField>
75
+ <CardField label="指标">销售额、销售量、库存量</CardField>
76
+ <CardField label="筛选条件" />
77
+ </div>
78
+ ),
79
+ };
80
+
81
+ // children 为自定义 ReactNode
82
+ export const CustomChildren: Story = {
83
+ args: {
84
+ label: '状态',
85
+ children: <span className="text-green-500 font-medium">已完成</span>,
86
+ },
87
+ };
@@ -0,0 +1,132 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { IDashWidgetType } from '@baishuyun/types';
3
+ import { DashWidgetIcon } from '@/components/biz-comp/dash-widget-icon';
4
+
5
+ const DASH_WIDGET_TYPES: IDashWidgetType[] = [
6
+ 'metric_table',
7
+ 'gauge_chart',
8
+ 'column_chart',
9
+ 'funnel_chart',
10
+ 'line_chart',
11
+ 'pie_chart',
12
+ 'area_chart',
13
+ 'radar_chart',
14
+ 'bar_chart',
15
+ 'gantt',
16
+ 'multi_axes_chart',
17
+ 'data_table',
18
+ 'background_table',
19
+ 'pivot_table',
20
+ 'map_chart',
21
+ 'newMap',
22
+ 'card',
23
+ 'rili',
24
+ 'description',
25
+ 'image',
26
+ 'gauge_imageMore',
27
+ ];
28
+
29
+ const DASH_WIDGET_TYPE_LABEL: Record<IDashWidgetType, string> = {
30
+ metric_table: '指标图',
31
+ gauge_chart: '仪表盘',
32
+ column_chart: '柱形图',
33
+ funnel_chart: '漏斗图',
34
+ line_chart: '折线图',
35
+ pie_chart: '饼图',
36
+ area_chart: '面积图',
37
+ radar_chart: '雷达图',
38
+ bar_chart: '条形图',
39
+ gantt: '甘特图',
40
+ multi_axes_chart: '双轴图',
41
+ data_table: '数据表',
42
+ background_table: '背景表',
43
+ pivot_table: '透视图',
44
+ map_chart: '地图',
45
+ newMap: '新地图',
46
+ card: '卡片',
47
+ rili: '日历',
48
+ description: '富文本',
49
+ image: '图片',
50
+ gauge_imageMore: '仪表盘更多',
51
+ };
52
+
53
+ const meta: Meta<typeof DashWidgetIcon> = {
54
+ title: 'Example/Icons/DashWidgetIcon',
55
+ component: DashWidgetIcon,
56
+ tags: ['autodocs'],
57
+ parameters: {
58
+ layout: 'centered',
59
+ },
60
+ argTypes: {
61
+ type: {
62
+ control: 'select',
63
+ options: DASH_WIDGET_TYPES,
64
+ },
65
+ },
66
+ };
67
+
68
+ export default meta;
69
+ type Story = StoryObj<typeof DashWidgetIcon>;
70
+
71
+ // 默认:指标图
72
+ export const MetricTable: Story = {
73
+ args: { type: 'metric_table' },
74
+ };
75
+
76
+ // 仪表盘
77
+ export const GaugeChart: Story = {
78
+ args: { type: 'gauge_chart' },
79
+ };
80
+
81
+ // 柱形图
82
+ export const ColumnChart: Story = {
83
+ args: { type: 'column_chart' },
84
+ };
85
+
86
+ // 折线图
87
+ export const LineChart: Story = {
88
+ args: { type: 'line_chart' },
89
+ };
90
+
91
+ // 饼图
92
+ export const PieChart: Story = {
93
+ args: { type: 'pie_chart' },
94
+ };
95
+
96
+ // 条形图
97
+ export const BarChart: Story = {
98
+ args: { type: 'bar_chart' },
99
+ };
100
+
101
+ // 所有图标类型一览
102
+ export const AllTypes: Story = {
103
+ args: { type: 'metric_table' },
104
+ render: () => (
105
+ <div
106
+ style={{
107
+ display: 'grid',
108
+ gridTemplateColumns: 'repeat(4, 1fr)',
109
+ gap: '16px',
110
+ }}
111
+ >
112
+ {DASH_WIDGET_TYPES.map((t) => (
113
+ <div
114
+ key={t}
115
+ style={{
116
+ display: 'flex',
117
+ flexDirection: 'column',
118
+ alignItems: 'center',
119
+ gap: '4px',
120
+ padding: '12px',
121
+ border: '1px solid #eee',
122
+ borderRadius: '8px',
123
+ }}
124
+ >
125
+ <DashWidgetIcon type={t} style={{ fontSize: 24 }} />
126
+ <span style={{ fontSize: 12, color: '#666' }}>{DASH_WIDGET_TYPE_LABEL[t]}</span>
127
+ <span style={{ fontSize: 10, color: '#aaa' }}>{t}</span>
128
+ </div>
129
+ ))}
130
+ </div>
131
+ ),
132
+ };