@nokecy/qc-ui 1.1.64 → 1.1.66
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/queryForm/index.js +13 -5
- package/dist/cjs/ag-grid-plus/queryForm/schemaKey.d.ts +20 -0
- package/dist/cjs/ag-grid-plus/queryForm/schemaKey.js +25 -0
- package/dist/cjs/generatedListPage/ConfigurableToolbar.d.ts +2 -0
- package/dist/cjs/generatedListPage/ConfigurableToolbar.js +3 -2
- package/dist/cjs/generatedListPage/GeneratedListPage.js +13 -6
- package/dist/cjs/generatedListPage/OptionsColumn.js +26 -9
- package/dist/cjs/generatedListPage/index.d.ts +1 -1
- package/dist/cjs/generatedListPage/types.d.ts +26 -1
- package/dist/esm/ag-grid-plus/queryForm/index.js +13 -5
- package/dist/esm/ag-grid-plus/queryForm/schemaKey.d.ts +20 -0
- package/dist/esm/ag-grid-plus/queryForm/schemaKey.js +19 -0
- package/dist/esm/generatedListPage/ConfigurableToolbar.d.ts +2 -0
- package/dist/esm/generatedListPage/ConfigurableToolbar.js +3 -2
- package/dist/esm/generatedListPage/GeneratedListPage.js +13 -6
- package/dist/esm/generatedListPage/OptionsColumn.js +27 -10
- package/dist/esm/generatedListPage/index.d.ts +1 -1
- package/dist/esm/generatedListPage/types.d.ts +26 -1
- package/dist/umd/qc-ui.min.js +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ var _antd = require("antd");
|
|
|
12
12
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
13
13
|
var _react2 = _interopRequireWildcard(require("react"));
|
|
14
14
|
var _queryForm = _interopRequireDefault(require("./queryForm"));
|
|
15
|
+
var _schemaKey = require("./schemaKey");
|
|
15
16
|
var _boolSelect = _interopRequireDefault(require("../_utils/boolSelect"));
|
|
16
17
|
require("./index.less");
|
|
17
18
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
@@ -203,8 +204,19 @@ var FormRender = function FormRender(props) {
|
|
|
203
204
|
// 【新增】用于追踪是否已完成首次初始化
|
|
204
205
|
var initializedRef = (0, _react2.useRef)(false);
|
|
205
206
|
(0, _react2.useEffect)(function () {
|
|
207
|
+
var _new_schema$propertie, _new_schema$propertie2;
|
|
206
208
|
var new_schema = getSchema(onReset);
|
|
207
209
|
setSchema(new_schema);
|
|
210
|
+
// Formily 只在字段首次创建时读取 schema:已有查询项要把新标题、组件属性(如下拉选项)写回字段。@author nokecy
|
|
211
|
+
Object.entries((_new_schema$propertie = (_new_schema$propertie2 = new_schema.properties) === null || _new_schema$propertie2 === void 0 || (_new_schema$propertie2 = _new_schema$propertie2.queryForm) === null || _new_schema$propertie2 === void 0 ? void 0 : _new_schema$propertie2.properties) !== null && _new_schema$propertie !== void 0 ? _new_schema$propertie : {}).forEach(function (_ref) {
|
|
212
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
213
|
+
name = _ref2[0],
|
|
214
|
+
fieldSchema = _ref2[1];
|
|
215
|
+
form.query(name).take(function (field) {
|
|
216
|
+
field.title = fieldSchema.title;
|
|
217
|
+
field.setComponentProps(fieldSchema['x-component-props']);
|
|
218
|
+
});
|
|
219
|
+
});
|
|
208
220
|
|
|
209
221
|
// 【修复】在 schema 设置完成后调用 onInit
|
|
210
222
|
// 使用 setTimeout 确保 Formily 有时间处理 schema 并应用默认值
|
|
@@ -217,11 +229,7 @@ var FormRender = function FormRender(props) {
|
|
|
217
229
|
}, 0);
|
|
218
230
|
});
|
|
219
231
|
}
|
|
220
|
-
}, [
|
|
221
|
-
return c.colId;
|
|
222
|
-
}).join('|'), colDefs === null || colDefs === void 0 ? void 0 : colDefs.map(function (c) {
|
|
223
|
-
return "".concat(c.field, "|").concat(c.headerName);
|
|
224
|
-
}).join('|')]);
|
|
232
|
+
}, [(0, _schemaKey.queryFormSchemaKey)(columnStates, colDefs)]);
|
|
225
233
|
return /*#__PURE__*/_react2.default.createElement("div", {
|
|
226
234
|
className: (0, _classnames.default)(className, "ag-grid-table-search ag-grid-table-search-query-filter"),
|
|
227
235
|
style: {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type ColumnStateLike = {
|
|
2
|
+
colId?: string | null;
|
|
3
|
+
};
|
|
4
|
+
type QueryColumnLike = {
|
|
5
|
+
field?: string;
|
|
6
|
+
headerName?: string;
|
|
7
|
+
searchComponentProps?: {
|
|
8
|
+
options?: readonly {
|
|
9
|
+
value?: unknown;
|
|
10
|
+
label?: unknown;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* 查询区 schema 的重建键:列(id、字段、标题)或下拉选项变了才重建。
|
|
16
|
+
* 下拉选项常在首帧之后才到(如从基础资料接口取名称),只看列与标题时选项停在首帧。
|
|
17
|
+
* @author nokecy
|
|
18
|
+
*/
|
|
19
|
+
export declare const queryFormSchemaKey: (columnStates?: readonly ColumnStateLike[] | null, colDefs?: readonly QueryColumnLike[] | null) => string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.queryFormSchemaKey = void 0;
|
|
7
|
+
var optionsSignature = function optionsSignature(options) {
|
|
8
|
+
return Array.isArray(options) ? options.map(function (option) {
|
|
9
|
+
return "".concat(String(option === null || option === void 0 ? void 0 : option.value), "=").concat(String(option === null || option === void 0 ? void 0 : option.label));
|
|
10
|
+
}).join(',') : '';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 查询区 schema 的重建键:列(id、字段、标题)或下拉选项变了才重建。
|
|
15
|
+
* 下拉选项常在首帧之后才到(如从基础资料接口取名称),只看列与标题时选项停在首帧。
|
|
16
|
+
* @author nokecy
|
|
17
|
+
*/
|
|
18
|
+
var queryFormSchemaKey = exports.queryFormSchemaKey = function queryFormSchemaKey(columnStates, colDefs) {
|
|
19
|
+
return [columnStates === null || columnStates === void 0 ? void 0 : columnStates.map(function (column) {
|
|
20
|
+
return column.colId;
|
|
21
|
+
}).join('|'), colDefs === null || colDefs === void 0 ? void 0 : colDefs.map(function (column) {
|
|
22
|
+
var _column$searchCompone;
|
|
23
|
+
return "".concat(column.field, "|").concat(column.headerName, "|").concat(optionsSignature((_column$searchCompone = column.searchComponentProps) === null || _column$searchCompone === void 0 ? void 0 : _column$searchCompone.options));
|
|
24
|
+
}).join('|')].join('#');
|
|
25
|
+
};
|
|
@@ -40,9 +40,10 @@ var ConfigurableToolbar = function ConfigurableToolbar(_ref) {
|
|
|
40
40
|
_ref$exportFileName = _ref.exportFileName,
|
|
41
41
|
exportFileName = _ref$exportFileName === void 0 ? 'export.xlsx' : _ref$exportFileName,
|
|
42
42
|
filter = _ref.filter,
|
|
43
|
-
permissions = _ref.permissions
|
|
43
|
+
permissions = _ref.permissions,
|
|
44
|
+
access = _ref.access;
|
|
44
45
|
// 使用统一的权限检查 Hook
|
|
45
|
-
var _usePermissionCheck = (0, _usePermissionCheck2.usePermissionCheck)(permissions || {}),
|
|
46
|
+
var _usePermissionCheck = (0, _usePermissionCheck2.usePermissionCheck)(permissions || {}, access),
|
|
46
47
|
canCreate = _usePermissionCheck.canCreate,
|
|
47
48
|
canImport = _usePermissionCheck.canImport,
|
|
48
49
|
canExport = _usePermissionCheck.canExport,
|
|
@@ -92,7 +92,11 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
92
92
|
} : _config$paginationCon,
|
|
93
93
|
externalGridRef = config.gridRef,
|
|
94
94
|
externalOnRefresh = config.onRefresh,
|
|
95
|
-
pagedApiAdapter = config.pagedApiAdapter
|
|
95
|
+
pagedApiAdapter = config.pagedApiAdapter,
|
|
96
|
+
gridComponent = config.gridComponent,
|
|
97
|
+
access = config.access,
|
|
98
|
+
deleteConfirm = config.deleteConfirm;
|
|
99
|
+
var Grid = gridComponent || _agGridPlus.AgGridPlus;
|
|
96
100
|
|
|
97
101
|
// 内部Grid引用
|
|
98
102
|
var internalGridRef = (0, _react.useRef)();
|
|
@@ -165,11 +169,13 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
165
169
|
permissions: permissions,
|
|
166
170
|
formDialog: formDialog,
|
|
167
171
|
deleteApi: apiConfig.delete,
|
|
168
|
-
useErrorHandler: errorConfig.useErrorHandler
|
|
172
|
+
useErrorHandler: errorConfig.useErrorHandler,
|
|
173
|
+
access: access,
|
|
174
|
+
deleteConfirm: deleteConfirm
|
|
169
175
|
}
|
|
170
176
|
};
|
|
171
177
|
return [].concat(_toConsumableArray(columnDefs), [operationColumn]);
|
|
172
|
-
}, [columnDefs, formDialog, apiConfig.delete, permissions, onRefresh, OptionsColumnComponent, errorConfig.useErrorHandler]);
|
|
178
|
+
}, [columnDefs, formDialog, apiConfig.delete, permissions, onRefresh, OptionsColumnComponent, errorConfig.useErrorHandler, access, deleteConfirm]);
|
|
173
179
|
|
|
174
180
|
/**
|
|
175
181
|
* 从扁平数据构建树形结构
|
|
@@ -413,9 +419,10 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
413
419
|
importConfig: importConfig,
|
|
414
420
|
exportFileName: exportFileName,
|
|
415
421
|
filter: filter,
|
|
416
|
-
permissions: permissions
|
|
422
|
+
permissions: permissions,
|
|
423
|
+
access: access
|
|
417
424
|
}))];
|
|
418
|
-
}, [enableImportExport, toolbarActions, formDialog, apiConfig, onRefresh, importConfig, exportFileName, permissions]);
|
|
425
|
+
}, [enableImportExport, toolbarActions, formDialog, apiConfig, onRefresh, importConfig, exportFileName, permissions, access]);
|
|
419
426
|
|
|
420
427
|
// AgGridPlus属性配置
|
|
421
428
|
var agGridProps = _objectSpread({
|
|
@@ -476,7 +483,7 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
476
483
|
position: 'relative',
|
|
477
484
|
height: '100%'
|
|
478
485
|
}
|
|
479
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
486
|
+
}, /*#__PURE__*/_react.default.createElement(Grid, agGridProps), /*#__PURE__*/_react.default.createElement(_PerformanceMonitor.PerformanceDevTools, {
|
|
480
487
|
componentName: "GeneratedListPage-".concat(title),
|
|
481
488
|
metrics: metrics,
|
|
482
489
|
onGetReport: getPerformanceReport
|
|
@@ -32,10 +32,12 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
32
32
|
formDialog = props.formDialog,
|
|
33
33
|
deleteApi = props.deleteApi,
|
|
34
34
|
_props$useErrorHandle = props.useErrorHandler,
|
|
35
|
-
useErrorHandler = _props$useErrorHandle === void 0 ? true : _props$useErrorHandle
|
|
35
|
+
useErrorHandler = _props$useErrorHandle === void 0 ? true : _props$useErrorHandle,
|
|
36
|
+
access = props.access,
|
|
37
|
+
deleteConfirm = props.deleteConfirm;
|
|
36
38
|
|
|
37
39
|
// 使用权限检查 Hook
|
|
38
|
-
var _usePermissionCheck = (0, _usePermissionCheck2.usePermissionCheck)(permissions),
|
|
40
|
+
var _usePermissionCheck = (0, _usePermissionCheck2.usePermissionCheck)(permissions, access),
|
|
39
41
|
canUpdate = _usePermissionCheck.canUpdate,
|
|
40
42
|
canDelete = _usePermissionCheck.canDelete,
|
|
41
43
|
hasPermission = _usePermissionCheck.hasPermission;
|
|
@@ -90,13 +92,24 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
90
92
|
return null;
|
|
91
93
|
}
|
|
92
94
|
var FormDialogComponent = formDialog === null || formDialog === void 0 ? void 0 : formDialog.component;
|
|
95
|
+
|
|
96
|
+
// 确认框要说清删的是哪一条:页面没给标题时取该行的名称或编码。@author nokecy
|
|
97
|
+
var record = data;
|
|
98
|
+
var recordLabel = (record === null || record === void 0 ? void 0 : record.name) || (record === null || record === void 0 ? void 0 : record.displayName) || (record === null || record === void 0 ? void 0 : record.code);
|
|
99
|
+
var resolveText = function resolveText(value, fallback) {
|
|
100
|
+
return typeof value === 'function' ? value(data) : value !== null && value !== void 0 ? value : fallback;
|
|
101
|
+
};
|
|
102
|
+
var deleteTitle = resolveText(deleteConfirm === null || deleteConfirm === void 0 ? void 0 : deleteConfirm.title, recordLabel ? "\u786E\u5B9A\u5220\u9664\u300C".concat(recordLabel, "\u300D\uFF1F") : '确定删除?');
|
|
103
|
+
var deleteContent = resolveText(deleteConfirm === null || deleteConfirm === void 0 ? void 0 : deleteConfirm.content, '删除后无法恢复。');
|
|
93
104
|
return /*#__PURE__*/_react.default.createElement(_antd.Space, {
|
|
94
105
|
onClick: function onClick(event) {
|
|
95
106
|
event.stopPropagation();
|
|
96
107
|
}
|
|
97
108
|
}, showEditButton && FormDialogComponent && /*#__PURE__*/_react.default.createElement(Access, {
|
|
98
109
|
accessible: canUpdate
|
|
99
|
-
}, /*#__PURE__*/_react.default.createElement(
|
|
110
|
+
}, /*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
|
|
111
|
+
title: "\u7F16\u8F91"
|
|
112
|
+
}, /*#__PURE__*/_react.default.createElement("span", null, /*#__PURE__*/_react.default.createElement(FormDialogComponent, {
|
|
100
113
|
buttonProps: {
|
|
101
114
|
size: "small",
|
|
102
115
|
type: "link",
|
|
@@ -104,17 +117,19 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
104
117
|
style: {
|
|
105
118
|
fontSize: 14
|
|
106
119
|
}
|
|
107
|
-
})
|
|
120
|
+
}),
|
|
121
|
+
'aria-label': '编辑'
|
|
108
122
|
},
|
|
109
123
|
key: data.id,
|
|
110
124
|
title: formDialog.editTitle || '编辑',
|
|
111
125
|
entityId: data.id,
|
|
112
126
|
onAfterSubmit: refresh
|
|
113
|
-
})), showDeleteButton && /*#__PURE__*/_react.default.createElement(Access, {
|
|
127
|
+
})))), showDeleteButton && /*#__PURE__*/_react.default.createElement(Access, {
|
|
114
128
|
accessible: canDelete
|
|
115
129
|
}, /*#__PURE__*/_react.default.createElement(_deleteConfirm.default, {
|
|
116
|
-
title:
|
|
117
|
-
content:
|
|
130
|
+
title: deleteTitle,
|
|
131
|
+
content: deleteContent,
|
|
132
|
+
okText: "\u5220\u9664",
|
|
118
133
|
onConfirm: /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
119
134
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
120
135
|
while (1) switch (_context2.prev = _context2.next) {
|
|
@@ -127,11 +142,13 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
127
142
|
}
|
|
128
143
|
}, _callee2);
|
|
129
144
|
}))
|
|
145
|
+
}, /*#__PURE__*/_react.default.createElement(_antd.Tooltip, {
|
|
146
|
+
title: "\u5220\u9664"
|
|
130
147
|
}, /*#__PURE__*/_react.default.createElement(_antd.Button, {
|
|
131
148
|
size: "small",
|
|
132
149
|
icon: /*#__PURE__*/_react.default.createElement(_icons.DeleteOutlined, null),
|
|
133
150
|
type: "link",
|
|
134
|
-
|
|
135
|
-
}))));
|
|
151
|
+
"aria-label": "\u5220\u9664"
|
|
152
|
+
})))));
|
|
136
153
|
};
|
|
137
154
|
var _default = exports.default = OptionsColumn;
|
|
@@ -12,7 +12,7 @@ export { default } from './GeneratedListPage';
|
|
|
12
12
|
export { default as GeneratedListPage } from './GeneratedListPage';
|
|
13
13
|
export { default as ConfigurableToolbar } from './ConfigurableToolbar';
|
|
14
14
|
export { default as OptionsColumn } from './OptionsColumn';
|
|
15
|
-
export type { GeneratedListPageConfig, PermissionConfig, ApiConfig, ListParams, PagedResult, DeleteParams, ExportParams, ToolbarActionConfig, FormDialogConfig, TreeDataConfig, OptionsComponentProps } from './types';
|
|
15
|
+
export type { GeneratedListPageConfig, PermissionConfig, ApiConfig, ListParams, PagedResult, DeleteParams, ExportParams, ToolbarActionConfig, FormDialogConfig, TreeDataConfig, OptionsComponentProps, DeleteConfirmConfig } from './types';
|
|
16
16
|
export { usePermissionCheck, PermissionChecker } from './usePermissionCheck';
|
|
17
17
|
export { usePerformanceMonitor, PerformanceDevTools } from './PerformanceMonitor';
|
|
18
18
|
export { useRequestManager } from './useRequestManager';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { GridRef } from "../ag-grid-plus/interface";
|
|
3
2
|
import { ColDef } from "ag-grid-community";
|
|
4
3
|
import { ButtonProps } from "antd";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
5
|
import { PagedApiAdapter } from '../adapters';
|
|
6
6
|
/**
|
|
7
7
|
* 权限配置接口
|
|
@@ -203,6 +203,27 @@ export interface GeneratedListPageConfig<T = any> {
|
|
|
203
203
|
onRefresh?: () => void;
|
|
204
204
|
/** 分页 API 适配器(默认 ABP);非 ABP 后端可注入。@author nokecy */
|
|
205
205
|
pagedApiAdapter?: PagedApiAdapter;
|
|
206
|
+
/**
|
|
207
|
+
* 表格组件,默认用包内 AgGridPlus。
|
|
208
|
+
* 宿主可注入自己的表格基座(属性与 AgGridPlus 相同),让序号、默认复选、编码列收起、
|
|
209
|
+
* 内部字段隐藏等列表规范在通用列表页上同样生效。@author nokecy
|
|
210
|
+
*/
|
|
211
|
+
gridComponent?: React.ComponentType<any>;
|
|
212
|
+
/**
|
|
213
|
+
* 当前用户已授予的权限(权限名 → 是否授予),通常传 umi 的 useAccess()。
|
|
214
|
+
* 不传时工具栏与操作列不做权限过滤——没有权限的人也会看到新建、编辑、删除,点了才报 403。@author nokecy
|
|
215
|
+
*/
|
|
216
|
+
access?: Record<string, boolean>;
|
|
217
|
+
/** 删除确认框;title、content 可按行生成 */
|
|
218
|
+
deleteConfirm?: DeleteConfirmConfig<T>;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 删除确认框配置。
|
|
222
|
+
* 不传 title 时标题带上该行的名称或编码,让用户看清删的是哪一条;不传 content 时说明删除后无法恢复。@author nokecy
|
|
223
|
+
*/
|
|
224
|
+
export interface DeleteConfirmConfig<T = any> {
|
|
225
|
+
title?: ReactNode | ((record: T) => ReactNode);
|
|
226
|
+
content?: ReactNode | ((record: T) => ReactNode);
|
|
206
227
|
}
|
|
207
228
|
/**
|
|
208
229
|
* 操作列组件属性接口
|
|
@@ -221,4 +242,8 @@ export interface OptionsComponentProps<T = any> {
|
|
|
221
242
|
deleteApi?: (params: DeleteParams) => Promise<void>;
|
|
222
243
|
/** 是否使用统一错误处理 */
|
|
223
244
|
useErrorHandler?: boolean;
|
|
245
|
+
/** 当前用户已授予的权限,见 GeneratedListPageConfig.access */
|
|
246
|
+
access?: Record<string, boolean>;
|
|
247
|
+
/** 删除确认框配置 */
|
|
248
|
+
deleteConfirm?: DeleteConfirmConfig<T>;
|
|
224
249
|
}
|
|
@@ -18,6 +18,7 @@ import { Button, theme } from 'antd';
|
|
|
18
18
|
import classNames from 'classnames';
|
|
19
19
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
20
20
|
import QueryForm from "./queryForm";
|
|
21
|
+
import { queryFormSchemaKey } from "./schemaKey";
|
|
21
22
|
import BoolSelect from "../_utils/boolSelect";
|
|
22
23
|
import "./index.less";
|
|
23
24
|
var FormRender = function FormRender(props) {
|
|
@@ -195,8 +196,19 @@ var FormRender = function FormRender(props) {
|
|
|
195
196
|
// 【新增】用于追踪是否已完成首次初始化
|
|
196
197
|
var initializedRef = useRef(false);
|
|
197
198
|
useEffect(function () {
|
|
199
|
+
var _new_schema$propertie, _new_schema$propertie2;
|
|
198
200
|
var new_schema = getSchema(onReset);
|
|
199
201
|
setSchema(new_schema);
|
|
202
|
+
// Formily 只在字段首次创建时读取 schema:已有查询项要把新标题、组件属性(如下拉选项)写回字段。@author nokecy
|
|
203
|
+
Object.entries((_new_schema$propertie = (_new_schema$propertie2 = new_schema.properties) === null || _new_schema$propertie2 === void 0 || (_new_schema$propertie2 = _new_schema$propertie2.queryForm) === null || _new_schema$propertie2 === void 0 ? void 0 : _new_schema$propertie2.properties) !== null && _new_schema$propertie !== void 0 ? _new_schema$propertie : {}).forEach(function (_ref) {
|
|
204
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
205
|
+
name = _ref2[0],
|
|
206
|
+
fieldSchema = _ref2[1];
|
|
207
|
+
form.query(name).take(function (field) {
|
|
208
|
+
field.title = fieldSchema.title;
|
|
209
|
+
field.setComponentProps(fieldSchema['x-component-props']);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
200
212
|
|
|
201
213
|
// 【修复】在 schema 设置完成后调用 onInit
|
|
202
214
|
// 使用 setTimeout 确保 Formily 有时间处理 schema 并应用默认值
|
|
@@ -209,11 +221,7 @@ var FormRender = function FormRender(props) {
|
|
|
209
221
|
}, 0);
|
|
210
222
|
});
|
|
211
223
|
}
|
|
212
|
-
}, [columnStates
|
|
213
|
-
return c.colId;
|
|
214
|
-
}).join('|'), colDefs === null || colDefs === void 0 ? void 0 : colDefs.map(function (c) {
|
|
215
|
-
return "".concat(c.field, "|").concat(c.headerName);
|
|
216
|
-
}).join('|')]);
|
|
224
|
+
}, [queryFormSchemaKey(columnStates, colDefs)]);
|
|
217
225
|
return /*#__PURE__*/React.createElement("div", {
|
|
218
226
|
className: classNames(className, "ag-grid-table-search ag-grid-table-search-query-filter"),
|
|
219
227
|
style: {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type ColumnStateLike = {
|
|
2
|
+
colId?: string | null;
|
|
3
|
+
};
|
|
4
|
+
type QueryColumnLike = {
|
|
5
|
+
field?: string;
|
|
6
|
+
headerName?: string;
|
|
7
|
+
searchComponentProps?: {
|
|
8
|
+
options?: readonly {
|
|
9
|
+
value?: unknown;
|
|
10
|
+
label?: unknown;
|
|
11
|
+
}[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* 查询区 schema 的重建键:列(id、字段、标题)或下拉选项变了才重建。
|
|
16
|
+
* 下拉选项常在首帧之后才到(如从基础资料接口取名称),只看列与标题时选项停在首帧。
|
|
17
|
+
* @author nokecy
|
|
18
|
+
*/
|
|
19
|
+
export declare const queryFormSchemaKey: (columnStates?: readonly ColumnStateLike[] | null, colDefs?: readonly QueryColumnLike[] | null) => string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
var optionsSignature = function optionsSignature(options) {
|
|
2
|
+
return Array.isArray(options) ? options.map(function (option) {
|
|
3
|
+
return "".concat(String(option === null || option === void 0 ? void 0 : option.value), "=").concat(String(option === null || option === void 0 ? void 0 : option.label));
|
|
4
|
+
}).join(',') : '';
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 查询区 schema 的重建键:列(id、字段、标题)或下拉选项变了才重建。
|
|
9
|
+
* 下拉选项常在首帧之后才到(如从基础资料接口取名称),只看列与标题时选项停在首帧。
|
|
10
|
+
* @author nokecy
|
|
11
|
+
*/
|
|
12
|
+
export var queryFormSchemaKey = function queryFormSchemaKey(columnStates, colDefs) {
|
|
13
|
+
return [columnStates === null || columnStates === void 0 ? void 0 : columnStates.map(function (column) {
|
|
14
|
+
return column.colId;
|
|
15
|
+
}).join('|'), colDefs === null || colDefs === void 0 ? void 0 : colDefs.map(function (column) {
|
|
16
|
+
var _column$searchCompone;
|
|
17
|
+
return "".concat(column.field, "|").concat(column.headerName, "|").concat(optionsSignature((_column$searchCompone = column.searchComponentProps) === null || _column$searchCompone === void 0 ? void 0 : _column$searchCompone.options));
|
|
18
|
+
}).join('|')].join('#');
|
|
19
|
+
};
|
|
@@ -32,9 +32,10 @@ var ConfigurableToolbar = function ConfigurableToolbar(_ref) {
|
|
|
32
32
|
_ref$exportFileName = _ref.exportFileName,
|
|
33
33
|
exportFileName = _ref$exportFileName === void 0 ? 'export.xlsx' : _ref$exportFileName,
|
|
34
34
|
filter = _ref.filter,
|
|
35
|
-
permissions = _ref.permissions
|
|
35
|
+
permissions = _ref.permissions,
|
|
36
|
+
access = _ref.access;
|
|
36
37
|
// 使用统一的权限检查 Hook
|
|
37
|
-
var _usePermissionCheck = usePermissionCheck(permissions || {}),
|
|
38
|
+
var _usePermissionCheck = usePermissionCheck(permissions || {}, access),
|
|
38
39
|
canCreate = _usePermissionCheck.canCreate,
|
|
39
40
|
canImport = _usePermissionCheck.canImport,
|
|
40
41
|
canExport = _usePermissionCheck.canExport,
|
|
@@ -82,7 +82,11 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
82
82
|
} : _config$paginationCon,
|
|
83
83
|
externalGridRef = config.gridRef,
|
|
84
84
|
externalOnRefresh = config.onRefresh,
|
|
85
|
-
pagedApiAdapter = config.pagedApiAdapter
|
|
85
|
+
pagedApiAdapter = config.pagedApiAdapter,
|
|
86
|
+
gridComponent = config.gridComponent,
|
|
87
|
+
access = config.access,
|
|
88
|
+
deleteConfirm = config.deleteConfirm;
|
|
89
|
+
var Grid = gridComponent || AgGridPlus;
|
|
86
90
|
|
|
87
91
|
// 内部Grid引用
|
|
88
92
|
var internalGridRef = useRef();
|
|
@@ -155,11 +159,13 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
155
159
|
permissions: permissions,
|
|
156
160
|
formDialog: formDialog,
|
|
157
161
|
deleteApi: apiConfig.delete,
|
|
158
|
-
useErrorHandler: errorConfig.useErrorHandler
|
|
162
|
+
useErrorHandler: errorConfig.useErrorHandler,
|
|
163
|
+
access: access,
|
|
164
|
+
deleteConfirm: deleteConfirm
|
|
159
165
|
}
|
|
160
166
|
};
|
|
161
167
|
return [].concat(_toConsumableArray(columnDefs), [operationColumn]);
|
|
162
|
-
}, [columnDefs, formDialog, apiConfig.delete, permissions, onRefresh, OptionsColumnComponent, errorConfig.useErrorHandler]);
|
|
168
|
+
}, [columnDefs, formDialog, apiConfig.delete, permissions, onRefresh, OptionsColumnComponent, errorConfig.useErrorHandler, access, deleteConfirm]);
|
|
163
169
|
|
|
164
170
|
/**
|
|
165
171
|
* 从扁平数据构建树形结构
|
|
@@ -403,9 +409,10 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
403
409
|
importConfig: importConfig,
|
|
404
410
|
exportFileName: exportFileName,
|
|
405
411
|
filter: filter,
|
|
406
|
-
permissions: permissions
|
|
412
|
+
permissions: permissions,
|
|
413
|
+
access: access
|
|
407
414
|
}))];
|
|
408
|
-
}, [enableImportExport, toolbarActions, formDialog, apiConfig, onRefresh, importConfig, exportFileName, permissions]);
|
|
415
|
+
}, [enableImportExport, toolbarActions, formDialog, apiConfig, onRefresh, importConfig, exportFileName, permissions, access]);
|
|
409
416
|
|
|
410
417
|
// AgGridPlus属性配置
|
|
411
418
|
var agGridProps = _objectSpread({
|
|
@@ -466,7 +473,7 @@ var GeneratedListPage = function GeneratedListPage(config) {
|
|
|
466
473
|
position: 'relative',
|
|
467
474
|
height: '100%'
|
|
468
475
|
}
|
|
469
|
-
}, /*#__PURE__*/React.createElement(
|
|
476
|
+
}, /*#__PURE__*/React.createElement(Grid, agGridProps), /*#__PURE__*/React.createElement(PerformanceDevTools, {
|
|
470
477
|
componentName: "GeneratedListPage-".concat(title),
|
|
471
478
|
metrics: metrics,
|
|
472
479
|
onGetReport: getPerformanceReport
|
|
@@ -3,7 +3,7 @@ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyri
|
|
|
3
3
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
4
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
5
5
|
import React, { useMemo } from 'react';
|
|
6
|
-
import { Space, Button } from 'antd';
|
|
6
|
+
import { Space, Button, Tooltip } from 'antd';
|
|
7
7
|
import { EditOutlined, DeleteOutlined } from '@ant-design/icons';
|
|
8
8
|
import AccessWrapper from "./_utils/AccessWrapper";
|
|
9
9
|
import { defaultHandleDelete } from "./_utils/defaultHandlers";
|
|
@@ -24,10 +24,12 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
24
24
|
formDialog = props.formDialog,
|
|
25
25
|
deleteApi = props.deleteApi,
|
|
26
26
|
_props$useErrorHandle = props.useErrorHandler,
|
|
27
|
-
useErrorHandler = _props$useErrorHandle === void 0 ? true : _props$useErrorHandle
|
|
27
|
+
useErrorHandler = _props$useErrorHandle === void 0 ? true : _props$useErrorHandle,
|
|
28
|
+
access = props.access,
|
|
29
|
+
deleteConfirm = props.deleteConfirm;
|
|
28
30
|
|
|
29
31
|
// 使用权限检查 Hook
|
|
30
|
-
var _usePermissionCheck = usePermissionCheck(permissions),
|
|
32
|
+
var _usePermissionCheck = usePermissionCheck(permissions, access),
|
|
31
33
|
canUpdate = _usePermissionCheck.canUpdate,
|
|
32
34
|
canDelete = _usePermissionCheck.canDelete,
|
|
33
35
|
hasPermission = _usePermissionCheck.hasPermission;
|
|
@@ -82,13 +84,24 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
82
84
|
return null;
|
|
83
85
|
}
|
|
84
86
|
var FormDialogComponent = formDialog === null || formDialog === void 0 ? void 0 : formDialog.component;
|
|
87
|
+
|
|
88
|
+
// 确认框要说清删的是哪一条:页面没给标题时取该行的名称或编码。@author nokecy
|
|
89
|
+
var record = data;
|
|
90
|
+
var recordLabel = (record === null || record === void 0 ? void 0 : record.name) || (record === null || record === void 0 ? void 0 : record.displayName) || (record === null || record === void 0 ? void 0 : record.code);
|
|
91
|
+
var resolveText = function resolveText(value, fallback) {
|
|
92
|
+
return typeof value === 'function' ? value(data) : value !== null && value !== void 0 ? value : fallback;
|
|
93
|
+
};
|
|
94
|
+
var deleteTitle = resolveText(deleteConfirm === null || deleteConfirm === void 0 ? void 0 : deleteConfirm.title, recordLabel ? "\u786E\u5B9A\u5220\u9664\u300C".concat(recordLabel, "\u300D\uFF1F") : '确定删除?');
|
|
95
|
+
var deleteContent = resolveText(deleteConfirm === null || deleteConfirm === void 0 ? void 0 : deleteConfirm.content, '删除后无法恢复。');
|
|
85
96
|
return /*#__PURE__*/React.createElement(Space, {
|
|
86
97
|
onClick: function onClick(event) {
|
|
87
98
|
event.stopPropagation();
|
|
88
99
|
}
|
|
89
100
|
}, showEditButton && FormDialogComponent && /*#__PURE__*/React.createElement(Access, {
|
|
90
101
|
accessible: canUpdate
|
|
91
|
-
}, /*#__PURE__*/React.createElement(
|
|
102
|
+
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
103
|
+
title: "\u7F16\u8F91"
|
|
104
|
+
}, /*#__PURE__*/React.createElement("span", null, /*#__PURE__*/React.createElement(FormDialogComponent, {
|
|
92
105
|
buttonProps: {
|
|
93
106
|
size: "small",
|
|
94
107
|
type: "link",
|
|
@@ -96,17 +109,19 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
96
109
|
style: {
|
|
97
110
|
fontSize: 14
|
|
98
111
|
}
|
|
99
|
-
})
|
|
112
|
+
}),
|
|
113
|
+
'aria-label': '编辑'
|
|
100
114
|
},
|
|
101
115
|
key: data.id,
|
|
102
116
|
title: formDialog.editTitle || '编辑',
|
|
103
117
|
entityId: data.id,
|
|
104
118
|
onAfterSubmit: refresh
|
|
105
|
-
})), showDeleteButton && /*#__PURE__*/React.createElement(Access, {
|
|
119
|
+
})))), showDeleteButton && /*#__PURE__*/React.createElement(Access, {
|
|
106
120
|
accessible: canDelete
|
|
107
121
|
}, /*#__PURE__*/React.createElement(DeleteConfirm, {
|
|
108
|
-
title:
|
|
109
|
-
content:
|
|
122
|
+
title: deleteTitle,
|
|
123
|
+
content: deleteContent,
|
|
124
|
+
okText: "\u5220\u9664",
|
|
110
125
|
onConfirm: /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
111
126
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
112
127
|
while (1) switch (_context2.prev = _context2.next) {
|
|
@@ -119,11 +134,13 @@ var OptionsColumn = function OptionsColumn(props) {
|
|
|
119
134
|
}
|
|
120
135
|
}, _callee2);
|
|
121
136
|
}))
|
|
137
|
+
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
138
|
+
title: "\u5220\u9664"
|
|
122
139
|
}, /*#__PURE__*/React.createElement(Button, {
|
|
123
140
|
size: "small",
|
|
124
141
|
icon: /*#__PURE__*/React.createElement(DeleteOutlined, null),
|
|
125
142
|
type: "link",
|
|
126
|
-
|
|
127
|
-
}))));
|
|
143
|
+
"aria-label": "\u5220\u9664"
|
|
144
|
+
})))));
|
|
128
145
|
};
|
|
129
146
|
export default OptionsColumn;
|
|
@@ -12,7 +12,7 @@ export { default } from './GeneratedListPage';
|
|
|
12
12
|
export { default as GeneratedListPage } from './GeneratedListPage';
|
|
13
13
|
export { default as ConfigurableToolbar } from './ConfigurableToolbar';
|
|
14
14
|
export { default as OptionsColumn } from './OptionsColumn';
|
|
15
|
-
export type { GeneratedListPageConfig, PermissionConfig, ApiConfig, ListParams, PagedResult, DeleteParams, ExportParams, ToolbarActionConfig, FormDialogConfig, TreeDataConfig, OptionsComponentProps } from './types';
|
|
15
|
+
export type { GeneratedListPageConfig, PermissionConfig, ApiConfig, ListParams, PagedResult, DeleteParams, ExportParams, ToolbarActionConfig, FormDialogConfig, TreeDataConfig, OptionsComponentProps, DeleteConfirmConfig } from './types';
|
|
16
16
|
export { usePermissionCheck, PermissionChecker } from './usePermissionCheck';
|
|
17
17
|
export { usePerformanceMonitor, PerformanceDevTools } from './PerformanceMonitor';
|
|
18
18
|
export { useRequestManager } from './useRequestManager';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { GridRef } from "../ag-grid-plus/interface";
|
|
3
2
|
import { ColDef } from "ag-grid-community";
|
|
4
3
|
import { ButtonProps } from "antd";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
5
|
import { PagedApiAdapter } from '../adapters';
|
|
6
6
|
/**
|
|
7
7
|
* 权限配置接口
|
|
@@ -203,6 +203,27 @@ export interface GeneratedListPageConfig<T = any> {
|
|
|
203
203
|
onRefresh?: () => void;
|
|
204
204
|
/** 分页 API 适配器(默认 ABP);非 ABP 后端可注入。@author nokecy */
|
|
205
205
|
pagedApiAdapter?: PagedApiAdapter;
|
|
206
|
+
/**
|
|
207
|
+
* 表格组件,默认用包内 AgGridPlus。
|
|
208
|
+
* 宿主可注入自己的表格基座(属性与 AgGridPlus 相同),让序号、默认复选、编码列收起、
|
|
209
|
+
* 内部字段隐藏等列表规范在通用列表页上同样生效。@author nokecy
|
|
210
|
+
*/
|
|
211
|
+
gridComponent?: React.ComponentType<any>;
|
|
212
|
+
/**
|
|
213
|
+
* 当前用户已授予的权限(权限名 → 是否授予),通常传 umi 的 useAccess()。
|
|
214
|
+
* 不传时工具栏与操作列不做权限过滤——没有权限的人也会看到新建、编辑、删除,点了才报 403。@author nokecy
|
|
215
|
+
*/
|
|
216
|
+
access?: Record<string, boolean>;
|
|
217
|
+
/** 删除确认框;title、content 可按行生成 */
|
|
218
|
+
deleteConfirm?: DeleteConfirmConfig<T>;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 删除确认框配置。
|
|
222
|
+
* 不传 title 时标题带上该行的名称或编码,让用户看清删的是哪一条;不传 content 时说明删除后无法恢复。@author nokecy
|
|
223
|
+
*/
|
|
224
|
+
export interface DeleteConfirmConfig<T = any> {
|
|
225
|
+
title?: ReactNode | ((record: T) => ReactNode);
|
|
226
|
+
content?: ReactNode | ((record: T) => ReactNode);
|
|
206
227
|
}
|
|
207
228
|
/**
|
|
208
229
|
* 操作列组件属性接口
|
|
@@ -221,4 +242,8 @@ export interface OptionsComponentProps<T = any> {
|
|
|
221
242
|
deleteApi?: (params: DeleteParams) => Promise<void>;
|
|
222
243
|
/** 是否使用统一错误处理 */
|
|
223
244
|
useErrorHandler?: boolean;
|
|
245
|
+
/** 当前用户已授予的权限,见 GeneratedListPageConfig.access */
|
|
246
|
+
access?: Record<string, boolean>;
|
|
247
|
+
/** 删除确认框配置 */
|
|
248
|
+
deleteConfirm?: DeleteConfirmConfig<T>;
|
|
224
249
|
}
|