@nokecy/qc-ui 1.1.81 → 1.1.83

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.
@@ -19,6 +19,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
19
19
  import React, { useReducer, useRef } from 'react';
20
20
  import { theme } from 'antd';
21
21
  import { useField, useFieldSchema, RecursionField, Observer, useExpressionScope } from '@formily/react';
22
+ import { untracked } from '@formily/reactive';
22
23
  import { isArr, lazyMerge } from '@formily/shared';
23
24
  import { Schema } from '@formily/json-schema';
24
25
  import ArrayBase from "./arrayBase";
@@ -297,6 +298,20 @@ var hasRequiredRule = function hasRequiredRule(rule) {
297
298
  return false;
298
299
  };
299
300
 
301
+ /**
302
+ * 数据字段是否挂了任何校验规则。
303
+ *
304
+ * 懒挂载的格子没有 Formily 字段,提交时 form.validate 碰不到它。必填规则能静态识别,
305
+ * 但「自定义 validator 函数里判空」「必填写在校验规则的其他形态里」识别不了——
306
+ * 这类列的空格子若不挂真控件,空值会绕过校验直接提交。故有校验规则的列,空格子按必填一样挂真控件。
307
+ * 有值的格子里不合格式的内容不在此列(要挂全部校验过的格子等于取消懒挂载)。@author nokecy
308
+ */
309
+ var hasValidatorRule = function hasValidatorRule(fieldSchema) {
310
+ var validator = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema['x-validator'];
311
+ if (validator == null || validator === '') return false;
312
+ return Array.isArray(validator) ? validator.length > 0 : true;
313
+ };
314
+
300
315
  /**
301
316
  * 数据字段是否必填(静态判定):字段上写了 required,或 x-validator 里带 required 规则。
302
317
  *
@@ -411,6 +426,28 @@ var LazyAgField = function LazyAgField(params) {
411
426
  };
412
427
  }();
413
428
 
429
+ /**
430
+ * 运行时设置的选项(field.setDataSource / setFieldState dataSource)。
431
+ *
432
+ * 只取本格自己的字段:点开过的格子字段还在,失焦卸回文本后仍按名称显示。
433
+ * 不借同列其他格的选项——选项常常按行不同(如标签类型跟随同行的打印功能),借来的选项会把值映射成别的名称,
434
+ * 比显示原编码更糟。从未点开过的格子没有字段,要显示名称请把选项写进 Schema(x-component-props.options)。
435
+ * 仅选项类组件且有值时才查;按精确地址取、放在 untracked 里,不让每个格子都订阅整张字段表。@author nokecy
436
+ */
437
+ var liveDataSource = function liveDataSource(liveValue) {
438
+ var _field$value$indexOf4, _field$value4, _field$value4$indexOf;
439
+ var form = field === null || field === void 0 ? void 0 : field.form;
440
+ // 只有用「选项映射」格式化器的列(Select 一族,或登记为同一格式化器的组件)才需要运行时选项
441
+ if (!form || !dataKey || isBlank(liveValue) || formatter !== getReadOnlyFormatter('Select')) return undefined;
442
+ var index = (_field$value$indexOf4 = field === null || field === void 0 || (_field$value4 = field.value) === null || _field$value4 === void 0 || (_field$value4$indexOf = _field$value4.indexOf) === null || _field$value4$indexOf === void 0 ? void 0 : _field$value4$indexOf.call(_field$value4, record)) !== null && _field$value$indexOf4 !== void 0 ? _field$value$indexOf4 : -1;
443
+ if (index < 0) return undefined;
444
+ var own = untracked(function () {
445
+ return form.query(field.path.concat(index).concat(dataKey)).take();
446
+ });
447
+ var source = own === null || own === void 0 ? void 0 : own.dataSource;
448
+ return Array.isArray(source) && source.length > 0 ? source : undefined;
449
+ };
450
+
414
451
  // Observer 让本格反应式跟随内层 Formily 字段值。
415
452
  // record 即 field.value[index] 的可观察对象;在 Observer 里按内层字段名直接读 record[dataKey]
416
453
  // (而非 AG-Grid 渲染时快照的 params.value)建立依赖后,onFieldValueChange/setValuesIn 程序化原地
@@ -443,10 +480,12 @@ var LazyAgField = function LazyAgField(params) {
443
480
  node: node
444
481
  }));
445
482
  }
446
- var text = formatter ? formatter(liveValue, {
483
+ var ctx = {
447
484
  columnProps: columnProps,
448
- fieldSchema: fieldSchema
449
- }) : liveValue == null ? '' : String(liveValue);
485
+ fieldSchema: fieldSchema,
486
+ dataSource: activated ? undefined : liveDataSource(liveValue)
487
+ };
488
+ var text = formatter ? formatter(liveValue, ctx) : liveValue == null ? '' : String(liveValue);
450
489
  // 纯文本占满单元格,点击交给 AG-Grid onCellClicked 激活;样式尽量贴近 Editable 只读态避免点开跳动
451
490
  // 只读态(readPretty/disabled/readOnly)的空格不出编辑提示,留空与只读快路径一致
452
491
  var pattern = text === '' ? resolveLazyCellPattern(field, record, dataKey, fieldSchema, scope) : undefined;
@@ -463,10 +502,7 @@ var LazyAgField = function LazyAgField(params) {
463
502
  }, resolveEmptyPlaceholder(fieldSchema));
464
503
  }
465
504
  // 登记了只读渲染器的组件(如带颜色的 Tag)按渲染器出内容,与组件自己的阅读态一致
466
- var shown = renderer && text !== '' ? renderer(liveValue, {
467
- columnProps: columnProps,
468
- fieldSchema: fieldSchema
469
- }) : text;
505
+ var shown = renderer && text !== '' ? renderer(liveValue, ctx) : text;
470
506
  return /*#__PURE__*/React.createElement("span", {
471
507
  className: "ag-array-table-lazy-text",
472
508
  style: {
@@ -644,6 +680,9 @@ var buildArrayTableColumns = function buildArrayTableColumns(dataSource, field,
644
680
  // 懒挂载会把它降成「是/否」纯文本(点击才挂出开关),用户会以为开关消失。故可编辑态强制 eager。
645
681
  // 只读态(下方 ① 路径)仍走「是/否」文本快路径不受影响。@author nokecy
646
682
  var isInlineToggle = component === 'Switch' || component === 'Checkbox';
683
+ // ArrayTableIndex 靠「挂载时 useEffect 调 onChange(index+1)」把行号写进数据字段(如工艺路线的 sort)。
684
+ // 懒挂载只出文本、不挂真组件,effect 永远不执行,新增行的行号字段就是空的,故强制 eager。@author nokecy
685
+ var isIndexWriter = component === 'ArrayTableIndex';
647
686
 
648
687
  // formatter 路径(只读快路径/懒挂载)经 AG-Grid params.value 取值,而 params.value 由 colDef.field(=name)驱动。
649
688
  // 但设计器生成的 schema 里 Column key 多为随机 designable-id 且无 dataIndex,真实数据键在内层字段 name 上,
@@ -710,7 +749,7 @@ var buildArrayTableColumns = function buildArrayTableColumns(dataSource, field,
710
749
  }
711
750
 
712
751
  // ② 可编辑懒挂载(排除单击直控的 Switch/Checkbox:须 eager 出真控件)
713
- if (!readOnly && formatter && !hasReactions && !forceEager && !isInlineToggle && canFastPath) {
752
+ if (!readOnly && formatter && !hasReactions && !forceEager && !isInlineToggle && !isIndexWriter && canFastPath) {
714
753
  return emit(_objectSpread(_objectSpread(_objectSpread({}, base), valueGetter ? {
715
754
  valueGetter: valueGetter
716
755
  } : {}), {}, {
@@ -725,7 +764,8 @@ var buildArrayTableColumns = function buildArrayTableColumns(dataSource, field,
725
764
  fieldSchema: dataField,
726
765
  lazyEditable: true,
727
766
  // 供 index.tsx 识别懒列(激活/导航用)
728
- required: isRequiredSchema(dataField) // 必填且为空的格必须挂真控件,见 LazyAgField
767
+ // 必填、或带校验规则且为空的格必须挂真控件,否则没有字段节点,提交时没人校验它,见 LazyAgField
768
+ required: isRequiredSchema(dataField) || hasValidatorRule(dataField)
729
769
  }
730
770
  }));
731
771
  }
@@ -753,4 +793,55 @@ var useAddition = function useAddition() {
753
793
  return addition;
754
794
  }, null);
755
795
  };
756
- export { isColumnComponent, useArrayTableSources, useArrayTableActions, buildArrayTableColumns, useAddition, LazyAgField, LazyReadOnlyText };
796
+ export { isColumnComponent, useArrayTableSources, useArrayTableActions, buildArrayTableColumns, useAddition, LazyAgField, LazyReadOnlyText };
797
+
798
+ /** 简单字段名(非路径、非解构),默认值回填只处理这一种 */
799
+ var SIMPLE_FIELD_NAME = /^[A-Za-z_$][\w$]*$/;
800
+ /**
801
+ * 收集懒挂载列上声明了 default 的字段。
802
+ *
803
+ * Formily 在字段创建时把 schema 的 default 写进值(值为空时)。懒挂载的格子不创建字段,
804
+ * 老记录里缺的列、代码直接 push 的行就拿不到默认值,保存时是 null。
805
+ * 表达式形态的默认值({{...}})要求值上下文,这里不处理。@author nokecy
806
+ */
807
+ export var collectLazyDefaults = function collectLazyDefaults(columns) {
808
+ return (columns !== null && columns !== void 0 ? columns : []).filter(function (col) {
809
+ var _col$cellRendererPara;
810
+ return col === null || col === void 0 || (_col$cellRendererPara = col.cellRendererParams) === null || _col$cellRendererPara === void 0 ? void 0 : _col$cellRendererPara.lazyEditable;
811
+ }).map(function (col) {
812
+ var _fieldSchema$name3;
813
+ var fieldSchema = col.cellRendererParams.fieldSchema;
814
+ return {
815
+ key: String((_fieldSchema$name3 = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.name) !== null && _fieldSchema$name3 !== void 0 ? _fieldSchema$name3 : col.field),
816
+ value: fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.default
817
+ };
818
+ }).filter(function (_ref7) {
819
+ var key = _ref7.key,
820
+ value = _ref7.value;
821
+ return SIMPLE_FIELD_NAME.test(key) && value !== undefined && value !== null && !(typeof value === 'string' && value.includes('{{'));
822
+ });
823
+ };
824
+
825
+ /**
826
+ * 给还没处理过的新增行补默认值:值为空(null/undefined)才写,每行只补一次——
827
+ * 用户之后把格子清空是有意的,不能再被填回去。已落库的行(带 id)不动。@author nokecy
828
+ */
829
+ export var applyLazyDefaults = function applyLazyDefaults(arrayField, defaults, handled) {
830
+ var rows = arrayField === null || arrayField === void 0 ? void 0 : arrayField.value;
831
+ var form = arrayField === null || arrayField === void 0 ? void 0 : arrayField.form;
832
+ if (!Array.isArray(rows) || !form || defaults.length === 0) return;
833
+ rows.forEach(function (row, index) {
834
+ if (row == null || _typeof(row) !== 'object' || handled.has(row)) return;
835
+ handled.add(row);
836
+ // 已落库的行(带 id)保持库里的样子:补默认值会让受控字段凭空出现「变更」,
837
+ // 已审批的数据保存时还会被要求填变更原因。只补新增行(按钮之外的途径推进来的行)。
838
+ if (row.id != null || row._id != null) return;
839
+ defaults.forEach(function (_ref8) {
840
+ var key = _ref8.key,
841
+ value = _ref8.value;
842
+ if (row[key] == null) {
843
+ form.setValuesIn(arrayField.path.concat(index).concat(key), _typeof(value) === 'object' ? JSON.parse(JSON.stringify(value)) : value);
844
+ }
845
+ });
846
+ });
847
+ };
@@ -1,10 +1,12 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { ArrayBase } from "../array-table/arrayBase";
3
3
  export default (function (props) {
4
- var onChange = props.onChange;
4
+ var onChange = props.onChange,
5
+ value = props.value;
5
6
  var index = ArrayBase.useIndex();
6
7
  useEffect(function () {
7
- onChange(index + 1);
8
- }, [index]);
8
+ // 行号变了、或字段值被外部覆盖/清空(如 setValues、重置)而不等于行号时,重新写入
9
+ if (value !== index + 1) onChange(index + 1);
10
+ }, [index, value]);
9
11
  return /*#__PURE__*/React.createElement("span", props, "#", index + 1, ".");
10
12
  });