form-driver 0.3.14 → 0.4.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.
@@ -1,34 +1,42 @@
1
-
2
1
  import { MUtil } from "../framework/MUtil";
3
2
  import { MFieldSchemaAnonymity, MValidationResult } from "../framework/Schema";
4
- import { MType} from "./MType";
3
+ import { MType } from "./MType";
5
4
 
6
- import { validateArrayItemMinMax, validateRequired } from "../framework/Validator";
5
+ import {
6
+ validateArrayItemMinMax,
7
+ validateRequired,
8
+ } from "../framework/Validator";
7
9
  import { assembly, Assembly } from "../framework/Assembly";
8
10
  import _ from "lodash";
9
11
 
10
12
  // 选项是否合法、开放选项是否合法
11
- function validateCandidate(a:Assembly, schema:MFieldSchemaAnonymity, value:any, path:string): MValidationResult {
13
+ function validateCandidate(
14
+ a: Assembly,
15
+ schema: MFieldSchemaAnonymity,
16
+ value: any,
17
+ path: string
18
+ ): MValidationResult {
12
19
  let fs = MUtil.option(schema);
13
- const openOption = _.clone(schema.openOption ?? schema.setOpen)
14
-
15
- for(let v of value){
20
+ const openOption = _.clone(schema.openOption ?? schema.setOpen);
21
+
22
+ for (let v of value) {
16
23
  let vIsOk = false;
17
- for(let f of fs){
18
- if(MUtil.isEquals(f.value, v, schema.tolerate)){
24
+ for (let f of fs) {
25
+ if (MUtil.isEquals(f.value, v, schema.tolerate)) {
19
26
  vIsOk = true;
20
27
  break; // v校验ok
21
28
  }
22
29
  }
23
- if(!vIsOk) {
24
- if(openOption) {
30
+ if (!vIsOk) {
31
+ if (openOption) {
25
32
  openOption.required = true; // 既然勾上了开放选项,就必须填
26
33
  const vr = assembly.validate(openOption, v, path);
27
- if(vr) { // 开放值无效
34
+ if (vr) {
35
+ // 开放值无效
28
36
  return vr;
29
37
  }
30
38
  } else {
31
- return {message:"请重新选择", path};
39
+ return { message: "请重新选择", path };
32
40
  }
33
41
  }
34
42
  }
@@ -36,36 +44,59 @@ function validateCandidate(a:Assembly, schema:MFieldSchemaAnonymity, value:any,
36
44
  }
37
45
 
38
46
  export const MSetType: MType & {
39
- change: (isAdd:boolean, newValue:any, value:any[], s:MFieldSchemaAnonymity)=>any[],
40
- openValueIndex: (s:MFieldSchemaAnonymity, vs: any[])=>number,
41
- clearOpenValue: (s:MFieldSchemaAnonymity, vs: any[], keepOne:boolean)=>any[]
42
- } = {
47
+ change: (
48
+ isAdd: boolean,
49
+ newValue: any,
50
+ value: any[],
51
+ s: MFieldSchemaAnonymity,
52
+ isNeedSkipHandleOpenValue?: boolean
53
+ ) => any[];
54
+ openValueIndex: (s: MFieldSchemaAnonymity, vs: any[]) => number;
55
+ clearOpenValue: (
56
+ s: MFieldSchemaAnonymity,
57
+ vs: any[],
58
+ keepOne: boolean
59
+ ) => any[];
60
+ } = {
43
61
  validators: [validateRequired, validateCandidate, validateArrayItemMinMax],
44
62
 
45
- toReadable: (assembly:Assembly, s:MFieldSchemaAnonymity, vs:any):string => {
63
+ toReadable: (
64
+ assembly: Assembly,
65
+ s: MFieldSchemaAnonymity,
66
+ vs: any
67
+ ): string => {
46
68
  const fs = MUtil.option(s);
47
- if(_.isNil(vs)){
69
+ if (_.isNil(vs)) {
48
70
  return assembly.theme.READABLE_BLANK;
49
- } else if(!_.isArray(vs)){
71
+ } else if (!_.isArray(vs)) {
50
72
  return assembly.theme.READABLE_ERROR;
51
73
  }
52
- return vs.map((v:any) => {
53
- for(let f of fs) {
54
- if(f.value === v){
55
- return f.label ?? v;
74
+ return vs
75
+ .map((v: any) => {
76
+ for (let f of fs) {
77
+ if (f.value === v) {
78
+ return f.label ?? v;
79
+ }
56
80
  }
57
- }
58
- // 其他选项的内容前加上标识
59
- return s.openOption ? `「${s.openOption.label}」${v}` : assembly.theme.READABLE_INVALID
60
- }).join(", ");
81
+ // 其他选项的内容前加上标识
82
+ return s.openOption
83
+ ? `「${s.openOption.label}」${v}`
84
+ : assembly.theme.READABLE_INVALID;
85
+ })
86
+ .join(", ");
61
87
  },
62
88
 
63
- standardValue: (a:Assembly, s:MFieldSchemaAnonymity, vs:any, strict:boolean):any => {
89
+ standardValue: (
90
+ a: Assembly,
91
+ s: MFieldSchemaAnonymity,
92
+ vs: any,
93
+ strict: boolean
94
+ ): any => {
64
95
  // 类型正确
65
- if(!_.isArray(vs)){
96
+ if (!_.isArray(vs)) {
66
97
  return s.defaultValue;
67
98
  }
68
- if(!strict){
99
+ if (!strict) {
69
100
  return vs;
70
101
  }
71
102
 
@@ -73,16 +104,22 @@ export const MSetType: MType & {
73
104
  const fs = MUtil.option(s);
74
105
  const result = [];
75
106
  let openValueFound = false; // 只能有一个开放值
76
- for(let v of vs) {
107
+ for (let v of vs) {
77
108
  let matched = false;
78
- for(let f of fs){
79
- if(MUtil.isEquals(f.value, v, s.tolerate)){
80
- result.push(v)
109
+ for (let f of fs) {
110
+ if (MUtil.isEquals(f.value, v, s.tolerate)) {
111
+ result.push(v);
81
112
  matched = true;
82
113
  break;
83
114
  }
84
115
  }
85
- if((s.openOption ?? s.setOpen)&& !matched && !openValueFound && !_.isNil(v)) { // 使用第一个非nil的开放值
116
+ if (
117
+ (s.openOption ?? s.setOpen) &&
118
+ !matched &&
119
+ !openValueFound &&
120
+ !_.isNil(v)
121
+ ) {
122
+ // 使用第一个非nil的开放值
86
123
  openValueFound = true;
87
124
  result.push(v);
88
125
  }
@@ -98,40 +135,51 @@ export const MSetType: MType & {
98
135
  * @param s schema
99
136
  * @returns 修改后的集合,可能不是newValue对象
100
137
  */
101
- change: (isAdd:boolean, newValue:any, prevValue:any[], s:MFieldSchemaAnonymity):any[] => {
102
- if(isAdd) {
138
+ change: (
139
+ isAdd: boolean,
140
+ newValue: any,
141
+ prevValue: any[],
142
+ s: MFieldSchemaAnonymity,
143
+ isNeedSkipHandleOpenValue?: boolean
144
+ ): any[] => {
145
+ if (isAdd) {
103
146
  // 如果有多个不在option中的值,就只保留一个
104
- prevValue = MSetType.clearOpenValue(s, prevValue, true);
147
+ if (!isNeedSkipHandleOpenValue) {
148
+ prevValue = MSetType.clearOpenValue(s, prevValue, true);
149
+ }
105
150
 
106
- if(prevValue?.indexOf(newValue) >= 0){ // 如果要add的值已经存在了,直接返回即可
151
+ if (prevValue?.indexOf(newValue) >= 0) {
152
+ // 如果要add的值已经存在了,直接返回即可
107
153
  return prevValue;
108
154
  }
109
155
 
110
156
  // 处理排他选项
111
157
  const option = MUtil.option(s);
112
- const newFs = _.find(option, {value:newValue});
158
+ const newFs = _.find(option, { value: newValue });
159
+ console.log("change 变化", option, prevValue, newValue, newFs);
113
160
  // 把所有exclusive跟自己不同的都清掉(newFs空是开放选项,不用管)
114
- if(newFs) {
115
- prevValue = prevValue?.filter(v => {
116
- const fs = _.find(option, {value:v});
117
- if(fs && fs.exclusive !== newFs.exclusive) {
161
+ if (newFs) {
162
+ prevValue = prevValue?.filter((v) => {
163
+ const fs = _.find(option, { value: v });
164
+ if (fs && fs.exclusive !== newFs.exclusive) {
118
165
  return false;
119
166
  }
120
- return true;
121
- })
167
+ return true;
168
+ });
122
169
  }
123
170
 
124
171
  // 新值加入
125
- if(!_.isArray(prevValue)){
172
+ if (!_.isArray(prevValue)) {
126
173
  prevValue = [];
127
174
  }
128
175
  prevValue.push(newValue);
129
176
 
130
177
  // 处理max限制
131
178
  const max = s.max ?? Number.MAX_VALUE;
132
- while(max > 0 && prevValue.length > max) { // 超过上限了,要删到上限为止,但不能删新加的那条
133
- for(let d of prevValue) {
134
- if(d !== newValue){
179
+ while (max > 0 && prevValue.length > max) {
180
+ // 超过上限了,要删到上限为止,但不能删新加的那条
181
+ for (let d of prevValue) {
182
+ if (d !== newValue) {
135
183
  MUtil.arrayRemove(prevValue, d);
136
184
  break;
137
185
  }
@@ -140,10 +188,13 @@ export const MSetType: MType & {
140
188
  } else {
141
189
  MUtil.arrayRemove(prevValue, newValue);
142
190
 
143
- // 如果有多个不在option中的值,就只保留一个
144
- prevValue = MSetType.clearOpenValue(s, prevValue, true);
191
+ if (!isNeedSkipHandleOpenValue) {
192
+ // 如果有多个不在option中的值,就只保留一个
193
+ prevValue = MSetType.clearOpenValue(s, prevValue, true);
194
+ }
145
195
  }
146
- if(!prevValue?.length) { // 如果删光了,或者只剩个开放选项,但是没有填
196
+ if (!prevValue?.length) {
197
+ // 如果删光了,或者只剩个开放选项,但是没有填
147
198
  prevValue = undefined;
148
199
  }
149
200
  return prevValue;
@@ -155,27 +206,33 @@ export const MSetType: MType & {
155
206
  * @param vs 值
156
207
  * @param keepOne 是否在schema允许的情况下(有openOption)保留一个有意义的(尽量非nil)开放选项
157
208
  */
158
- clearOpenValue: (s:MFieldSchemaAnonymity, vs: any[], keepOne:boolean):any[] =>{
159
- if(!vs){
209
+ clearOpenValue: (
210
+ s: MFieldSchemaAnonymity,
211
+ vs: any[],
212
+ keepOne: boolean
213
+ ): any[] => {
214
+ if (!vs) {
160
215
  return;
161
216
  }
162
217
  const opt = MUtil.option(s);
163
218
  const result = [];
164
-
219
+
165
220
  let openValue;
166
221
  let openValueFound = false;
167
222
 
168
- for(let i = 0; i < vs.length; i ++) {
169
- const matched = opt.find(o => MUtil.isEquals(vs[i], o.value, s.tolerate));
170
- if(matched) {
223
+ for (let i = 0; i < vs.length; i++) {
224
+ const matched = opt.find((o) =>
225
+ MUtil.isEquals(vs[i], o.value, s.tolerate)
226
+ );
227
+ if (matched) {
171
228
  result.push(matched.value);
172
229
  } else {
173
- openValue = openValue ?? vs[i]
230
+ openValue = openValue ?? vs[i];
174
231
  openValueFound = true;
175
232
  }
176
233
  }
177
234
 
178
- if(openValueFound && keepOne && (s.openOption ?? s.setOpen)) {
235
+ if (openValueFound && keepOne && (s.openOption ?? s.setOpen)) {
179
236
  result.push(openValue);
180
237
  }
181
238
 
@@ -184,8 +241,8 @@ export const MSetType: MType & {
184
241
 
185
242
  /**
186
243
  * 获取开放选项的下标。
187
- * @param s
188
- * @param vs
244
+ * @param s
245
+ * @param vs
189
246
  * 1. 优先把nil值作为开放选项(为了尽量保留有意义的值)
190
247
  * 2. 如果没有nil,最后一个在option中未出现的值作为开放选项
191
248
  * 例如
@@ -193,26 +250,26 @@ export const MSetType: MType & {
193
250
  * openValueIndex(assembly, [a,b,c], [a, e, d, f]) = 3
194
251
  * @returns -1表示没有找到开放选项
195
252
  */
196
- openValueIndex: (s:MFieldSchemaAnonymity, vs: any[]):number =>{
197
- if(!vs){
253
+ openValueIndex: (s: MFieldSchemaAnonymity, vs: any[]): number => {
254
+ if (!vs) {
198
255
  return -1;
199
256
  }
200
257
  const opt = MUtil.option(s);
201
258
  let openIdx = -1;
202
- for(let i = 0; i < vs.length; i ++) {
259
+ for (let i = 0; i < vs.length; i++) {
203
260
  const v = vs[i];
204
- if(_.isNil(v)) {
261
+ if (_.isNil(v)) {
205
262
  return i;
206
263
  }
207
- if(! opt.find(o => MUtil.isEquals(v, o.value, s.tolerate)) ) {
264
+ if (!opt.find((o) => MUtil.isEquals(v, o.value, s.tolerate))) {
208
265
  openIdx = i;
209
266
  }
210
267
  }
211
268
  return openIdx;
212
269
  },
213
270
 
214
- createDefaultValue: (assembly:Assembly, s:MFieldSchemaAnonymity):any =>{
215
- if(s.defaultValue){
271
+ createDefaultValue: (assembly: Assembly, s: MFieldSchemaAnonymity): any => {
272
+ if (s.defaultValue) {
216
273
  return _.clone(s.defaultValue);
217
274
  } else {
218
275
  return []; // 默认不选
@@ -2,17 +2,17 @@ import React from "react";
2
2
  import { Checkbox, Modal } from "antd";
3
3
  import _ from "lodash";
4
4
  import { MUtil } from "../../../framework/MUtil";
5
- import { BaseViewer } from '../../BaseViewer';
6
- import { MEnumField, MProp, ValueConst } from '../../../framework/Schema';
7
- import { MSetType } from '../../../types/MSetType';
5
+ import { BaseViewer } from "../../BaseViewer";
6
+ import { MEnumField, MProp, ValueConst } from "../../../framework/Schema";
7
+ import { MSetType } from "../../../types/MSetType";
8
8
  import { MFieldViewer } from "../../../framework/MFieldViewer";
9
9
  import { assembly } from "../../../framework/Assembly";
10
10
 
11
11
  function ACheckBoxLabel(field: MEnumField) {
12
12
  if (field.html) {
13
- return <div dangerouslySetInnerHTML={{ __html: field.html }} />
13
+ return <div dangerouslySetInnerHTML={{ __html: field.html }} />;
14
14
  } else {
15
- return field.label ?? field.value
15
+ return field.label ?? field.value;
16
16
  }
17
17
  }
18
18
 
@@ -31,47 +31,70 @@ export class ACheckBox extends BaseViewer {
31
31
  constructor(p: MProp) {
32
32
  super(p);
33
33
  this._enumFields = MUtil.option(this.props.schema);
34
- this._enumValues = this._enumFields.map(e => e.value);
34
+ this._enumValues = this._enumFields.map((e) => e.value);
35
35
 
36
36
  const openOpt = p.schema.openOption ?? p.schema.setOpen;
37
- if(openOpt) {
38
- this._inputBoxValue =
39
- _.first(_.difference(super.getValue(), this._enumValues)) ??
37
+ if (openOpt) {
38
+ this._inputBoxValue =
39
+ _.first(_.difference(super.getValue(), this._enumValues)) ??
40
40
  assembly.types[openOpt.type].createDefaultValue(assembly, openOpt);
41
41
  }
42
42
  }
43
43
 
44
44
  _createBr() {
45
- return this.props.schema.layoutHint == "h" ? undefined : <div key={MUtil.unique()} />;
45
+ return this.props.schema.layoutHint == "h" ? undefined : (
46
+ <div key={MUtil.unique()} />
47
+ );
46
48
  }
47
49
 
48
50
  element(ctx) {
49
- let data: any[] = super.getValue()
51
+ let data: any[] = super.getValue();
50
52
 
51
53
  const openIndex = MSetType.openValueIndex(this.props.schema, data);
52
54
  let checkboxs: any[] = this._enumFields.map((m: any, index) => {
53
- const isShow = MUtil.isShow(this.props.database, ctx.rootProps.schema?.objectFields, m.showIf)
55
+ const isShow = MUtil.isShow(
56
+ this.props.database,
57
+ ctx.rootProps.schema?.objectFields,
58
+ m.showIf
59
+ );
54
60
  if (!isShow) return null;
55
61
  return [
56
- <Checkbox key={index} disabled={this.props.disable} checked={_.includes(data, m.value)} onChange={(e) => {
57
- console.log(this.props.schema)
58
- console.log(data)
59
- const max = this.props.schema.max
60
- if (max > 0 && e.target.checked) {
61
- const len = data ? data.length : 0
62
- // 选择第 max + 1 项时,提示并组织
63
- if (len >= this.props.schema.max) {
64
- Modal.info({title: `此题最多只能选择 ${max} 项`, okText: '确认', icon: null, centered: true, cancelText: ''})
65
- return
62
+ <Checkbox
63
+ key={index}
64
+ disabled={this.props.disable}
65
+ checked={_.includes(data, m.value)}
66
+ onChange={(e) => {
67
+ console.log(this.props.schema);
68
+ console.log(data);
69
+ const max = this.props.schema.max;
70
+ if (max > 0 && e.target.checked) {
71
+ const len = data ? data.length : 0;
72
+ // 选择第 max + 1 项时,提示并组织
73
+ if (len >= this.props.schema.max) {
74
+ Modal.info({
75
+ title: `此题最多只能选择 ${max} 项`,
76
+ okText: "确认",
77
+ icon: null,
78
+ centered: true,
79
+ cancelText: "",
80
+ });
81
+ return;
82
+ }
66
83
  }
67
- }
68
- super.changeValue(MSetType.change(e.target.checked, m.value, data, this.props.schema))
69
- }}
70
- >
84
+ super.changeValue(
85
+ MSetType.change(
86
+ e.target.checked,
87
+ m.value,
88
+ data,
89
+ this.props.schema
90
+ )
91
+ );
92
+ }}
93
+ >
71
94
  {ACheckBoxLabel(m)}
72
95
  </Checkbox>,
73
- this._createBr()
74
- ]
96
+ this._createBr(),
97
+ ];
75
98
  });
76
99
 
77
100
  // 开放选项
@@ -82,31 +105,56 @@ export class ACheckBox extends BaseViewer {
82
105
  key="opened:"
83
106
  checked={openIndex >= 0}
84
107
  onChange={(e) => {
85
- if(e.target.checked) {
86
- super.changeValue(MSetType.change(true, this._inputBoxValue, data, this.props.schema))
108
+ if (e.target.checked) {
109
+ super.changeValue(
110
+ MSetType.change(
111
+ true,
112
+ this._inputBoxValue,
113
+ data,
114
+ this.props.schema
115
+ )
116
+ );
87
117
  } else {
88
- super.changeValue(MSetType.clearOpenValue(this.props.schema, data, false)) // 不能用MSetType.change,因为可能有多个开放值
118
+ super.changeValue(
119
+ MSetType.clearOpenValue(this.props.schema, data, false)
120
+ ); // 不能用MSetType.change,因为可能有多个开放值
89
121
  }
90
- }}>
91
- <span style={{ marginRight: "10px" }}>{this.props.schema.openOption.label ?? "其他"}</span>
92
- <MFieldViewer morph={this.props.morph} schema={this.props.schema.openOption} database={this} path="_inputBoxValue" afterChange={(path: string, str: any, final: boolean) => {
93
- const matchEnum = this._enumFields.find(e => e.value === str);
94
- if (matchEnum) { // 不能让用户输入某个枚举值
95
- this._inputBoxValue = "";
96
- _.remove(data, (e) => !this._enumValues.includes(e))
97
- if (!data.includes(str)) {
98
- data.push(str);
99
- }
100
- super.changeValueEx(data, true, final);
101
- } else {
102
- const idx = data.findIndex(v => !this._enumValues.includes(v));
103
- if (!_.isNil(idx)) {
104
- this._inputBoxValue = str;
105
- data[idx] = str;
106
- super.changeValueEx(data, false, final);
122
+ }}
123
+ >
124
+ <span style={{ marginRight: "10px" }}>
125
+ {this.props.schema.openOption.label ?? "其他"}
126
+ </span>
127
+ <MFieldViewer
128
+ morph={this.props.morph}
129
+ schema={this.props.schema.openOption}
130
+ database={this}
131
+ path="_inputBoxValue"
132
+ afterChange={(path: string, str: any, final: boolean) => {
133
+ const matchEnum = this._enumFields.find((e) => e.value === str);
134
+ if (matchEnum) {
135
+ // 不能让用户输入某个枚举值
136
+ this._inputBoxValue = "";
137
+ _.remove(data, (e) => !this._enumValues.includes(e));
138
+ if (!data.includes(str)) {
139
+ data.push(str);
140
+ }
141
+ super.changeValueEx(data, true, final);
142
+ } else {
143
+ const idx = data.findIndex(
144
+ (v) => !this._enumValues.includes(v)
145
+ );
146
+ if (!_.isNil(idx)) {
147
+ this._inputBoxValue = str;
148
+ data[idx] = str;
149
+ super.changeValueEx(data, false, final);
150
+ }
107
151
  }
108
- }
109
- }} parent={this.props.schema} forceValid={false} disable={openIndex < 0} style={{ width: "inherit" }} />
152
+ }}
153
+ parent={this.props.schema}
154
+ forceValid={false}
155
+ disable={openIndex < 0}
156
+ style={{ width: "inherit" }}
157
+ />
110
158
  </Checkbox>,
111
159
  this._createBr()
112
160
  );