plain-design 1.0.0-beta.133 → 1.0.0-beta.135

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 (36) hide show
  1. package/dist/plain-design.commonjs.min.js +2 -18
  2. package/dist/plain-design.commonjs.min.js.LICENSE.txt +18 -0
  3. package/dist/plain-design.min.css +2 -1
  4. package/dist/plain-design.min.js +2 -18
  5. package/dist/plain-design.min.js.LICENSE.txt +18 -0
  6. package/dist/report.html +3 -3
  7. package/package.json +43 -40
  8. package/src/packages/components/$ai/index.tsx +214 -0
  9. package/src/packages/components/$configuration/index.tsx +2 -0
  10. package/src/packages/components/$file/index.tsx +43 -0
  11. package/src/packages/components/AiChatBox/ai-chat-box.scss +71 -0
  12. package/src/packages/components/AiChatBox/index.tsx +154 -0
  13. package/src/packages/components/AutoTable/auto-table.scss +4 -3
  14. package/src/packages/components/AutoTable/createTableOptionUser.tsx +3 -1
  15. package/src/packages/components/AutoTable/filter/useTableOption.filter.state.ts +4 -3
  16. package/src/packages/components/AutoTable/setting/useTableOption.setting.config.tsx +57 -15
  17. package/src/packages/components/AutoTable/setting/useTableOption.setting.export.tsx +2 -27
  18. package/src/packages/components/AutoTable/setting/useTableOption.setting.senior.filter.tsx +92 -92
  19. package/src/packages/components/AutoTable/setting/useTableOption.setting.senior.sort.tsx +14 -7
  20. package/src/packages/components/AutoTable/use/useTableOption.ai.tsx +485 -0
  21. package/src/packages/components/AutoTable/use/useTableOption.buttons.tsx +26 -16
  22. package/src/packages/components/AutoTable/use/useTableOption.methods.tsx +3 -0
  23. package/src/packages/components/AutoTable/use/useTableOption.sort.ts +4 -3
  24. package/src/packages/components/AutoTable/utils/AutoTable.utils.ts +75 -0
  25. package/src/packages/components/AutoTable/utils/TableOption.space.tsx +2 -1
  26. package/src/packages/components/FilterService/filter/filter.select.tsx +1 -0
  27. package/src/packages/components/Image/index.tsx +2 -2
  28. package/src/packages/components/ImageUploader/index.tsx +4 -4
  29. package/src/packages/components/PlcImage/index.tsx +5 -5
  30. package/src/packages/components/Table/editor/PlcSelect.tsx +1 -0
  31. package/src/packages/components/Table/table/use/useTableFormEditor.tsx +38 -34
  32. package/src/packages/components/Table/table/utils/table.utils.ts +1 -0
  33. package/src/packages/components/useDialog/DialogService.tsx +1 -1
  34. package/src/packages/entry.tsx +4 -0
  35. package/src/packages/i18n/lang/en-us.ts +23 -14
  36. package/src/packages/i18n/lang/zh-cn.ts +10 -1
@@ -1,6 +1,8 @@
1
1
  import {tScopeSlotsType, tSlotsType} from "@peryl/react-compose";
2
2
  import {iTableCellRenderScope} from "../../Table/table/utils/table.utils";
3
3
  import {TableOptionSpace} from "./TableOption.space";
4
+ import {iAiConfiguration} from "../../$ai";
5
+ import {tPlc} from "../../Table/plc/utils/plc.utils";
4
6
 
5
7
  /**
6
8
  * AutoTable插槽类型
@@ -43,3 +45,76 @@ export interface iAutoTablePageData {
43
45
  hasNext: boolean,
44
46
  total?: null | number,
45
47
  }
48
+
49
+ /**
50
+ * AutoOption中配置AI的相关设置
51
+ * @author 韦胜健
52
+ * @date 2025/4/6 10:58
53
+ */
54
+ export interface iAutoTableAiConfig {
55
+ search: boolean,
56
+ sort: boolean,
57
+ config: boolean,
58
+ aiConfig?: iAiConfiguration,
59
+ }
60
+
61
+ /**
62
+ * settingConfig中编辑的数据类型
63
+ * @author 韦胜健
64
+ * @date 2025/4/7 22:43
65
+ */
66
+ export interface iPlcConfigData {
67
+ field: string,
68
+ title?: string,
69
+ order: number,
70
+ align: string,
71
+ width: number,
72
+ fixed: string,
73
+ hide?: boolean,
74
+
75
+ plcRef: () => tPlc,
76
+ key: string,
77
+ }
78
+
79
+ /**
80
+ * 通过外部数据源的方式配置字段信息的数据类型
81
+ * @author 韦胜健
82
+ * @date 2025/4/7 22:43
83
+ */
84
+ export type iPlcCustomData = Partial<Omit<iPlcConfigData, 'plcRef' | 'key' | 'field'>> & { field: string }
85
+
86
+ /*---------------------------------------table ai types-------------------------------------------*/
87
+
88
+ /*ai返回列表搜索的数据类型*/
89
+ export interface iTableAiOperateSearch {
90
+ type: 'search',
91
+ data: { filters: { id: string, field: string, filterHandler: string, value: any }[], filterExpression: string }
92
+ }
93
+
94
+ /*ai返回列表排序的数据类型*/
95
+ export interface iTableAiOperateSort {
96
+ type: 'sort',
97
+ data: { field: string, desc: boolean, title: string }[]
98
+ }
99
+
100
+ /*ai返回列表字段配置的数据类型*/
101
+ export interface iTableAiOperateConfig {
102
+ type: 'config',
103
+ data: iTableAiOperatePlcMeta[]
104
+ }
105
+
106
+ /*ai返回的解析错误的数据类型*/
107
+ export interface iTableAiOperateError {
108
+ type: 'error',
109
+ data: string
110
+ }
111
+
112
+ /**
113
+ * ai返回的配置字段的耽搁字段配置数据类型
114
+ * @author 韦胜健
115
+ * @date 2025/4/7 22:47
116
+ */
117
+ export type iTableAiOperatePlcMeta = iPlcCustomData & { filterType: string }
118
+
119
+ /*ai返回的数据类型*/
120
+ export type iTableAiOperate = iTableAiOperateSearch | iTableAiOperateSort | iTableAiOperateConfig | iTableAiOperateError
@@ -1,6 +1,6 @@
1
1
  import {PlainObject} from "@peryl/utils/event";
2
2
  import {iHttp} from "../../createHttp";
3
- import {iAutoTableRefer, iAutoTableScopeSlotsType, iAutoTableSlotsType} from "./AutoTable.utils";
3
+ import {iAutoTableAiConfig, iAutoTableRefer, iAutoTableScopeSlotsType, iAutoTableSlotsType} from "./AutoTable.utils";
4
4
  import {iUrl, tGetDefaultUrlConfig} from "./TableOption.url";
5
5
  import {iTableOperation, iTableOperationPermitConfig} from "../../Table/standard/PlcOperation/PlcOperation.utils";
6
6
  import {iTableRefer} from "../../Table/table/Table";
@@ -43,6 +43,7 @@ export namespace TableOptionSpace {
43
43
  setCache: (cacheData: iTableOptionCacheData) => void, // 保存缓存配置信息
44
44
  size?: typeof ThemeSize.TYPE, // 表格尺寸
45
45
  filterFormColumn: number, // 查询表单列数
46
+ ai?: false | Partial<iAutoTableAiConfig>, // AI设置
46
47
  }
47
48
 
48
49
  /**
@@ -8,6 +8,7 @@ import i18n from "../../i18n";
8
8
 
9
9
  export interface iFilterConfigSelect {
10
10
  renderOptions: () => RenderNode,
11
+ getSelectOptions: () => { label: string, val: any }[]
11
12
  }
12
13
 
13
14
  /**
@@ -3,9 +3,9 @@ import './image.scss';
3
3
  import {unit} from "@peryl/utils/unit";
4
4
  import {createEnum} from "@peryl/utils/createEnum";
5
5
  import {Icon} from "../Icon";
6
- import {$image} from "../$image";
7
6
  import {LoadingMask} from "../LoadingMask";
8
7
  import i18n from "../i18n";
8
+ import {$previewer} from "../$previewer";
9
9
 
10
10
  /**
11
11
  * 图片填充类型
@@ -135,7 +135,7 @@ export const Image = designComponent({
135
135
  const handler = {
136
136
  onClick: (e: iMouseEvent) => {
137
137
  if (state.status === eImageStatus.success && props.previewOnClick) {
138
- $image.preview(state.src!);
138
+ $previewer.preview(state.src!, e.currentTarget as any);
139
139
  }
140
140
  emit.onClick(e);
141
141
  }
@@ -1,9 +1,8 @@
1
- import {computed, designComponent, getComponentCls, PropType, reactive, useClasses, useModel, useRefs, useStyles, watch} from "@peryl/react-compose";
1
+ import {computed, designComponent, getComponentCls, iMouseEvent, PropType, reactive, useClasses, useModel, useRefs, useStyles, watch} from "@peryl/react-compose";
2
2
  import {unit} from "@peryl/utils/unit";
3
3
  import {deepcopy} from "@peryl/utils/deepcopy";
4
4
  import {defer} from "@peryl/utils/defer";
5
5
  import {Image, ImagePropsOptions} from "../Image";
6
- import {$image} from "../$image";
7
6
  import {Icon} from "../Icon";
8
7
  import {PlainObject} from "@peryl/utils/event";
9
8
  import {createEnum} from "@peryl/utils/createEnum";
@@ -13,6 +12,7 @@ import $configuration from "../$configuration";
13
12
  import {iUploadService} from "../$upload/createUploadService";
14
13
  import i18n from "../i18n";
15
14
  import {iUploadServiceConfig} from "../$upload/upload.utils";
15
+ import {$previewer} from "../$previewer";
16
16
 
17
17
  /**
18
18
  * ImageUploader的状态
@@ -174,7 +174,7 @@ export const ImageUploader = designComponent({
174
174
  if (!editComputed.value.editable) return;
175
175
  await methods.choose();
176
176
  },
177
- onClickImage: async () => {
177
+ onClickImage: async (e: iMouseEvent) => {
178
178
  if (state.status === eImageUploaderStatus.error) {
179
179
  return await handler.onClick();
180
180
  }
@@ -182,7 +182,7 @@ export const ImageUploader = designComponent({
182
182
  if (!!props.handlePreview) {
183
183
  return props.handlePreview(url);
184
184
  } else {
185
- !!url && $image.preview(url);
185
+ !!url && $previewer.preview(url, e.currentTarget as any);
186
186
  }
187
187
  },
188
188
  onClickDelete: async () => {
@@ -1,13 +1,13 @@
1
- import {computed, designComponent, PropType} from "@peryl/react-compose";
1
+ import {computed, designComponent, iMouseEvent, PropType} from "@peryl/react-compose";
2
2
  import {createPlcPropOptions, PlcEmitsOptions} from "../Table/plc/utils/plc.utils";
3
3
  import {PlcScopeSlotsOptions} from "../Table/plc/utils/plc.scope-slots";
4
4
  import {injectPlainTable} from "../Table/table/Table";
5
- import {$image} from "../$image";
6
5
  import {FileServiceUploadConfig} from "../$file";
7
6
  import $configuration from "../$configuration";
8
7
  import {formatImagePath, Image} from "../Image";
9
8
  import {usePlc} from "../Table/plc/use/usePlc";
10
9
  import ImageUploader from "../ImageUploader";
10
+ import {$previewer} from "../$previewer";
11
11
 
12
12
  export const PlcImage = designComponent({
13
13
  name: 'plc-image',
@@ -35,8 +35,8 @@ export const PlcImage = designComponent({
35
35
 
36
36
  const urlPrefix = computed(() => props.urlPrefix || upload?.config.prefix);
37
37
 
38
- const preview = (index: number) => {
39
- $image.preview((table.dataRef.value.data || []).map(i => formatImagePath(i[props.field!], urlPrefix.value)), index);
38
+ const preview = (index: number, e: iMouseEvent) => {
39
+ $previewer.preview({ current: index, urls: (table.dataRef.value.data || []).map(i => formatImagePath(i[props.field!], urlPrefix.value)) }, e.currentTarget as any);
40
40
  };
41
41
 
42
42
  return usePlc({
@@ -56,7 +56,7 @@ export const PlcImage = designComponent({
56
56
  minHeight={size.value}
57
57
  hideTips
58
58
  fit="cover"
59
- onClick={() => preview(node.state.index)}
59
+ onClick={(e) => preview(node.state.index, e)}
60
60
  />
61
61
  ),
62
62
  edit: ({ row, plc }) => !plc.props.field ? null :
@@ -51,6 +51,7 @@ export const PlcSelect = designComponent({
51
51
  const filterConfig = computed((): iFilterConfigSelect => {
52
52
  return {
53
53
  renderOptions: () => slots.default(),
54
+ getSelectOptions: () => selectOptionDecoder.options.map((so: any) => ({ label: so.props.label, val: so.props.val })),
54
55
  ...props.filterConfig,
55
56
  };
56
57
  });
@@ -115,40 +115,44 @@ export function useTableFormEditor(
115
115
  handleCancel={handler.handleCancel}
116
116
  position="right"
117
117
  initialize
118
- >
119
- <Form
120
- rules={rules}
121
- ref={onRef.form}
122
- column={1}
123
- modelValue={node.state.editRow}
124
- labelAlign="right"
125
- validateMessagePosition="bottom-left"
126
- >
127
- {showPlcArray.value.map((plc, index) => {
128
- if (plc.props.editColSpan === 0) {
129
- return null;
130
- }
131
- const { bodyCell } = cellBodyArray.value[index];
132
- const { editable, body } = bodyCell.value();
133
- const validateAttrs = pick(plc.props, Object.keys(PlcValidatePropsOption) as (keyof typeof PlcValidatePropsOption)[]);
134
- return (
135
- <FormItem
136
- key={index}
137
- label={plc.props.formLabel || plc.props.title}
138
- field={plc.props.field}
139
- required={plc.props.required}
140
- rules={plc.props.rules}
141
- validator={plc.props.validator}
142
- tip={plc.props.tip}
143
- disabled={!editable}
144
- {...validateAttrs}
145
- >
146
- {body}
147
- </FormItem>
148
- );
149
- })}
150
- </Form>
151
- </Dialog>
118
+ v-slots={{
119
+ default: () => (
120
+ <Form
121
+ rules={rules}
122
+ ref={onRef.form}
123
+ column={1}
124
+ modelValue={node.state.editRow}
125
+ labelAlign="right"
126
+ validateMessagePosition="bottom-left"
127
+ >
128
+ {showPlcArray.value.map((plc, index) => {
129
+ if (plc.props.editColSpan === 0) {
130
+ return null;
131
+ }
132
+ const { bodyCell } = cellBodyArray.value[index];
133
+ const { editable, body } = bodyCell.value();
134
+ const validateAttrs = pick(plc.props, Object.keys(PlcValidatePropsOption) as (keyof typeof PlcValidatePropsOption)[]);
135
+ return (
136
+ <FormItem
137
+ key={index}
138
+ label={plc.props.formLabel || plc.props.title}
139
+ field={plc.props.field}
140
+ required={plc.props.required}
141
+ rules={plc.props.rules}
142
+ validator={plc.props.validator}
143
+ tip={plc.props.tip}
144
+ disabled={!editable}
145
+ {...validateAttrs}
146
+ >
147
+ {body}
148
+ </FormItem>
149
+ );
150
+ })}
151
+ </Form>
152
+ ),
153
+ foot: () => props.formEditorFootRender?.(node.state.editRow)
154
+ }}
155
+ />
152
156
  );
153
157
  },
154
158
  }));
@@ -39,6 +39,7 @@ export const TablePropsOptions = {
39
39
  spanMethod: { type: Function as PropType<TablePropsSpanMethod> }, // 合并表体单元格的方法
40
40
  size: { ...StyleProps["size"] }, // 表格尺寸
41
41
  loading: { type: Boolean }, // 开启加载状态
42
+ formEditorFootRender: { type: Function as PropType<(formData: PlainObject) => any> },// 表单编辑器的foot渲染内容
42
43
 
43
44
  rowClassFunc: { type: Function as PropType<TablePropsRowClassFunc> },// 行 className 的计算函数
44
45
  cellClassFunc: { type: Function as PropType<TablePropsCellClassFunc> },// 单元格 className 的计算函数
@@ -136,7 +136,7 @@ export const DialogService = createApplicationServiceComponent<iDialogServiceOpt
136
136
  /*wrap handleConfirm*/
137
137
  dialogProps.handleConfirm = async (close: () => void) => {
138
138
  if (!!targetOption.value.customOption.editRequired) {
139
- if (state.editValue == null || !state.editValue.trim().length) {
139
+ if (state.editValue == null || (typeof state.editValue === "string" && !state.editValue.trim().length)) {
140
140
  $message.warn('不能为空!');
141
141
  return false;
142
142
  }
@@ -135,6 +135,10 @@ export {ImagePreviewer} from './components/ImagePreviewer/ImagePreviewer';
135
135
  export {Corner} from './components/Corner';
136
136
  export {useContextmenuOptions} from './components/useContextmenuOptions';
137
137
  export type {iContextmenuOption} from './components/useContextmenuOptions';
138
+ export {AiChatBox} from './components/AiChatBox';
139
+ export type {iChatBoxHistory} from './components/AiChatBox';
140
+ export {$ai} from './components/$ai';
141
+ export type {iAiChoice, iAiChatResponse, iAiConfiguration} from './components/$ai';
138
142
 
139
143
  export {VirtualTable} from './components/VirtualTable';
140
144
  export {Table} from './components/Table';
@@ -29,7 +29,7 @@ export const EnUsLocale: tZhCnLocale = {
29
29
  main: 'Main',
30
30
  fixed: 'Fixed',
31
31
  hide: 'Hidden',
32
- exportData: 'Export data',
32
+ exportData: 'Export Data',
33
33
  custom: 'Custom',
34
34
  setting: 'Setting',
35
35
  asc: 'Asc',
@@ -176,21 +176,22 @@ export const EnUsLocale: tZhCnLocale = {
176
176
  configSeniorFilter: 'Senior filter',
177
177
  formFilter: 'Form filter',
178
178
  formQuery: 'Form query',
179
+ aiButton: 'AI Chat',
179
180
  searchBar: 'Search bar',
180
181
  pleaseEditSearchParam: 'Please input search param directly',
181
- allFilter: 'All filter',
182
+ allFilter: 'All Filter',
182
183
  noFilter: 'No filter',
183
184
  clearAll: 'Clear all',
184
185
  pleaseInputThConfigurationName: 'Please input configuration name',
185
186
  bak: 'Backup',
186
187
  areYouSureToOverrideTheConfiguration: 'Are you sure to override "{title}" to be the latest configuration',
187
- cacheSetting: 'Cache setting',
188
+ cacheSetting: 'Cache Setting',
188
189
  clearFilterSortAndConfiguration: 'Clear filter, sort and configuration',
189
190
  withoutAnyConfiguration: 'Use none configuration',
190
191
  saveToNewConfiguration: 'Save current to be new configuration',
191
192
  cacheName: 'Cache name',
192
193
  createTime: 'Create time',
193
- customSetting: 'Custom setting',
194
+ customSetting: 'Custom Setting',
194
195
  title: 'Title',
195
196
  alignType: 'Align type',
196
197
  alignLeft: 'Left',
@@ -210,20 +211,21 @@ export const EnUsLocale: tZhCnLocale = {
210
211
  exportShowData: 'Export show data',
211
212
  fieldName: 'Field name',
212
213
  exportAgain: 'Export again',
213
- importData: 'Import data',
214
+ importData: 'Import Data',
214
215
  pleaseEnterCompleteParamsForCondition: 'Please input complete param for the {invalidIndex} condition ',
215
- seniorFilter: 'Senior filter',
216
+ seniorFilter: 'Senior Filter',
216
217
  pleaseAddFilterCondition: 'Please add filter condition',
217
- seniorQuery: 'Senior query',
218
+ seniorQuery: 'Senior Query',
218
219
  ascOrDesc: 'Asc Or Desc',
219
- formEdit: 'Form edit',
220
- batchCreate: 'Batch create',
221
- batchDelete: 'Batch delete',
222
- batchEdit: 'Batch edit',
223
- batchModify: 'Batch modify',
224
- seniorSort: 'Senior sort',
220
+ formEdit: 'Form Edit',
221
+ batchCreate: 'Batch Create',
222
+ aiCreate: 'AI Create',
223
+ batchDelete: 'Batch Delete',
224
+ batchEdit: 'Batch Edit',
225
+ batchModify: 'Batch Modify',
226
+ seniorSort: 'Senior Sort',
225
227
  canNotDeleteUsingCache: 'Can not delete cache which is using',
226
- columnFilter: 'Column filter',
228
+ columnFilter: 'Column Filter',
227
229
  distinctFilter: 'Distinct filter',
228
230
  filterTipInclude: '{field} includes {val}',
229
231
  clearDistinctFilter: 'Clear distinct filter',
@@ -316,4 +318,11 @@ export const EnUsLocale: tZhCnLocale = {
316
318
  searchHistory: 'Search History',
317
319
  favorite: 'Favorite'
318
320
  },
321
+ ai: {
322
+ placeholder: 'Please enter the content to be sent to the AI, such as: Who are you?',
323
+ require: 'The content of the question cannot be empty',
324
+ tableAiPlaceholder: 'You can have a conversation with the AI to achieve the functions of querying, sorting, and configuring the list. For example, query the data with the number approximately equal to 129 and the creation time greater than the day before yesterday, sort it in descending order by the creation time first, and then in ascending order by the update time. Finally, adjust the width of the number field.',
325
+ formAiPlaceholder: 'Describe the data content you want to edit in one sentence.',
326
+ smartFilling: 'Smart Filling',
327
+ }
319
328
  };
@@ -47,7 +47,7 @@ export const ZhCnLocale = {
47
47
  invalidAmount: '无效金额',
48
48
  province: '省',
49
49
  city: '市',
50
- district: '区/县',
50
+ district: '区县',
51
51
  lookUp: '查看',
52
52
  operation: '操作',
53
53
  noFilter: '暂无筛选',
@@ -174,6 +174,7 @@ export const ZhCnLocale = {
174
174
  configSeniorFilter: '配置高级查询',
175
175
  formFilter: '表单筛选',
176
176
  formQuery: '表单查询',
177
+ aiButton: 'AI对话',
177
178
  searchBar: '搜索栏',
178
179
  pleaseEditSearchParam: '请直接编辑搜索栏筛选参数',
179
180
  allFilter: '所有筛选',
@@ -216,6 +217,7 @@ export const ZhCnLocale = {
216
217
  ascOrDesc: '升序还是降序',
217
218
  formEdit: '表单编辑',
218
219
  batchCreate: '批量新建',
220
+ aiCreate: '智能新建',
219
221
  batchDelete: '批量删除',
220
222
  batchEdit: '批量编辑',
221
223
  batchModify: '批量修改',
@@ -314,6 +316,13 @@ export const ZhCnLocale = {
314
316
  searchHistory: '搜索历史',
315
317
  favorite: '收藏'
316
318
  },
319
+ ai: {
320
+ placeholder: '请输入要发送给ai的内容如:你是谁',
321
+ require: '提问的内容不能为空',
322
+ tableAiPlaceholder: '你可以与ai对话实现对列表的查询、排序以及配置功能;比如:查询编号约等于129,创建时间大于前天的数据,先按照创建时间降序,再按照更新时间升序排序;最后是调宽编号字段的宽度',
323
+ formAiPlaceholder: '一句话描述你要编辑的数据内容',
324
+ smartFilling:'智能填写',
325
+ }
317
326
  } as const;
318
327
 
319
328
  type ZhCnLocaleUtils<T> = { [k in keyof T]: T[k] extends string ? string : ZhCnLocaleUtils<T[k]> }