@lingxiteam/ebe-utils 0.2.2 → 0.2.4

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.
@@ -79,6 +79,8 @@ const TypeCells: React.FC<CellProps> = (props) => {
79
79
  const { code, operator, value } = data;
80
80
 
81
81
  const toStringVal = (val: any) => `${val}`;
82
+ const toNumberVal = (val: any) =>
83
+ !isNaN(Number(val)) ? Number(val) : toStringVal(val);
82
84
 
83
85
  switch (operator) {
84
86
  case OPERATOR_EQUAL:
@@ -86,9 +88,10 @@ const TypeCells: React.FC<CellProps> = (props) => {
86
88
  case OPERATOR_NOT_EQUAL:
87
89
  return toStringVal(row[code]) !== toStringVal(value);
88
90
  case OPERATOR_GREATER_THAN:
89
- return row[code] > value;
91
+ // 优先转成数字类型比较大小
92
+ return toNumberVal(row[code]) > toNumberVal(value);
90
93
  case OPERATOR_LESS_THAN:
91
- return row[code] < value;
94
+ return toNumberVal(row[code]) < toNumberVal(value);
92
95
  case OPERATOR_INCLUDE:
93
96
  if (typeof row[code].includes === 'function') {
94
97
  return row[code].includes(value);
@@ -1,6 +1,7 @@
1
1
  import { LingxiForwardRef } from '@lingxiteam/types';
2
2
  import { Col, Form as AntdForm, Row } from 'antd';
3
3
  import type { FormLayout } from 'antd/lib/form/Form';
4
+ import classNames from 'classnames';
4
5
  import { isEqual } from 'lodash';
5
6
  import React, {
6
7
  Children,
@@ -146,6 +147,16 @@ export const FormChildren = (props: FormChildrenType) => {
146
147
  return colSpace as number;
147
148
  })();
148
149
 
150
+ useEffect(() => {
151
+ if (Number(rowSpace) >= 14) {
152
+ // 动态设置 CSS 变量
153
+ document.documentElement.style.setProperty(
154
+ '--explainHelp-Line-height',
155
+ `${Number(rowSpace)}px`,
156
+ );
157
+ }
158
+ }, []);
159
+
149
160
  /**
150
161
  * 布局子组件
151
162
  */
@@ -235,7 +246,10 @@ export const FormChildren = (props: FormChildrenType) => {
235
246
  return (
236
247
  <Row
237
248
  ref={formRef}
238
- className={Number(rowSpace) < 14 ? 'form-tips' : undefined}
249
+ className={classNames({
250
+ 'form-tips': Number(rowSpace) < 14,
251
+ 'explainHelp-line-height': Number(rowSpace) >= 14,
252
+ })}
239
253
  gutter={[compatColSpace, rowSpace as number]}
240
254
  >
241
255
  {layoutChildren()}
@@ -26,6 +26,8 @@ const validateCondition = (data: any, row: any) => {
26
26
  const { code, operator, value } = data;
27
27
 
28
28
  const toStringVal = (val: any) => `${val}`;
29
+ const toNumberVal = (val: any) =>
30
+ !isNaN(Number(val)) ? Number(val) : toStringVal(val);
29
31
 
30
32
  switch (operator) {
31
33
  case OPERATOR_EQUAL:
@@ -33,9 +35,10 @@ const validateCondition = (data: any, row: any) => {
33
35
  case OPERATOR_NOT_EQUAL:
34
36
  return toStringVal(row[code]) !== toStringVal(value);
35
37
  case OPERATOR_GREATER_THAN:
36
- return row[code] > value;
38
+ // 优先转成数字类型比较大小
39
+ return toNumberVal(row[code]) > toNumberVal(value);
37
40
  case OPERATOR_LESS_THAN:
38
- return row[code] < value;
41
+ return toNumberVal(row[code]) < toNumberVal(value);
39
42
  case OPERATOR_INCLUDE:
40
43
  if (typeof row[code].includes === 'function') {
41
44
  return row[code].includes(value);
@@ -11,7 +11,7 @@ const SingleBtn = (props: SingleBtnProps) => {
11
11
  onBtnClick,
12
12
  getLocale,
13
13
  actionsMap,
14
- setMorePopVisible,
14
+ hideMorePopover,
15
15
  BtnIcon,
16
16
  c,
17
17
  idx,
@@ -42,7 +42,7 @@ const SingleBtn = (props: SingleBtnProps) => {
42
42
  isPopover &&
43
43
  !(typeof c === 'string' ? c === 'delete' : c.type === 'delete')
44
44
  ) {
45
- setMorePopVisible(false);
45
+ hideMorePopover();
46
46
  }
47
47
  }}
48
48
  onDoubleClick={(e) => {
@@ -96,7 +96,7 @@ const SingleBtn = (props: SingleBtnProps) => {
96
96
  onConfirm={(e: any) => {
97
97
  onDeleteClick(e);
98
98
  if (isPopover) {
99
- setMorePopVisible(false);
99
+ hideMorePopover();
100
100
  }
101
101
  }}
102
102
  >
@@ -98,11 +98,37 @@ const OperationCell = (props: OperationCellProps) => {
98
98
  return BtnIcon;
99
99
  };
100
100
 
101
+ // 更多操作按钮气泡卡片
102
+ const onMorePopVisible = (vis: boolean, idx: number) => {
103
+ setMorePopVisible(vis);
104
+ if (fixedAction && tableRef?.current) {
105
+ const fixedActionEle =
106
+ tableRef.current?.querySelectorAll('.ued-table-actions')?.[idx]
107
+ ?.parentNode;
108
+ // 操作列固定时 此时fixedActionEle默认antd样式为 position: sticky;z-index: 2
109
+ // 由于气泡卡片挂在fixedActionEle里面导致被后面的列遮盖
110
+ if (fixedActionEle) {
111
+ if (timerRef.current) {
112
+ clearTimeout(timerRef.current);
113
+ }
114
+ if (!vis) {
115
+ // 防止卡片部分被遮盖再隐藏
116
+ timerRef.current = setTimeout(() => {
117
+ fixedActionEle.style.zIndex = 2;
118
+ timerRef.current = null;
119
+ }, 200);
120
+ return;
121
+ }
122
+ fixedActionEle.style.zIndex = 3;
123
+ }
124
+ }
125
+ };
126
+
101
127
  // 操作栏单个内置按钮
102
128
  const renderBuiltInSingleBtn = (
103
129
  c: any,
104
130
  row: any,
105
- rowIndex: number | null,
131
+ rowIndex: number,
106
132
  idx: number,
107
133
  defaultBtnList: any,
108
134
  isPopover = false,
@@ -145,7 +171,7 @@ const OperationCell = (props: OperationCellProps) => {
145
171
  <SingleBtn
146
172
  getLocale={getLocale}
147
173
  actionsMap={actionsMap}
148
- setMorePopVisible={setMorePopVisible}
174
+ hideMorePopover={() => onMorePopVisible(false, rowIndex)}
149
175
  BtnIcon={BtnIcon}
150
176
  c={c}
151
177
  idx={idx}
@@ -199,7 +225,7 @@ const OperationCell = (props: OperationCellProps) => {
199
225
  if (typeof onClick === 'function') {
200
226
  onClick(currentRowKey ? row[currentRowKey] : row, row, index);
201
227
  }
202
- setMorePopVisible(false);
228
+ onMorePopVisible(false, index);
203
229
  }}
204
230
  >
205
231
  <div className="ued-table-actions-extendBtn" style={buttonStyle}>
@@ -310,29 +336,7 @@ const OperationCell = (props: OperationCellProps) => {
310
336
  triggerNode?.parentNode as HTMLElement
311
337
  }
312
338
  onOpenChange={(vis: boolean) => {
313
- setMorePopVisible(vis);
314
- if (fixedAction && tableRef?.current) {
315
- const fixedActionEle =
316
- tableRef.current?.querySelectorAll(
317
- '.ued-table-actions',
318
- )?.[index]?.parentNode;
319
- // 操作列固定时 此时fixedActionEle默认antd样式为 position: sticky;z-index: 2
320
- // 由于气泡卡片挂在fixedActionEle里面导致被后面的列遮盖
321
- if (fixedActionEle) {
322
- if (timerRef.current) {
323
- clearTimeout(timerRef.current);
324
- }
325
- if (!vis) {
326
- // 防止卡片部分被遮盖再隐藏
327
- timerRef.current = setTimeout(() => {
328
- fixedActionEle.style.zIndex = 2;
329
- timerRef.current = null;
330
- }, 200);
331
- return;
332
- }
333
- fixedActionEle.style.zIndex = 3;
334
- }
335
- }
339
+ onMorePopVisible(vis, index);
336
340
  }}
337
341
  >
338
342
  <Button
@@ -28,7 +28,7 @@ export interface SingleBtnProps {
28
28
  onBtnClick: (e: any) => void;
29
29
  getLocale: LocaleFunction;
30
30
  actionsMap: any;
31
- setMorePopVisible: (vis: boolean) => void;
31
+ hideMorePopover: () => void;
32
32
  BtnIcon?: React.ReactElement;
33
33
  c: any;
34
34
  idx: number;
@@ -673,6 +673,7 @@ const MyTransfer = LingxiForwardRef<any, MyTransferProps>((props, ref) => {
673
673
  onSelect={(_, { node: { key } }) => {
674
674
  onItemSelect(key as string, !isChecked(checkedKeys, key));
675
675
  }}
676
+ disabled={disabled}
676
677
  />
677
678
  );
678
679
  }
@@ -113,6 +113,7 @@ export interface MyTreeProps {
113
113
  closeExpandedKey?: any;
114
114
  showLine?: any;
115
115
  getEngineApis: any;
116
+ nodeIconsType?: 'default' | 'forceDropdown';
116
117
  }
117
118
 
118
119
  // const prefixCls = 'tree';
@@ -141,6 +142,7 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
141
142
  onClickMenuItem,
142
143
  customRenderCode,
143
144
  getEngineApis,
145
+ nodeIconsType = 'default',
144
146
  ...resetProps
145
147
  } = props;
146
148
 
@@ -187,6 +189,8 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
187
189
 
188
190
  // 当前操作字段key
189
191
  const [editingKey, setEditingKey] = useState('');
192
+ // 强制菜单模式
193
+ const forceDrowdown = nodeIconsType === 'forceDropdown';
190
194
 
191
195
  useImperativeHandle(ref, () => ({
192
196
  get dataSource() {
@@ -626,7 +630,7 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
626
630
  c: Record<string, any>,
627
631
  icon: any,
628
632
  ) => {
629
- e.stopPropagation();
633
+ // e.stopPropagation();
630
634
 
631
635
  // 设置当前操作key
632
636
  setEditingKey(c.key);
@@ -654,7 +658,10 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
654
658
  dropdown?: boolean,
655
659
  ) => {
656
660
  return dropdown ? (
657
- <span onClick={(e) => onClickIcon(e, c, icon)}>
661
+ <span
662
+ className="ued-tree-icon-dropdown"
663
+ onClick={(e) => onClickIcon(e, c, icon)}
664
+ >
658
665
  {icon?.title || iconMap[icon]?.name}
659
666
  </span>
660
667
  ) : (
@@ -762,7 +769,7 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
762
769
  dropdown?: boolean,
763
770
  ) =>
764
771
  dropdown ? (
765
- <Menu>
772
+ <Menu onClick={(e) => e.domEvent.stopPropagation()}>
766
773
  {icons.map((icon) => (
767
774
  <Menu.Item key={icon?.type || icon}>
768
775
  {(icon?.type || icon) === 'delete'
@@ -877,7 +884,7 @@ const MyTree = LingxiForwardRef<any, MyTreeProps>((props, ref) => {
877
884
  }
878
885
  return true;
879
886
  });
880
- if (finalNodeIcons.length <= 3) {
887
+ if (finalNodeIcons.length <= 3 && !forceDrowdown) {
881
888
  iconsDom = (
882
889
  <div key={c.key} className="ued-tree-icons ued-tree-icons-normal">
883
890
  {renderIcons(c, finalNodeIcons)}
@@ -8,6 +8,10 @@
8
8
  .form-tips .@{form-prefix-cls}-item-with-help {
9
9
  margin-bottom: 14px;
10
10
  }
11
+
12
+ .explainHelp-line-height .@{form-item-prefix-cls}-explain {
13
+ line-height: var(--explainHelp-Line-height);
14
+ }
11
15
 
12
16
  .@{form-prefix-cls}-item {
13
17
  // height: 100%;
@@ -173,6 +173,12 @@
173
173
  color: fade(@text-color, 75%);
174
174
  font-size: @font-size-sm;
175
175
 
176
+ &-dropdown {
177
+ white-space: nowrap;
178
+ max-width: 240px;
179
+ overflow: hidden;
180
+ }
181
+
176
182
  > svg {
177
183
  fill: fade(@text-color, 75%);
178
184
  }
@@ -480,3 +480,11 @@ export const getLocalLocation = ({
480
480
  }
481
481
  });
482
482
  };
483
+
484
+ export const isTrue = (value: any) => {
485
+ return value == true || value === 'true';
486
+ };
487
+
488
+ export const isFalse = (value: any) => {
489
+ return value == false || value === 'false';
490
+ };
@@ -1,8 +1,18 @@
1
- import { updateNodeChildren } from './formUtils';
1
+ import { useContext } from 'react';
2
+ import { Context } from './Context/context';
3
+ import {
4
+ getAllForm,
5
+ getBoframerOwnForms,
6
+ getBOFramerOwnFormValues,
7
+ getFieldsValue,
8
+ getFormByCompId,
9
+ getOwnFormValues,
10
+ updateNodeChildren,
11
+ } from './formUtils';
2
12
 
3
13
  const toBool = (v: string | boolean, defaultValue?: any) => {
4
14
  let val = v;
5
- if ([null, undefined].includes(val as any) && defaultValue !== undefined) {
15
+ if ([null, undefined].includes(val) && defaultValue !== undefined) {
6
16
  val = defaultValue;
7
17
  }
8
18
 
@@ -25,6 +35,8 @@ export interface ToolsContext {
25
35
  }
26
36
 
27
37
  export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
38
+ const { refs: renderRefs } = useContext(Context);
39
+
28
40
  const { addToAwaitQueue } = context;
29
41
 
30
42
  const asyncGetValue = (id: string, stateName?: string) => {
@@ -195,6 +207,157 @@ export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
195
207
  }
196
208
  });
197
209
 
210
+ /**
211
+ * 获取当前表单值
212
+ */
213
+ const getFormValue = async (compId: string): Promise<any> => {
214
+ // 为了兼容动态渲染引擎,表单不存在 就返回空对象
215
+ if (!refs[compId]) return Promise.resolve({});
216
+
217
+ // 表单的情况 可能是循环容器
218
+ if (refs[compId].compName === 'Form') {
219
+ const forms = getFormByCompId(compId, refs);
220
+ return getFieldsValue(forms, (form) => {
221
+ return form?.getFieldsValue?.();
222
+ });
223
+ }
224
+
225
+ if (refs[compId].compName === 'BOFramer') {
226
+ return getBOFramerOwnFormValues(
227
+ {
228
+ refs,
229
+ renderRefs,
230
+ compId,
231
+ },
232
+ (form) => form?.getFieldsValue?.(),
233
+ );
234
+ }
235
+
236
+ return Promise.reject(
237
+ new Error('该组件不支持使用getFormValues获取表单数据'),
238
+ );
239
+ };
240
+
241
+ /**
242
+ * 验证并取值
243
+ * @param compId
244
+ */
245
+ const validateForm = async (compId: string): Promise<any> => {
246
+ // 为了兼容动态渲染引擎,表单不存在 就返回空对象
247
+ if (!refs[compId]) return Promise.resolve({});
248
+
249
+ // 表单的情况 可能是循环容器
250
+ if (refs[compId].compName === 'Form') {
251
+ const forms = getFormByCompId(compId, refs);
252
+ return getFieldsValue(forms, (form) => {
253
+ return form?.validateFormAndScroll?.();
254
+ });
255
+ }
256
+
257
+ if (refs[compId].compName === 'BOFramer') {
258
+ return getBOFramerOwnFormValues(
259
+ {
260
+ refs,
261
+ renderRefs,
262
+ compId,
263
+ },
264
+ (form) => form?.validateFormAndScroll?.(),
265
+ );
266
+ }
267
+ return Promise.reject(
268
+ new Error('该组件不支持使用getFormValues获取表单数据'),
269
+ );
270
+ };
271
+
272
+ /**
273
+ * 重置表单值
274
+ * @param compId
275
+ */
276
+ const resetForm = (compId: string) => {
277
+ if (!refs[compId]) return;
278
+ const compName = refs[compId].compName;
279
+ if (compName === 'BOFramer') {
280
+ const forms = getBoframerOwnForms({
281
+ currentRefs: refs,
282
+ renderRefs,
283
+ compId,
284
+ });
285
+
286
+ forms.forEach((form) => {
287
+ form?.resetFields?.();
288
+ });
289
+ } else {
290
+ const forms = getFormByCompId(compId, refs);
291
+ // 支持循环容器中的表单重置
292
+ (Array.isArray(forms) ? forms : [forms]).forEach((form) =>
293
+ form?.resetFields(),
294
+ );
295
+ }
296
+ };
297
+
298
+ /**
299
+ * 设置表单值
300
+ * @param compId 组件id
301
+ * @param formValues 表单值
302
+ */
303
+ const setFormValues = (
304
+ compId: string,
305
+ formValues: Record<string, any> = {},
306
+ ) => {
307
+ if (!refs[compId]) return;
308
+ const compName = refs[compId].compName;
309
+
310
+ if (compName === 'BOFramer') {
311
+ const forms = getBoframerOwnForms({
312
+ currentRefs: refs,
313
+ renderRefs,
314
+ compId,
315
+ });
316
+
317
+ forms.forEach((form) => {
318
+ form?.setFieldsValue(formValues);
319
+ });
320
+ } else {
321
+ refs[compId]?.setFieldsValue?.(formValues);
322
+ }
323
+ };
324
+
325
+ /**
326
+ * 校验并获取所有表单值
327
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
328
+ * 不包含所有弹窗类组件的表单数据
329
+ */
330
+ const validateAllForm = () =>
331
+ getOwnFormValues({ currentRefs: refs, renderRefs }, (form) =>
332
+ form.validateFormAndScroll?.(false),
333
+ );
334
+
335
+ /**
336
+ * 获取所有表单值 但不校验
337
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
338
+ * 不包含所有弹窗类组件的表单数据
339
+ */
340
+ const getAllFormValues = () =>
341
+ getOwnFormValues({ currentRefs: refs, renderRefs }, (form) =>
342
+ form.getFieldsValue?.(),
343
+ );
344
+
345
+ /**
346
+ * 重置所有表单
347
+ * 获取页面下的所有表单,包含当前页面下的表单、页面容器下的表单、业务组件下的表单。
348
+ * 不包含所有弹窗类组件的表单数据
349
+ */
350
+ const resetAllForm = () => {
351
+ const forms = getAllForm({
352
+ currentRefs: refs,
353
+ renderRefs,
354
+ });
355
+
356
+ forms.forEach((form) => {
357
+ form.resetFields();
358
+ });
359
+ };
360
+
198
361
  /**
199
362
  * 获取联动数据值
200
363
  * @param attrDataMap 静态数据
@@ -250,8 +413,15 @@ export const useTool = (refs: Record<string, any>, context: ToolsContext) => {
250
413
  callComponentMethod,
251
414
  setDisabled,
252
415
  getDisabled,
416
+ getFormValue,
417
+ validateForm,
418
+ resetForm,
253
419
  clearValue,
420
+ setFormValues,
254
421
  asyncCallComponentMethod,
422
+ validateAllForm,
423
+ getAllFormValues,
424
+ resetAllForm,
255
425
  updateNodeChildren,
256
426
  getTriggerRelDataSource,
257
427
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingxiteam/ebe-utils",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "author": "",
@@ -17,9 +17,9 @@
17
17
  "@babel/parser": "^7.12.12",
18
18
  "@babel/traverse": "^7.12.12",
19
19
  "@babel/types": "^7.12.12",
20
- "@lingxiteam/ebe": "0.2.2",
21
20
  "cac": "^6.7.14",
22
- "fs-extra": "9.x"
21
+ "fs-extra": "9.x",
22
+ "@lingxiteam/ebe": "0.2.4"
23
23
  },
24
24
  "publishConfig": {
25
25
  "access": "public"
@@ -1,43 +0,0 @@
1
- .cust-icon-ed {
2
- width: 16px;
3
- height: 16px;
4
- font-size: 16px;
5
- svg {
6
- width: 1em;
7
- height: 1em;
8
- }
9
- }
10
- .cust-icon-theme {
11
- fill: var(--adm-color-primary);
12
- color: var(--adm-color-primary);
13
- }
14
-
15
- .cust-icon-ed-xxs {
16
- width: 12px;
17
- height: 12px;
18
- font-size: 12px;
19
- }
20
-
21
- .cust-icon-ed-xs {
22
- width: 16px;
23
- height: 16px;
24
- font-size: 16px;
25
- }
26
-
27
- .cust-icon-ed-sm {
28
- width: 20px;
29
- height: 20px;
30
- font-size: 20px;
31
- }
32
-
33
- .cust-icon-ed-md {
34
- width: 24px;
35
- height: 24px;
36
- font-size: 24px;
37
- }
38
-
39
- .cust-icon-ed-lg {
40
- width: 36px;
41
- height: 36px;
42
- font-size: 36px;
43
- }