@nokecy/qc-ui 1.1.87 → 1.1.88
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.
- package/dist/cjs/ag-grid-plus/ag-gridPlus.js +148 -144
- package/dist/cjs/ag-grid-plus/context/useSchemeDataFlow.js +4 -4
- package/dist/cjs/ag-grid-plus/interface.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/queryForm/index.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/queryForm/index.js +47 -51
- package/dist/cjs/ag-grid-plus/queryForm/queryColumns.d.ts +8 -0
- package/dist/cjs/ag-grid-plus/queryForm/queryColumns.js +52 -0
- package/dist/cjs/ag-grid-plus/queryForm/schemaKey.d.ts +15 -8
- package/dist/cjs/ag-grid-plus/queryForm/schemaKey.js +64 -12
- package/dist/cjs/ag-grid-plus/setting/ColumnConfigForm.js +3 -0
- package/dist/cjs/ag-grid-plus/setting/ColumnSetting.js +69 -106
- package/dist/cjs/ag-grid-plus/setting/QuerySchemeManager.js +3 -1
- package/dist/cjs/ag-grid-plus/setting/columnGroupTypes.d.ts +2 -0
- package/dist/cjs/ag-grid-plus/setting/columnGroupUtils.d.ts +14 -0
- package/dist/cjs/ag-grid-plus/setting/columnGroupUtils.js +98 -110
- package/dist/cjs/ag-grid-plus/types.d.ts +6 -0
- package/dist/cjs/array-table/batchRemove.d.ts +36 -0
- package/dist/cjs/array-table/batchRemove.js +299 -0
- package/dist/cjs/array-table/cellFocusScope.js +44 -8
- package/dist/cjs/array-table/cellInteractionLock.d.ts +13 -0
- package/dist/cjs/array-table/cellInteractionLock.js +26 -0
- package/dist/cjs/array-table/hooks.d.ts +11 -6
- package/dist/cjs/array-table/hooks.js +138 -88
- package/dist/cjs/array-table/index.d.ts +8 -2
- package/dist/cjs/array-table/index.js +55 -32
- package/dist/cjs/array-table/indexColumn.d.ts +1 -1
- package/dist/cjs/array-table/indexColumn.js +3 -2
- package/dist/cjs/array-table/interface.d.ts +13 -1
- package/dist/cjs/array-table/preview.js +8 -0
- package/dist/cjs/array-table/readOnlyFormatters.d.ts +9 -1
- package/dist/cjs/array-table/readOnlyFormatters.js +41 -13
- package/dist/cjs/array-table/rowIdentity.d.ts +17 -0
- package/dist/cjs/array-table/rowIdentity.js +43 -0
- package/dist/cjs/array-table/sorting.d.ts +3 -0
- package/dist/cjs/array-table/sorting.js +46 -0
- package/dist/cjs/array-table/utils.js +146 -67
- package/dist/cjs/dialogSelect/index.d.ts +3 -0
- package/dist/cjs/dialogSelect/index.js +13 -3
- package/dist/cjs/editable/index.js +101 -139
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +14 -0
- package/dist/cjs/readPretty/arrayTable.js +29 -14
- package/dist/cjs/readPretty/formily.d.ts +1 -0
- package/dist/cjs/readPretty/formily.js +7 -0
- package/dist/cjs/readPretty/index.d.ts +1 -0
- package/dist/cjs/readPretty/index.js +7 -0
- package/dist/cjs/readPretty/schemaScope.d.ts +2 -0
- package/dist/cjs/readPretty/schemaScope.js +49 -0
- package/dist/esm/ag-grid-plus/ag-gridPlus.js +148 -144
- package/dist/esm/ag-grid-plus/context/useSchemeDataFlow.js +4 -4
- package/dist/esm/ag-grid-plus/interface.d.ts +2 -0
- package/dist/esm/ag-grid-plus/queryForm/index.d.ts +2 -0
- package/dist/esm/ag-grid-plus/queryForm/index.js +47 -52
- package/dist/esm/ag-grid-plus/queryForm/queryColumns.d.ts +8 -0
- package/dist/esm/ag-grid-plus/queryForm/queryColumns.js +46 -0
- package/dist/esm/ag-grid-plus/queryForm/schemaKey.d.ts +15 -8
- package/dist/esm/ag-grid-plus/queryForm/schemaKey.js +64 -12
- package/dist/esm/ag-grid-plus/setting/ColumnConfigForm.js +3 -0
- package/dist/esm/ag-grid-plus/setting/ColumnSetting.js +70 -107
- package/dist/esm/ag-grid-plus/setting/QuerySchemeManager.js +3 -1
- package/dist/esm/ag-grid-plus/setting/columnGroupTypes.d.ts +2 -0
- package/dist/esm/ag-grid-plus/setting/columnGroupUtils.d.ts +14 -0
- package/dist/esm/ag-grid-plus/setting/columnGroupUtils.js +95 -110
- package/dist/esm/ag-grid-plus/types.d.ts +6 -0
- package/dist/esm/array-table/batchRemove.d.ts +36 -0
- package/dist/esm/array-table/batchRemove.js +289 -0
- package/dist/esm/array-table/cellFocusScope.js +45 -9
- package/dist/esm/array-table/cellInteractionLock.d.ts +13 -0
- package/dist/esm/array-table/cellInteractionLock.js +21 -0
- package/dist/esm/array-table/hooks.d.ts +11 -6
- package/dist/esm/array-table/hooks.js +139 -89
- package/dist/esm/array-table/index.d.ts +8 -2
- package/dist/esm/array-table/index.js +55 -32
- package/dist/esm/array-table/indexColumn.d.ts +1 -1
- package/dist/esm/array-table/indexColumn.js +3 -2
- package/dist/esm/array-table/interface.d.ts +13 -1
- package/dist/esm/array-table/preview.js +8 -0
- package/dist/esm/array-table/readOnlyFormatters.d.ts +9 -1
- package/dist/esm/array-table/readOnlyFormatters.js +41 -12
- package/dist/esm/array-table/rowIdentity.d.ts +17 -0
- package/dist/esm/array-table/rowIdentity.js +37 -0
- package/dist/esm/array-table/sorting.d.ts +3 -0
- package/dist/esm/array-table/sorting.js +40 -0
- package/dist/esm/array-table/utils.js +147 -68
- package/dist/esm/dialogSelect/index.d.ts +3 -0
- package/dist/esm/dialogSelect/index.js +13 -3
- package/dist/esm/editable/index.js +102 -140
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/readPretty/arrayTable.js +30 -13
- package/dist/esm/readPretty/formily.d.ts +1 -0
- package/dist/esm/readPretty/formily.js +1 -0
- package/dist/esm/readPretty/index.d.ts +1 -0
- package/dist/esm/readPretty/index.js +1 -0
- package/dist/esm/readPretty/schemaScope.d.ts +2 -0
- package/dist/esm/readPretty/schemaScope.js +42 -0
- package/dist/umd/qc-ui.min.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
5
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
6
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
7
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
8
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
9
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
11
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
12
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
13
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
14
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
15
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
16
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
17
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
18
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
19
|
+
import { Button, Modal, Space } from 'antd';
|
|
20
|
+
import { DeleteOutlined } from '@ant-design/icons';
|
|
21
|
+
import { batch } from '@formily/reactive';
|
|
22
|
+
|
|
23
|
+
/** 标准删除控件在行内的字段路径与静态约束。@author nokecy */
|
|
24
|
+
|
|
25
|
+
/** 收集标准删除入口,保留列级显隐约束,不把其他业务按钮当成删除。@author nokecy */
|
|
26
|
+
export function collectRemovalActions(sources) {
|
|
27
|
+
var actions = [];
|
|
28
|
+
var _iterator = _createForOfIteratorHelper(sources),
|
|
29
|
+
_step;
|
|
30
|
+
try {
|
|
31
|
+
var _loop = function _loop() {
|
|
32
|
+
var column = _step.value;
|
|
33
|
+
if (column.display && column.display !== 'visible') return 1; // continue
|
|
34
|
+
var visit = function visit(schema, path, ancestors) {
|
|
35
|
+
if (!schema) return;
|
|
36
|
+
var schemas = [].concat(_toConsumableArray(ancestors), [schema]);
|
|
37
|
+
if (typeof schema['x-component'] === 'string' && /^(?:ArrayTable|ArrayBase)\.Remove$/.test(schema['x-component'])) {
|
|
38
|
+
actions.push({
|
|
39
|
+
path: path,
|
|
40
|
+
schemas: schemas,
|
|
41
|
+
column: column
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
Object.entries(schema.properties || {}).forEach(function (_ref) {
|
|
46
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
47
|
+
key = _ref2[0],
|
|
48
|
+
child = _ref2[1];
|
|
49
|
+
return visit(child, [].concat(_toConsumableArray(path), [key]), schemas);
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
// 列本身不进入行地址;AgField 使用 onlyRenderProperties 挂载列内字段。
|
|
53
|
+
Object.entries(column.schema.properties || {}).forEach(function (_ref3) {
|
|
54
|
+
var _ref4 = _slicedToArray(_ref3, 2),
|
|
55
|
+
key = _ref4[0],
|
|
56
|
+
child = _ref4[1];
|
|
57
|
+
return visit(child, [key], []);
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
61
|
+
if (_loop()) continue;
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
_iterator.e(err);
|
|
65
|
+
} finally {
|
|
66
|
+
_iterator.f();
|
|
67
|
+
}
|
|
68
|
+
return actions;
|
|
69
|
+
}
|
|
70
|
+
var permitsRemoval = function permitsRemoval(field) {
|
|
71
|
+
var _field$componentProps, _field$componentProps2;
|
|
72
|
+
return !field || field.display === 'visible' && field.pattern === 'editable' && !field.disabled && ((_field$componentProps = field.componentProps) === null || _field$componentProps === void 0 ? void 0 : _field$componentProps.disabled) !== true && ((_field$componentProps2 = field.componentProps) === null || _field$componentProps2 === void 0 ? void 0 : _field$componentProps2.readOnly) !== true;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* 与行内删除共用字段的运行时权限;未挂载的普通行采用静态规则。
|
|
77
|
+
* 含动态权限且尚未求值的行保持不可删除,避免绕过业务禁用条件。@author nokecy
|
|
78
|
+
*/
|
|
79
|
+
export function findRemovalAction(field, index, actions) {
|
|
80
|
+
if (field.pattern !== 'editable' || field.disabled || !Array.isArray(field.value) || !field.value[index]) return;
|
|
81
|
+
return actions.find(function (action) {
|
|
82
|
+
if (!permitsRemoval(action.column.field)) return false;
|
|
83
|
+
if (action.column.schema['x-visible'] === false || action.column.schema['x-hidden'] === true) return false;
|
|
84
|
+
var _loop2 = function _loop2() {
|
|
85
|
+
var schema = action.schemas[depth];
|
|
86
|
+
var runtime = field.query(field.address.concat(index).concat(action.path.slice(0, depth + 1))).take();
|
|
87
|
+
if (runtime) {
|
|
88
|
+
if (!permitsRemoval(runtime)) return {
|
|
89
|
+
v: false
|
|
90
|
+
};
|
|
91
|
+
} else {
|
|
92
|
+
var _schema$xComponentP, _schema$xComponentP2;
|
|
93
|
+
if (schema['x-visible'] === false || schema['x-hidden'] === true || schema['x-display'] && schema['x-display'] !== 'visible' || schema['x-pattern'] && schema['x-pattern'] !== 'editable' || schema['x-disabled'] === true || schema['x-read-only'] === true || (_schema$xComponentP = schema['x-component-props']) !== null && _schema$xComponentP !== void 0 && _schema$xComponentP.disabled || (_schema$xComponentP2 = schema['x-component-props']) !== null && _schema$xComponentP2 !== void 0 && _schema$xComponentP2.readOnly || schema['x-reactions'] || ['x-visible', 'x-hidden', 'x-disabled', 'x-read-only'].some(function (key) {
|
|
94
|
+
return typeof schema[key] === 'string';
|
|
95
|
+
})) return {
|
|
96
|
+
v: false
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
_ret;
|
|
101
|
+
for (var depth = 0; depth < action.path.length; depth++) {
|
|
102
|
+
_ret = _loop2();
|
|
103
|
+
if (_ret) return _ret.v;
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 把选择时的稳定行标识转换为当前表单索引;确认前全部复核,倒序删除保持数组地址正确。
|
|
111
|
+
* 返回 false 表示所选行已删除或变为不可删除,整个批次不执行。@author nokecy
|
|
112
|
+
*/
|
|
113
|
+
export function removeSelectedRows(field, ids, actions, getId, onRemove, event) {
|
|
114
|
+
var rows = Array.isArray(field.value) ? field.value : [];
|
|
115
|
+
var indices = new Map(rows.map(function (row, index) {
|
|
116
|
+
return [getId(row), index];
|
|
117
|
+
}));
|
|
118
|
+
var targets = Array.from(new Set(ids)).map(function (id) {
|
|
119
|
+
var _indices$get;
|
|
120
|
+
var index = (_indices$get = indices.get(id)) !== null && _indices$get !== void 0 ? _indices$get : -1;
|
|
121
|
+
return {
|
|
122
|
+
index: index,
|
|
123
|
+
action: index < 0 ? undefined : findRemovalAction(field, index, actions)
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
if (!targets.length || targets.some(function (target) {
|
|
127
|
+
return !target.action;
|
|
128
|
+
})) return false;
|
|
129
|
+
// 先固定已求值的回调,数组删除会让后续字段索引迁移。
|
|
130
|
+
var removals = targets.sort(function (a, b) {
|
|
131
|
+
return b.index - a.index;
|
|
132
|
+
}).map(function (_ref5) {
|
|
133
|
+
var _field$query$take$com, _field$query$take, _schemas$xComponent;
|
|
134
|
+
var index = _ref5.index,
|
|
135
|
+
action = _ref5.action;
|
|
136
|
+
return {
|
|
137
|
+
index: index,
|
|
138
|
+
onClick: (_field$query$take$com = (_field$query$take = field.query(field.address.concat(index).concat(action.path)).take()) === null || _field$query$take === void 0 || (_field$query$take = _field$query$take.componentProps) === null || _field$query$take === void 0 ? void 0 : _field$query$take.onClick) !== null && _field$query$take$com !== void 0 ? _field$query$take$com : (_schemas$xComponent = action.schemas[action.schemas.length - 1]['x-component-props']) === null || _schemas$xComponent === void 0 ? void 0 : _schemas$xComponent.onClick
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
batch(function () {
|
|
142
|
+
return removals.forEach(function (_ref6) {
|
|
143
|
+
var index = _ref6.index,
|
|
144
|
+
onClick = _ref6.onClick;
|
|
145
|
+
field.remove(index);
|
|
146
|
+
onRemove === null || onRemove === void 0 || onRemove(index);
|
|
147
|
+
if (typeof onClick === 'function') onClick(event);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** 公共明细表格的勾选及批量删除,沿用业务行权限、行标识与删除通知。@author nokecy */
|
|
154
|
+
export function useArrayTableBatchRemove(field, sources, props, apiRef, getId) {
|
|
155
|
+
var _useState = useState(0),
|
|
156
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
157
|
+
selectedCount = _useState2[0],
|
|
158
|
+
setSelectedCount = _useState2[1];
|
|
159
|
+
var _Modal$useModal = Modal.useModal(),
|
|
160
|
+
_Modal$useModal2 = _slicedToArray(_Modal$useModal, 2),
|
|
161
|
+
modal = _Modal$useModal2[0],
|
|
162
|
+
contextHolder = _Modal$useModal2[1];
|
|
163
|
+
var actions = collectRemovalActions(sources);
|
|
164
|
+
var enabled = props.batchRemove !== false && !props.disabled && field.pattern === 'editable' && !field.disabled && actions.length > 0;
|
|
165
|
+
var indices = new Map((field.value || []).map(function (row, index) {
|
|
166
|
+
return [getId(row), index];
|
|
167
|
+
}));
|
|
168
|
+
var removableIds = new Set(Array.from(indices).filter(function (_ref7) {
|
|
169
|
+
var _ref8 = _slicedToArray(_ref7, 2),
|
|
170
|
+
index = _ref8[1];
|
|
171
|
+
return !!findRemovalAction(field, index, actions);
|
|
172
|
+
}).map(function (_ref9) {
|
|
173
|
+
var _ref10 = _slicedToArray(_ref9, 1),
|
|
174
|
+
id = _ref10[0];
|
|
175
|
+
return id;
|
|
176
|
+
}));
|
|
177
|
+
var eligibilityKey = JSON.stringify(Array.from(removableIds));
|
|
178
|
+
var canRemove = function canRemove(node) {
|
|
179
|
+
if (node.rowPinned || !node.data) return false;
|
|
180
|
+
return removableIds.has(getId(node.data));
|
|
181
|
+
};
|
|
182
|
+
var businessSelectable = _typeof(props.rowSelection) === 'object' ? props.rowSelection.isRowSelectable : undefined;
|
|
183
|
+
var latest = React.useRef({
|
|
184
|
+
actions: actions,
|
|
185
|
+
enabled: enabled,
|
|
186
|
+
canRemove: canRemove,
|
|
187
|
+
onRemove: props.onRemove,
|
|
188
|
+
businessSelectable: businessSelectable
|
|
189
|
+
});
|
|
190
|
+
latest.current = {
|
|
191
|
+
actions: actions,
|
|
192
|
+
enabled: enabled,
|
|
193
|
+
canRemove: canRemove,
|
|
194
|
+
onRemove: props.onRemove,
|
|
195
|
+
businessSelectable: businessSelectable
|
|
196
|
+
};
|
|
197
|
+
var rowSelection = useMemo(function () {
|
|
198
|
+
var _configured$mode;
|
|
199
|
+
if (!enabled) return props.rowSelection;
|
|
200
|
+
var configured = _typeof(props.rowSelection) === 'object' ? props.rowSelection : undefined;
|
|
201
|
+
var businessSelectable = configured === null || configured === void 0 ? void 0 : configured.isRowSelectable;
|
|
202
|
+
var multiple = ((_configured$mode = configured === null || configured === void 0 ? void 0 : configured.mode) !== null && _configured$mode !== void 0 ? _configured$mode : props.rowSelection === 'single' ? 'singleRow' : 'multiRow') === 'multiRow';
|
|
203
|
+
return _objectSpread(_objectSpread(_objectSpread({
|
|
204
|
+
mode: multiple ? 'multiRow' : 'singleRow',
|
|
205
|
+
checkboxes: true,
|
|
206
|
+
enableClickSelection: false
|
|
207
|
+
}, multiple ? {
|
|
208
|
+
headerCheckbox: true,
|
|
209
|
+
selectAll: 'filtered'
|
|
210
|
+
} : {}), configured), {}, {
|
|
211
|
+
isRowSelectable: function isRowSelectable(node) {
|
|
212
|
+
return latest.current.canRemove(node) && (!businessSelectable || businessSelectable(node));
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}, [enabled, props.rowSelection, eligibilityKey]);
|
|
216
|
+
var syncSelection = function syncSelection(api) {
|
|
217
|
+
return setSelectedCount(api.getSelectedNodes().filter(function (node) {
|
|
218
|
+
return latest.current.canRemove(node);
|
|
219
|
+
}).length);
|
|
220
|
+
};
|
|
221
|
+
useEffect(function () {
|
|
222
|
+
var api = apiRef.current;
|
|
223
|
+
if (api && !api.isDestroyed() && enabled) {
|
|
224
|
+
syncSelection(api);
|
|
225
|
+
}
|
|
226
|
+
}, [enabled, rowSelection]);
|
|
227
|
+
var confirmRemove = function confirmRemove(event) {
|
|
228
|
+
var api = apiRef.current;
|
|
229
|
+
if (!api || !latest.current.enabled) return;
|
|
230
|
+
var ids = api.getSelectedNodes().filter(function (node) {
|
|
231
|
+
return latest.current.canRemove(node);
|
|
232
|
+
}).map(function (node) {
|
|
233
|
+
return getId(node.data);
|
|
234
|
+
});
|
|
235
|
+
if (!ids.length) return;
|
|
236
|
+
modal.confirm({
|
|
237
|
+
title: '确认批量删除明细',
|
|
238
|
+
content: "\u5C06\u4ECE\u5F53\u524D\u8868\u5355\u79FB\u9664\u9009\u4E2D\u7684 ".concat(ids.length, " \u6761\u660E\u7EC6\uFF0C\u4FDD\u5B58\u540E\u4E0D\u53EF\u6062\u590D\u3002\u662F\u5426\u5220\u9664\uFF1F"),
|
|
239
|
+
okText: '删除',
|
|
240
|
+
okButtonProps: {
|
|
241
|
+
danger: true
|
|
242
|
+
},
|
|
243
|
+
onOk: function onOk() {
|
|
244
|
+
var current = latest.current;
|
|
245
|
+
if (api.isDestroyed()) return;
|
|
246
|
+
var stillSelectable = ids.every(function (id) {
|
|
247
|
+
var node = api.getRowNode(id);
|
|
248
|
+
return node && current.canRemove(node) && (!current.businessSelectable || current.businessSelectable(node));
|
|
249
|
+
});
|
|
250
|
+
if (!current.enabled || !stillSelectable || !removeSelectedRows(field, ids, current.actions, getId, current.onRemove, event)) {
|
|
251
|
+
modal.warning({
|
|
252
|
+
title: '明细已发生变化',
|
|
253
|
+
content: '部分明细已删除或不可删除,请重新选择后操作。'
|
|
254
|
+
});
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (!api.isDestroyed()) api.deselectAll();
|
|
258
|
+
setSelectedCount(0);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
return {
|
|
263
|
+
rowSelection: rowSelection,
|
|
264
|
+
selectionColumnDef: enabled ? _objectSpread({
|
|
265
|
+
pinned: 'left',
|
|
266
|
+
lockPosition: true,
|
|
267
|
+
width: 46,
|
|
268
|
+
resizable: false,
|
|
269
|
+
suppressHeaderMenuButton: true
|
|
270
|
+
}, props.selectionColumnDef) : props.selectionColumnDef,
|
|
271
|
+
onSelectionChanged: function onSelectionChanged(event) {
|
|
272
|
+
var _props$onSelectionCha;
|
|
273
|
+
syncSelection(event.api);
|
|
274
|
+
(_props$onSelectionCha = props.onSelectionChanged) === null || _props$onSelectionCha === void 0 || _props$onSelectionCha.call(props, event);
|
|
275
|
+
},
|
|
276
|
+
toolbar: /*#__PURE__*/React.createElement(React.Fragment, null, contextHolder, enabled && /*#__PURE__*/React.createElement(Space, null, selectedCount > 0 && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", null, "\u5DF2\u9009 ", selectedCount, " \u9879"), /*#__PURE__*/React.createElement(Button, {
|
|
277
|
+
type: "link",
|
|
278
|
+
onClick: function onClick() {
|
|
279
|
+
var _apiRef$current;
|
|
280
|
+
return (_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 ? void 0 : _apiRef$current.deselectAll();
|
|
281
|
+
}
|
|
282
|
+
}, "\u53D6\u6D88\u9009\u62E9")), /*#__PURE__*/React.createElement(Button, {
|
|
283
|
+
danger: true,
|
|
284
|
+
icon: /*#__PURE__*/React.createElement(DeleteOutlined, null),
|
|
285
|
+
disabled: !selectedCount,
|
|
286
|
+
onClick: confirmRemove
|
|
287
|
+
}, "\u6279\u91CF\u5220\u9664")))
|
|
288
|
+
};
|
|
289
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef } from 'react';
|
|
1
|
+
import React, { useCallback, useContext, useEffect, useRef } from 'react';
|
|
2
|
+
import { CellInteractionLockContext } from "./cellInteractionLock";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* 判断「焦点离开了这个单元格」的作用域,给懒挂载格「用完卸回纯文本」用。
|
|
@@ -22,10 +23,13 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
22
23
|
children = _ref.children;
|
|
23
24
|
var rootRef = useRef(null);
|
|
24
25
|
var timerRef = useRef();
|
|
26
|
+
var dateTimerRef = useRef();
|
|
27
|
+
var acquireParentInteractionLock = useContext(CellInteractionLockContext);
|
|
25
28
|
// 通过 React portal 渲染到 body 的弹层仍属于当前格;记录经过本作用域的指针事件,
|
|
26
29
|
// 避免日期/下拉弹层中的点击被 document 级离开检测误判。@author nokecy
|
|
27
30
|
var pointerEventsInScopeRef = useRef(new WeakSet());
|
|
28
31
|
var focusWithinRef = useRef(false);
|
|
32
|
+
var interactionLocksRef = useRef(new Set());
|
|
29
33
|
// 每次焦点回到格内、或卸载时递增;进行中的异步判定拿它判断自己是否已过期
|
|
30
34
|
var generationRef = useRef(0);
|
|
31
35
|
var onLeaveRef = useRef(onLeave);
|
|
@@ -33,14 +37,22 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
33
37
|
var cancel = useCallback(function () {
|
|
34
38
|
generationRef.current += 1;
|
|
35
39
|
window.clearTimeout(timerRef.current);
|
|
40
|
+
window.clearTimeout(dateTimerRef.current);
|
|
36
41
|
}, []);
|
|
37
42
|
var scheduleLeave = useCallback(function () {
|
|
38
43
|
var pointerLeftScope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
39
44
|
var hadFocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : focusWithinRef.current;
|
|
45
|
+
var pointerEvent = arguments.length > 2 ? arguments[2] : undefined;
|
|
40
46
|
cancel();
|
|
41
47
|
var generation = generationRef.current;
|
|
42
48
|
timerRef.current = window.setTimeout(function () {
|
|
43
49
|
var _rootRef$current;
|
|
50
|
+
// 对话框仍打开时,按钮 loading、候选清空等引起的暂时失焦不结束整次选择交互。
|
|
51
|
+
// 结束条件由弹层自身关闭控制,避免连同弹窗一起卸成静默文本。@author nokecy
|
|
52
|
+
if (interactionLocksRef.current.size > 0) return;
|
|
53
|
+
// document 捕获先于 React portal 的捕获处理;到任务末再按完整的 React 作用域判定。
|
|
54
|
+
// 选择器弹层内的点击不结束当前格的编辑。@author nokecy
|
|
55
|
+
if (pointerEvent && pointerEventsInScopeRef.current.has(pointerEvent)) return;
|
|
44
56
|
// blur 后 activeElement 仍在本格通常是窗口切走或格内弹层切焦点,不算离开。
|
|
45
57
|
// 指针明确点到本格/其弹层之外时,即使目标不可聚焦导致 activeElement 没变,也应离开。
|
|
46
58
|
if (!pointerLeftScope && (_rootRef$current = rootRef.current) !== null && _rootRef$current !== void 0 && _rootRef$current.contains(document.activeElement)) return;
|
|
@@ -49,6 +61,20 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
49
61
|
}, hadFocus);
|
|
50
62
|
}, 0);
|
|
51
63
|
}, [cancel]);
|
|
64
|
+
var acquireInteractionLock = useCallback(function () {
|
|
65
|
+
var lock = Symbol('cell-popup');
|
|
66
|
+
interactionLocksRef.current.add(lock);
|
|
67
|
+
cancel();
|
|
68
|
+
// Editable 与懒挂载格可以嵌套;弹层同时占用所有父格,防止外层先卸掉选择器。@author nokecy
|
|
69
|
+
var releaseParent = acquireParentInteractionLock === null || acquireParentInteractionLock === void 0 ? void 0 : acquireParentInteractionLock();
|
|
70
|
+
return function () {
|
|
71
|
+
if (!interactionLocksRef.current.delete(lock)) return;
|
|
72
|
+
releaseParent === null || releaseParent === void 0 || releaseParent();
|
|
73
|
+
// 弹层关闭后恢复通常的校验与静默流程;不是永久屏蔽失焦。
|
|
74
|
+
// 卸载时 ref 已移除,不为已经销毁的单元格再排任务。@author nokecy
|
|
75
|
+
if (interactionLocksRef.current.size === 0 && rootRef.current) scheduleLeave(true, true);
|
|
76
|
+
};
|
|
77
|
+
}, [cancel, scheduleLeave, acquireParentInteractionLock]);
|
|
52
78
|
var handleFocus = function handleFocus() {
|
|
53
79
|
focusWithinRef.current = true;
|
|
54
80
|
cancel();
|
|
@@ -60,6 +86,8 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
60
86
|
};
|
|
61
87
|
var handlePointerDownCapture = function handlePointerDownCapture(event) {
|
|
62
88
|
pointerEventsInScopeRef.current.add(event.nativeEvent);
|
|
89
|
+
// 再次点击原输入框不一定产生 focus,仍须作废此前离开时发起的异步校验。@author nokecy
|
|
90
|
+
cancel();
|
|
63
91
|
};
|
|
64
92
|
var handleClickCapture = function handleClickCapture(event) {
|
|
65
93
|
var target = event.target;
|
|
@@ -70,7 +98,10 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
70
98
|
var selected = target.closest('.ant-picker-dropdown .ant-picker-cell-inner, .ant-picker-dropdown .ant-picker-ok, .ant-picker-dropdown .ant-picker-today-btn, .ant-picker-dropdown .ant-picker-now-btn');
|
|
71
99
|
if (!selected) return;
|
|
72
100
|
var dropdown = selected.closest('.ant-picker-dropdown');
|
|
73
|
-
window.
|
|
101
|
+
window.clearTimeout(dateTimerRef.current);
|
|
102
|
+
var generation = generationRef.current;
|
|
103
|
+
dateTimerRef.current = window.setTimeout(function () {
|
|
104
|
+
if (generation !== generationRef.current || !rootRef.current) return;
|
|
74
105
|
if (dropdown !== null && dropdown !== void 0 && dropdown.isConnected && !dropdown.classList.contains('ant-picker-dropdown-hidden')) return;
|
|
75
106
|
scheduleLeave(true, true);
|
|
76
107
|
}, 0);
|
|
@@ -84,22 +115,27 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
84
115
|
if (target instanceof Node && root.contains(target) || pointerEventsInScopeRef.current.has(event)) return;
|
|
85
116
|
// 新增行的必填空格也会预先挂载控件,但可能从未获得焦点;同样需要响应离开,
|
|
86
117
|
// 由 onLeave 根据 hadFocus 决定是否校验未触碰的空必填格。@author nokecy
|
|
87
|
-
scheduleLeave(true, focusWithinRef.current);
|
|
118
|
+
scheduleLeave(true, focusWithinRef.current, event);
|
|
88
119
|
};
|
|
89
|
-
|
|
120
|
+
|
|
121
|
+
// 捕获阶段也能收到被表单控件阻止冒泡的点击,避免必须点工具栏才退出编辑。
|
|
122
|
+
// portal 的归属在延迟任务中确认。@author nokecy
|
|
123
|
+
document.addEventListener('pointerdown', handleDocumentPointerDown, true);
|
|
90
124
|
return function () {
|
|
91
|
-
document.removeEventListener('pointerdown', handleDocumentPointerDown);
|
|
125
|
+
document.removeEventListener('pointerdown', handleDocumentPointerDown, true);
|
|
92
126
|
cancel();
|
|
93
127
|
};
|
|
94
128
|
}, [cancel, scheduleLeave]);
|
|
95
|
-
return /*#__PURE__*/React.createElement(
|
|
129
|
+
return /*#__PURE__*/React.createElement(CellInteractionLockContext.Provider, {
|
|
130
|
+
value: acquireInteractionLock
|
|
131
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
96
132
|
ref: rootRef,
|
|
97
133
|
style: {
|
|
98
134
|
display: 'contents'
|
|
99
135
|
},
|
|
100
|
-
|
|
101
|
-
|
|
136
|
+
onFocusCapture: handleFocus,
|
|
137
|
+
onBlurCapture: handleBlur,
|
|
102
138
|
onClickCapture: handleClickCapture,
|
|
103
139
|
onPointerDownCapture: handlePointerDownCapture
|
|
104
|
-
}, children);
|
|
140
|
+
}, children));
|
|
105
141
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/**
|
|
3
|
+
* 单元格弹层的交互占用。最后一个弹层关闭前,暂时失焦不能卸载单元格。
|
|
4
|
+
* 不在懒单元格中使用时无需任何额外处理。
|
|
5
|
+
* @author nokecy
|
|
6
|
+
*/
|
|
7
|
+
export declare const CellInteractionLockContext: import("react").Context<(() => () => void) | undefined>;
|
|
8
|
+
/**
|
|
9
|
+
* 将弹层的打开状态绑定到所属单元格,支持嵌套弹层并在关闭或卸载时释放。
|
|
10
|
+
* 使用布局阶段同步占用,避免打开弹层的同一次交互产生的失焦任务先卸载控件。
|
|
11
|
+
* @author nokecy
|
|
12
|
+
*/
|
|
13
|
+
export declare const useCellInteractionLock: (open: boolean) => void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createContext, useContext, useLayoutEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 单元格弹层的交互占用。最后一个弹层关闭前,暂时失焦不能卸载单元格。
|
|
5
|
+
* 不在懒单元格中使用时无需任何额外处理。
|
|
6
|
+
* @author nokecy
|
|
7
|
+
*/
|
|
8
|
+
export var CellInteractionLockContext = /*#__PURE__*/createContext(undefined);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 将弹层的打开状态绑定到所属单元格,支持嵌套弹层并在关闭或卸载时释放。
|
|
12
|
+
* 使用布局阶段同步占用,避免打开弹层的同一次交互产生的失焦任务先卸载控件。
|
|
13
|
+
* @author nokecy
|
|
14
|
+
*/
|
|
15
|
+
export var useCellInteractionLock = function useCellInteractionLock(open) {
|
|
16
|
+
var acquire = useContext(CellInteractionLockContext);
|
|
17
|
+
useLayoutEffect(function () {
|
|
18
|
+
if (open) return acquire === null || acquire === void 0 ? void 0 : acquire();
|
|
19
|
+
return undefined;
|
|
20
|
+
}, [acquire, open]);
|
|
21
|
+
};
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
2
|
import { GridApi } from 'ag-grid-community';
|
|
3
3
|
import { ArrayField } from '@formily/core';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
type CellFocusRequest = {
|
|
5
|
+
isCurrent: () => boolean;
|
|
6
|
+
schedule: (callback: () => void, delay: number) => void;
|
|
7
|
+
};
|
|
8
|
+
type BeginCellFocusRequest = (resolveCell: () => Element | null | undefined, isTargetCurrent?: () => boolean) => CellFocusRequest;
|
|
9
|
+
/** 单元格聚焦;已获得焦点的控件保留用户光标,等待挂载的请求可被新操作取消。@author nokecy */
|
|
8
10
|
export declare const useCellFocus: () => {
|
|
9
|
-
focusInputInCell: (cell: Element) => void;
|
|
11
|
+
focusInputInCell: (cell: Element, isTargetCurrent?: () => boolean) => void;
|
|
12
|
+
scheduleCellFocus: (resolveCell: () => Element | null | undefined, delay: number, isTargetCurrent?: () => boolean) => void;
|
|
13
|
+
beginFocusRequest: BeginCellFocusRequest;
|
|
10
14
|
};
|
|
11
15
|
/**
|
|
12
16
|
* 键盘导航 Hook
|
|
13
17
|
* 处理方向键在表格单元格间的导航
|
|
14
18
|
*/
|
|
15
|
-
export declare const useKeyboardNavigation: (ref: RefObject<any>, dataSource: any[], focusInputInCell: (cell: Element) => void, activateCell?: ((api: GridApi, node: any, colId: string) => boolean) | undefined) => {
|
|
19
|
+
export declare const useKeyboardNavigation: (ref: RefObject<any>, dataSource: any[], focusInputInCell: (cell: Element, isTargetCurrent?: () => boolean) => void, activateCell?: ((api: GridApi, node: any, colId: string) => boolean) | undefined, beginSharedFocusRequest?: BeginCellFocusRequest) => {
|
|
16
20
|
handleCellKeyDown: (event: any) => void;
|
|
17
21
|
};
|
|
18
22
|
/**
|
|
@@ -39,3 +43,4 @@ export declare const isNativeInputKey: (event: KeyboardEvent) => boolean;
|
|
|
39
43
|
export declare const suppressNativeInputKeys: ({ event }: {
|
|
40
44
|
event: KeyboardEvent;
|
|
41
45
|
}) => boolean;
|
|
46
|
+
export {};
|