Commit 768c1456 authored by drigle's avatar drigle

feat: support configurable view filter fields

parent 558ad817
......@@ -92,6 +92,7 @@ import {
normalizeDelayRequest,
normalizeDelayRequestItems,
normalizeDepartmentRectificationItems,
resolveProblemRectificationFilterColumns,
getViewRestrictionDefaults,
} from '../problemRectificationListService';
import {
......@@ -1058,8 +1059,15 @@ export default function ProblemRectificationListPage() {
[records, activeGridView, subject],
);
const dynamicFilterSchema = useMemo(
() => buildProblemRectificationFilterSchema(configuredView.columns || []),
[configuredView.columns],
() =>
buildProblemRectificationFilterSchema(
resolveProblemRectificationFilterColumns(
activeGridView,
subject,
configuredView.columns || [],
),
),
[activeGridView, configuredView.columns, subject],
);
const createFields = useMemo(
......
......@@ -59,7 +59,7 @@
问题整改列表的新增表单、筛选和表格均读取当前激活 Grid View:
- 新增表单按 `settings.columns` 顺序渲染可见字段,并包含记录标题字段;标题是否必填跟随视图列配置,未配置短标题时使用标题作为默认回退值。`settings.shortTitle = true` 时隐藏列表及新增表单的根级记录标题,不校验或提交根级 `title`。
- 筛选控件由视图列的 Subject 字段类型自动生成。`select` 选项来自 `settings.options`,日期、数字、布尔、用户和引用字段使用对应控件;提交时按 `field:<path>` 通过 `/record/query` 远程筛选,不再提供独立关键词搜索。
- 筛选控件默认按视图可见列的 Subject 字段类型自动生成;当 Grid View 配置 `settings.filters.fields` 时,仅按该数组顺序展示筛选字段,支持 `metadata.<field>`、裸字段名或 `{ field }` 配置,也可引用视图中的隐藏列。未配置属性时回退到可见列,空数组表示不展示筛选控件;无效字段会被忽略。`select` 选项来自 `settings.options`,日期、数字、布尔、用户和引用字段使用对应控件;提交时按 `field:<path>` 通过 `/record/query` 远程筛选,不再提供独立关键词搜索。
- 引用和用户多选的输入摘要、列表勾选与草稿统一使用归一化 ID;引用写入只保存目标记录 `_id` 或 `_id[]`。
- 表格请求期间 DataGrid 使用居中的 loading 遮罩,空结果与加载中状态分开处理。
......
......@@ -778,6 +778,14 @@ function normalizeDynamicFilterField(field) {
return `metadata.${normalized}`;
}
function normalizeConfiguredFilterField(field) {
if (typeof field !== 'string') {
return '';
}
return normalizeDynamicFilterField(field.trim());
}
function escapeDynamicFilterRegex(value) {
return String(value ?? '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
......@@ -859,6 +867,31 @@ export function buildProblemRectificationFilterSchema(columns = []) {
}, []);
}
export function resolveProblemRectificationFilterColumns(view, subject, visibleColumns = []) {
const configuredFields = view?.settings?.filters?.fields;
if (!Array.isArray(configuredFields)) {
return visibleColumns;
}
const allViewColumns = buildViewColumns(view, subject, { includeHidden: true });
const columnsByField = new Map(
[...allViewColumns, ...visibleColumns].map((column) => [
normalizeConfiguredFilterField(column?.field),
column,
]),
);
return configuredFields
.map((item) => {
const configuredField =
typeof item === 'string'
? item
: item?.field || item?.path || item?.name;
return columnsByField.get(normalizeConfiguredFilterField(configuredField));
})
.filter(Boolean);
}
function buildInspectionReportMonthFilter(month) {
const normalizedMonth = normalizeText(month);
if (!/^\d{4}-(0[1-9]|1[0-2])$/.test(normalizedMonth)) {
......@@ -1025,7 +1058,7 @@ function buildCalculatedQualityRatingFilter(rating) {
}
export function buildProblemRectificationQueryFilter(filters = {}, gridView, subject) {
const columns = buildViewColumnsForList(gridView, subject);
const columns = buildViewColumns(gridView, subject, { includeHidden: true });
const uiFieldClauses = Object.entries(FILTER_FIELD_PATHS).map(([filterKey, fieldPath]) => {
const value = filters?.[filterKey];
if (isEmptyFilterValue(value)) {
......@@ -1048,7 +1081,11 @@ export function buildProblemRectificationQueryFilter(filters = {}, gridView, sub
.map(([key, value]) => buildDynamicFilterClause(
key.slice('field:'.length),
value,
columns.find((column) => column.field === key.slice('field:'.length))?.fieldDef,
columns.find(
(column) =>
normalizeConfiguredFilterField(column.field) ===
normalizeConfiguredFilterField(key.slice('field:'.length)),
)?.fieldDef,
)),
]);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment