openxiangda 2.0.0-alpha.80 → 2.0.0-alpha.81
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/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
- package/dist/browser/components/resource/GeneratedResourceCrud.js +246 -20
- package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
- package/dist/browser/components/resource/ResourceBatchActions.d.ts +9 -0
- package/dist/browser/components/resource/ResourceBatchActions.d.ts.map +1 -1
- package/dist/browser/components/resource/ResourceBatchActions.js +115 -1
- package/dist/browser/components/resource/ResourceBatchActions.js.map +1 -1
- package/dist/browser/components/resource/StandardResourcePages.d.ts +2 -5
- package/dist/browser/components/resource/StandardResourcePages.d.ts.map +1 -1
- package/dist/browser/components/resource/StandardResourcePages.js +5 -10
- package/dist/browser/components/resource/StandardResourcePages.js.map +1 -1
- package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -1
- package/dist/browser/components/resource/SurfaceFields.js +1 -6
- package/dist/browser/components/resource/SurfaceFields.js.map +1 -1
- package/dist/browser/components/resource/workflow-resource-import.d.ts +27 -0
- package/dist/browser/components/resource/workflow-resource-import.d.ts.map +1 -0
- package/dist/browser/components/resource/workflow-resource-import.js +35 -0
- package/dist/browser/components/resource/workflow-resource-import.js.map +1 -0
- package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -1
- package/dist/browser/components/workflow/StandardWorkflowPages.js +47 -24
- package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -1
- package/dist/browser/platform-client.d.ts +21 -0
- package/dist/browser/platform-client.d.ts.map +1 -1
- package/dist/browser/platform-client.js +15 -0
- package/dist/browser/platform-client.js.map +1 -1
- package/dist/browser/styles.css +45 -14
- package/package.json +7 -7
- package/skills/openxiangda-v2/SKILL.md +3 -3
- package/skills/openxiangda-v2/references/data-authz.md +7 -2
- package/skills/openxiangda-v2/references/workspace.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeneratedResourceCrud.d.ts","sourceRoot":"","sources":["../../../../src/browser/components/resource/GeneratedResourceCrud.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GeneratedResourceCrud.d.ts","sourceRoot":"","sources":["../../../../src/browser/components/resource/GeneratedResourceCrud.tsx"],"names":[],"mappings":"AAgGA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAWnF,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA4QD,wBAAgB,qBAAqB,CAAC,EACpC,YAAY,EACZ,IAAa,EACb,OAAmB,EACnB,UAAU,EAAE,kBAAkB,EAC9B,KAAK,GACN,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC7C,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,KAAK,EAAE,2BAA2B,CAAC;CACpC,2CAqBA"}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { ArrowRightOutlined, ColumnHeightOutlined, DeleteOutlined, EditOutlined, EyeOutlined, ExportOutlined, FilterOutlined, PlusOutlined, ReloadOutlined, SearchOutlined, SettingOutlined, } from '@ant-design/icons';
|
|
2
|
+
import { ArrowRightOutlined, ColumnHeightOutlined, DeleteOutlined, EditOutlined, EyeOutlined, ExportOutlined, FilterOutlined, PlusOutlined, ReloadOutlined, SaveOutlined, SearchOutlined, SettingOutlined, UndoOutlined, } from '@ant-design/icons';
|
|
3
3
|
import { useCreate, useDelete, useList, useOne, useUpdate } from '@refinedev/core';
|
|
4
4
|
import { App, Alert, Button, Card, Collapse, Descriptions, Dropdown, Empty, Form, Input, Modal, Popconfirm, Result, Space, Spin, Table, Tag, Tooltip, Typography, } from 'antd';
|
|
5
5
|
import { Fragment, useEffect, useMemo, useState } from 'react';
|
|
6
6
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
7
7
|
import { MobileResourceDetailPage, MobileResourceFormPage, MobileResourceListPage, ResourceDetailPage, ResourceFormPage, ResourceListPage, } from './StandardResourcePages';
|
|
8
8
|
import { auditActorLabel, auditFieldChange, auditFieldCodes, listSurfaceFields, MobileSurfaceFieldControl, SurfaceAuditFieldValue, SurfaceFieldControl, SurfaceFieldValue, SurfaceFilterControl, } from './SurfaceFields';
|
|
9
|
-
import { createNativeResourceClient, transactNativeData, } from '../../platform-client';
|
|
9
|
+
import { createNativeResourceClient, loadResourceListPreference, resetResourceListPreference, saveResourceListPreference, transactNativeData, } from '../../platform-client';
|
|
10
10
|
import { normalizeFormValues, normalizeRecordForForm } from '../platform-fields/field-form-codec';
|
|
11
|
-
import { DirectoryIdentityText } from '../../AuthoritativeSelector';
|
|
12
11
|
import { useRuntime } from '../../runtime';
|
|
13
|
-
import { ResourceBatchActions, ResourceImportButton } from './ResourceBatchActions';
|
|
12
|
+
import { ResourceBatchActions, ResourceImportButton, WorkflowResourceImportButton, } from './ResourceBatchActions';
|
|
14
13
|
import { isAdminContributionAllowed, useAdminResourceContributions, } from '../../admin-contributions';
|
|
15
14
|
import { SubtableField, SubtableValueDisplay, } from '../platform-fields/SubtableField';
|
|
16
15
|
import { buildSubtableOperations, } from '../platform-fields/subtable-value';
|
|
17
16
|
import { useResourceDefinitions } from '../../resource-definitions';
|
|
17
|
+
import { useWorkflowDefinitions } from '../../workflow-definitions';
|
|
18
18
|
function resourceRecordPath(path, id) {
|
|
19
19
|
if (!path || !path.includes(':id')) {
|
|
20
20
|
throw new Error('OPENXIANGDA_GENERATED_RESOURCE_ROUTE_MISSING');
|
|
@@ -145,7 +145,12 @@ async function exportResourceRows(code, name, surface, fields, query, sort) {
|
|
|
145
145
|
}
|
|
146
146
|
function AuditEntry({ entry, resourceCode, surface, readable, }) {
|
|
147
147
|
const fields = auditChangeFields(entry, surface).filter(readable);
|
|
148
|
-
|
|
148
|
+
const actorName = entry.actorDisplay?.displayName || auditActorLabel(entry);
|
|
149
|
+
const occurredAt = new Date(entry.occurredAt).toLocaleString('zh-CN');
|
|
150
|
+
if (entry.operation === 'created') {
|
|
151
|
+
return (_jsx("div", { className: "oxa-audit-entry oxa-audit-entry-created", children: _jsxs(Typography.Text, { children: [_jsx("strong", { children: actorName }), " \u4E8E ", occurredAt, " \u521B\u5EFA\u8BB0\u5F55"] }) }));
|
|
152
|
+
}
|
|
153
|
+
return (_jsxs("div", { className: "oxa-audit-entry", children: [_jsxs("div", { className: "oxa-audit-heading", children: [_jsx("strong", { children: auditOperationLabel(entry.operation) }), _jsxs(Typography.Text, { type: "secondary", children: ["\u7248\u672C ", entry.revision] })] }), _jsxs("div", { className: "oxa-audit-meta", children: [_jsx("span", { children: "\u64CD\u4F5C\u4EBA" }), _jsx(Typography.Text, { children: actorName }), _jsx("span", { children: "\u65F6\u95F4" }), _jsx(Typography.Text, { children: occurredAt })] }), fields.length ? (_jsx("div", { className: "oxa-audit-changes", children: fields.map((field) => {
|
|
149
154
|
const change = auditFieldChange(entry, field.key);
|
|
150
155
|
const before = change?.before;
|
|
151
156
|
const after = change?.after;
|
|
@@ -228,6 +233,7 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
228
233
|
const { hasCapability, hasReadCapability, identity } = useRuntime();
|
|
229
234
|
const { code, name, surface, capabilities } = definition;
|
|
230
235
|
const generated = surface.generated;
|
|
236
|
+
const workflowDefinitions = useWorkflowDefinitions();
|
|
231
237
|
const contributions = useAdminResourceContributions(code);
|
|
232
238
|
const fields = listSurfaceFields(surface.fields).filter((field) => fieldReadable(field, hasReadCapability, identity.isAppSuperAdmin));
|
|
233
239
|
const readableFieldCodes = new Set(Object.entries(surface.fields)
|
|
@@ -238,12 +244,24 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
238
244
|
const [moreFiltersOpen, setMoreFiltersOpen] = useState(false);
|
|
239
245
|
const [moreFilterDraft, setMoreFilterDraft] = useState({});
|
|
240
246
|
const [density, setDensity] = useState('middle');
|
|
241
|
-
const [visibleColumnKeys, setVisibleColumnKeys] = useState(() =>
|
|
247
|
+
const [visibleColumnKeys, setVisibleColumnKeys] = useState(() => [
|
|
248
|
+
...fields.map((field) => field.key),
|
|
249
|
+
'created_at',
|
|
250
|
+
'updated_at',
|
|
251
|
+
]);
|
|
242
252
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
253
|
+
const [preferenceReady, setPreferenceReady] = useState(false);
|
|
254
|
+
const [preferenceSaving, setPreferenceSaving] = useState(false);
|
|
255
|
+
const [savedPreferenceFingerprint, setSavedPreferenceFingerprint] = useState('');
|
|
256
|
+
const [hasSavedPreference, setHasSavedPreference] = useState(false);
|
|
243
257
|
const remove = useDelete();
|
|
244
258
|
const rows = (state.list.result.data || []);
|
|
245
259
|
useEffect(() => {
|
|
246
|
-
setVisibleColumnKeys(
|
|
260
|
+
setVisibleColumnKeys([
|
|
261
|
+
...fields.map((field) => field.key),
|
|
262
|
+
'created_at',
|
|
263
|
+
'updated_at',
|
|
264
|
+
]);
|
|
247
265
|
setMoreFiltersOpen(false);
|
|
248
266
|
setMoreFilterDraft({});
|
|
249
267
|
setDensity('middle');
|
|
@@ -256,12 +274,158 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
256
274
|
const importWritableFieldCodes = formFields
|
|
257
275
|
.filter((field) => field.widget !== 'readonly' && fieldWritable(field, 'create', hasCapability, identity.isAppSuperAdmin))
|
|
258
276
|
.map((field) => field.key);
|
|
277
|
+
const standardWorkflows = [...workflowDefinitions.values()].filter(workflow => workflow.subject.resourceCode === code &&
|
|
278
|
+
['standalone', 'hidden-handoff'].includes(workflow.launch.mode) &&
|
|
279
|
+
Boolean(workflow.processOperationCode));
|
|
280
|
+
const standardWorkflow = surface.mutationOwner === 'workflow' && standardWorkflows.length === 1
|
|
281
|
+
? standardWorkflows[0]
|
|
282
|
+
: undefined;
|
|
283
|
+
const workflowImportFieldCodes = formFields
|
|
284
|
+
.filter(field => !field.system &&
|
|
285
|
+
field.widget !== 'readonly' &&
|
|
286
|
+
field.type !== 'subtable')
|
|
287
|
+
.map(field => field.key);
|
|
259
288
|
const batchWritableFields = formFields.filter((field) => !['file', 'readonly'].includes(field.widget || '') && fieldWritable(field, 'edit', hasCapability, identity.isAppSuperAdmin));
|
|
260
289
|
const selectedRows = rows.filter((row) => selectedRowKeys.includes(row.id));
|
|
261
290
|
const toolbarContributions = (contributions?.toolbar || []).filter((item) => isAdminContributionAllowed(item, hasCapability));
|
|
262
291
|
const rowContributions = (contributions?.row || []).filter((item) => isAdminContributionAllowed(item, hasCapability));
|
|
263
292
|
const canBatch = (generated.update && hasCapability(capabilities.update)) ||
|
|
264
293
|
(generated.delete && hasCapability(capabilities.delete));
|
|
294
|
+
const configurableColumns = [
|
|
295
|
+
...fields.map(field => ({ key: field.key, label: field.label })),
|
|
296
|
+
{ key: 'created_at', label: '创建时间' },
|
|
297
|
+
{ key: 'updated_at', label: '更新时间' },
|
|
298
|
+
];
|
|
299
|
+
const listKey = `openxiangda-v2:resource:${code}`;
|
|
300
|
+
const preferencePayload = () => ({
|
|
301
|
+
version: 1,
|
|
302
|
+
columns: configurableColumns.map(column => ({
|
|
303
|
+
key: column.key,
|
|
304
|
+
visible: visibleColumnKeys.includes(column.key),
|
|
305
|
+
})),
|
|
306
|
+
filters: {
|
|
307
|
+
...(state.query.keyword?.trim()
|
|
308
|
+
? { keyword: state.query.keyword.trim() }
|
|
309
|
+
: {}),
|
|
310
|
+
...(state.query.filters && Object.keys(state.query.filters).length
|
|
311
|
+
? { values: state.query.filters }
|
|
312
|
+
: {}),
|
|
313
|
+
},
|
|
314
|
+
sorts: [
|
|
315
|
+
{
|
|
316
|
+
field: state.sort.field,
|
|
317
|
+
direction: state.sort.order === 'asc' ? 'ascend' : 'descend',
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
density,
|
|
321
|
+
pageSize: state.pageSize,
|
|
322
|
+
});
|
|
323
|
+
const preferenceFingerprint = (preference) => JSON.stringify({
|
|
324
|
+
version: preference.version,
|
|
325
|
+
columns: preference.columns,
|
|
326
|
+
filters: preference.filters,
|
|
327
|
+
sorts: preference.sorts,
|
|
328
|
+
density: preference.density,
|
|
329
|
+
pageSize: preference.pageSize,
|
|
330
|
+
});
|
|
331
|
+
const currentPreferenceFingerprint = preferenceFingerprint(preferencePayload());
|
|
332
|
+
const preferenceDirty = preferenceReady &&
|
|
333
|
+
currentPreferenceFingerprint !== savedPreferenceFingerprint;
|
|
334
|
+
useEffect(() => {
|
|
335
|
+
let active = true;
|
|
336
|
+
setPreferenceReady(false);
|
|
337
|
+
const defaults = preferencePayload();
|
|
338
|
+
void loadResourceListPreference(listKey)
|
|
339
|
+
.then(preference => {
|
|
340
|
+
if (!active)
|
|
341
|
+
return;
|
|
342
|
+
const allowedColumns = new Set(configurableColumns.map(column => column.key));
|
|
343
|
+
const storedColumns = Array.isArray(preference?.columns)
|
|
344
|
+
? preference.columns.filter(column => allowedColumns.has(column.key))
|
|
345
|
+
: [];
|
|
346
|
+
const visible = storedColumns
|
|
347
|
+
.filter(column => column.visible)
|
|
348
|
+
.map(column => column.key);
|
|
349
|
+
const nextVisible = visible.length
|
|
350
|
+
? visible
|
|
351
|
+
: defaults.columns.filter(column => column.visible).map(column => column.key);
|
|
352
|
+
const allowedFilters = new Set(surface.list?.filterFields || []);
|
|
353
|
+
const filterValues = preference?.filters?.values &&
|
|
354
|
+
typeof preference.filters.values === 'object' &&
|
|
355
|
+
!Array.isArray(preference.filters.values)
|
|
356
|
+
? Object.fromEntries(Object.entries(preference.filters.values).filter(([key]) => allowedFilters.has(key)))
|
|
357
|
+
: {};
|
|
358
|
+
const keyword = (surface.list?.searchableFields || []).length &&
|
|
359
|
+
typeof preference?.filters?.keyword === 'string'
|
|
360
|
+
? preference.filters.keyword
|
|
361
|
+
: undefined;
|
|
362
|
+
const storedSort = preference?.sorts?.[0];
|
|
363
|
+
const sortableFields = new Set(fields.filter(field => field.sortable).map(field => field.key));
|
|
364
|
+
const nextSort = storedSort && sortableFields.has(storedSort.field)
|
|
365
|
+
? {
|
|
366
|
+
field: storedSort.field,
|
|
367
|
+
order: storedSort.direction === 'descend' ? 'desc' : 'asc',
|
|
368
|
+
}
|
|
369
|
+
: defaults.sorts[0]
|
|
370
|
+
? {
|
|
371
|
+
field: defaults.sorts[0].field,
|
|
372
|
+
order: defaults.sorts[0].direction === 'descend' ? 'desc' : 'asc',
|
|
373
|
+
}
|
|
374
|
+
: state.sort;
|
|
375
|
+
const nextDensity = ['small', 'middle', 'large'].includes(String(preference?.density || ''))
|
|
376
|
+
? preference.density
|
|
377
|
+
: defaults.density;
|
|
378
|
+
const nextPageSize = Number.isSafeInteger(preference?.pageSize) &&
|
|
379
|
+
Number(preference?.pageSize) >= 10 &&
|
|
380
|
+
Number(preference?.pageSize) <= 100
|
|
381
|
+
? Number(preference.pageSize)
|
|
382
|
+
: defaults.pageSize;
|
|
383
|
+
const nextQuery = {
|
|
384
|
+
...(keyword ? { keyword } : {}),
|
|
385
|
+
...(Object.keys(filterValues).length ? { filters: filterValues } : {}),
|
|
386
|
+
};
|
|
387
|
+
setVisibleColumnKeys(nextVisible);
|
|
388
|
+
setDensity(nextDensity);
|
|
389
|
+
state.setDraft(nextQuery);
|
|
390
|
+
state.setQuery(nextQuery);
|
|
391
|
+
state.setSort(nextSort);
|
|
392
|
+
state.setPageSize(nextPageSize);
|
|
393
|
+
state.setPage(1);
|
|
394
|
+
const normalized = {
|
|
395
|
+
version: 1,
|
|
396
|
+
columns: configurableColumns.map(column => ({
|
|
397
|
+
key: column.key,
|
|
398
|
+
visible: nextVisible.includes(column.key),
|
|
399
|
+
})),
|
|
400
|
+
filters: {
|
|
401
|
+
...(keyword ? { keyword } : {}),
|
|
402
|
+
...(Object.keys(filterValues).length ? { values: filterValues } : {}),
|
|
403
|
+
},
|
|
404
|
+
sorts: [{
|
|
405
|
+
field: nextSort.field,
|
|
406
|
+
direction: nextSort.order === 'asc' ? 'ascend' : 'descend',
|
|
407
|
+
}],
|
|
408
|
+
density: nextDensity,
|
|
409
|
+
pageSize: nextPageSize,
|
|
410
|
+
};
|
|
411
|
+
setHasSavedPreference(Boolean(preference));
|
|
412
|
+
setSavedPreferenceFingerprint(preferenceFingerprint(normalized));
|
|
413
|
+
setPreferenceReady(true);
|
|
414
|
+
})
|
|
415
|
+
.catch(() => {
|
|
416
|
+
if (!active)
|
|
417
|
+
return;
|
|
418
|
+
setHasSavedPreference(false);
|
|
419
|
+
setSavedPreferenceFingerprint(preferenceFingerprint(defaults));
|
|
420
|
+
setPreferenceReady(true);
|
|
421
|
+
});
|
|
422
|
+
return () => {
|
|
423
|
+
active = false;
|
|
424
|
+
};
|
|
425
|
+
// Resource changes remount the generated page and own preference scope.
|
|
426
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
427
|
+
}, [code]);
|
|
428
|
+
const firstVisibleBusinessField = fields.find(field => visibleColumnKeys.includes(field.key));
|
|
265
429
|
const columns = useMemo(() => [
|
|
266
430
|
...fields
|
|
267
431
|
.filter((field) => visibleColumnKeys.includes(field.key))
|
|
@@ -269,18 +433,27 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
269
433
|
title: field.label,
|
|
270
434
|
dataIndex: field.key,
|
|
271
435
|
key: field.key,
|
|
436
|
+
align: field.type === 'number.integer' || field.type === 'number.decimal'
|
|
437
|
+
? 'right'
|
|
438
|
+
: undefined,
|
|
272
439
|
sorter: Boolean(field.sortable),
|
|
273
440
|
render: (value, record) => {
|
|
274
441
|
const rendered = (_jsx(SurfaceFieldValue, { field: field, resourceCode: code, value: value }));
|
|
275
|
-
return field.key ===
|
|
442
|
+
return field.key === firstVisibleBusinessField?.key && generated.detail ? (_jsx("a", { onClick: () => navigate(resourceRecordPath(paths.detail, record.id)), children: rendered })) : rendered;
|
|
276
443
|
},
|
|
277
444
|
})),
|
|
278
|
-
{
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
445
|
+
...(visibleColumnKeys.includes('created_at') ? [{
|
|
446
|
+
title: '创建时间',
|
|
447
|
+
dataIndex: 'created_at',
|
|
448
|
+
key: 'created_at',
|
|
449
|
+
render: (value) => (value ? new Date(String(value)).toLocaleString('zh-CN') : '-'),
|
|
450
|
+
}] : []),
|
|
451
|
+
...(visibleColumnKeys.includes('updated_at') ? [{
|
|
452
|
+
title: '更新时间',
|
|
453
|
+
dataIndex: 'updated_at',
|
|
454
|
+
key: 'updated_at',
|
|
455
|
+
render: (value) => (value ? new Date(String(value)).toLocaleString('zh-CN') : '-'),
|
|
456
|
+
}] : []),
|
|
284
457
|
{
|
|
285
458
|
title: '操作',
|
|
286
459
|
key: 'actions',
|
|
@@ -305,6 +478,7 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
305
478
|
capabilities.update,
|
|
306
479
|
code,
|
|
307
480
|
fields,
|
|
481
|
+
firstVisibleBusinessField,
|
|
308
482
|
hasCapability,
|
|
309
483
|
message,
|
|
310
484
|
name,
|
|
@@ -327,6 +501,61 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
327
501
|
setExporting(false);
|
|
328
502
|
}
|
|
329
503
|
};
|
|
504
|
+
const savePreference = async () => {
|
|
505
|
+
setPreferenceSaving(true);
|
|
506
|
+
try {
|
|
507
|
+
const saved = await saveResourceListPreference(listKey, preferencePayload());
|
|
508
|
+
setSavedPreferenceFingerprint(preferenceFingerprint(saved));
|
|
509
|
+
setHasSavedPreference(true);
|
|
510
|
+
message.success('列表设置已保存');
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
message.error(error instanceof Error ? error.message : '列表设置保存失败');
|
|
514
|
+
}
|
|
515
|
+
finally {
|
|
516
|
+
setPreferenceSaving(false);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
const restorePreference = async () => {
|
|
520
|
+
setPreferenceSaving(true);
|
|
521
|
+
try {
|
|
522
|
+
await resetResourceListPreference(listKey);
|
|
523
|
+
const nextVisible = configurableColumns.map(column => column.key);
|
|
524
|
+
const defaultSortField = surface.list?.defaultSort?.field || fields[0]?.key || 'id';
|
|
525
|
+
const defaultSortOrder = surface.list?.defaultSort?.order || 'asc';
|
|
526
|
+
const defaultPageSize = surface.list?.defaultPageSize || 20;
|
|
527
|
+
setVisibleColumnKeys(nextVisible);
|
|
528
|
+
setDensity('middle');
|
|
529
|
+
state.setDraft({});
|
|
530
|
+
state.setQuery({});
|
|
531
|
+
state.setSort({ field: defaultSortField, order: defaultSortOrder });
|
|
532
|
+
state.setPageSize(defaultPageSize);
|
|
533
|
+
state.setPage(1);
|
|
534
|
+
const restored = {
|
|
535
|
+
version: 1,
|
|
536
|
+
columns: configurableColumns.map(column => ({
|
|
537
|
+
key: column.key,
|
|
538
|
+
visible: true,
|
|
539
|
+
})),
|
|
540
|
+
filters: {},
|
|
541
|
+
sorts: [{
|
|
542
|
+
field: defaultSortField,
|
|
543
|
+
direction: defaultSortOrder === 'asc' ? 'ascend' : 'descend',
|
|
544
|
+
}],
|
|
545
|
+
density: 'middle',
|
|
546
|
+
pageSize: defaultPageSize,
|
|
547
|
+
};
|
|
548
|
+
setSavedPreferenceFingerprint(preferenceFingerprint(restored));
|
|
549
|
+
setHasSavedPreference(false);
|
|
550
|
+
message.success('已恢复平台默认设置');
|
|
551
|
+
}
|
|
552
|
+
catch (error) {
|
|
553
|
+
message.error(error instanceof Error ? error.message : '恢复默认设置失败');
|
|
554
|
+
}
|
|
555
|
+
finally {
|
|
556
|
+
setPreferenceSaving(false);
|
|
557
|
+
}
|
|
558
|
+
};
|
|
330
559
|
const filterFields = (surface.list?.filterFields || []).filter((field) => readableFieldCodes.has(field));
|
|
331
560
|
const searchableFields = (surface.list?.searchableFields || []).filter((field) => readableFieldCodes.has(field));
|
|
332
561
|
const primaryFilterFields = filterFields.slice(0, 2);
|
|
@@ -365,7 +594,7 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
365
594
|
})),
|
|
366
595
|
];
|
|
367
596
|
const columnMenu = {
|
|
368
|
-
items:
|
|
597
|
+
items: configurableColumns.map((column) => ({ key: column.key, label: column.label })),
|
|
369
598
|
multiple: true,
|
|
370
599
|
selectable: true,
|
|
371
600
|
selectedKeys: visibleColumnKeys,
|
|
@@ -412,11 +641,11 @@ function GeneratedDesktopList({ definition, paths }) {
|
|
|
412
641
|
}, open: moreFiltersOpen, title: "\u66F4\u591A\u7B5B\u9009", width: 860, children: _jsx("div", { className: "oxa-more-filter-grid", children: additionalFilterFields.map(key => {
|
|
413
642
|
const field = fieldFor(surface, key);
|
|
414
643
|
return (_jsxs("div", { className: "oxa-more-filter-field", children: [_jsx("label", { children: field.label }), _jsx(SurfaceFilterControl, { field: field, resourceCode: code, onChange: (value) => setMoreFilterDraft(current => ({ ...current, [key]: value })), value: moreFilterDraft[key] })] }, key));
|
|
415
|
-
}) }) }), _jsxs("div", { className: "oxa-list-toolbar", children: [_jsxs(Space, { className: "oxa-list-toolbar-primary", wrap: true, children: [generated.create && hasCapability(capabilities.create) && (_jsxs(Button, { icon: _jsx(PlusOutlined, {}), onClick: () => navigate(paths.create), type: "primary", children: ["\u65B0\u589E", name] })), generated.create && hasCapability(capabilities.create) && (_jsx(ResourceImportButton, { code: code, name: name, surface: surface, writableFieldCodes: importWritableFieldCodes, onCompleted: () => state.list.query.refetch() })), _jsx(Button, { icon: _jsx(ExportOutlined, {}), loading: exporting, onClick: () => void handleExport(), children: "\u5BFC\u51FA" }), toolbarContributions.map((contribution) => (_jsx(Fragment, { children: contribution.render({
|
|
644
|
+
}) }) }), _jsxs("div", { className: "oxa-list-toolbar", children: [_jsxs(Space, { className: "oxa-list-toolbar-primary", wrap: true, children: [generated.create && hasCapability(capabilities.create) && (_jsxs(Button, { icon: _jsx(PlusOutlined, {}), onClick: () => navigate(paths.create), type: "primary", children: ["\u65B0\u589E", name] })), standardWorkflow?.processOperationCode && (_jsx(WorkflowResourceImportButton, { code: code, name: name, onCompleted: () => state.list.query.refetch(), processOperationCode: standardWorkflow.processOperationCode, surface: surface, workflowCode: standardWorkflow.code, writableFieldCodes: workflowImportFieldCodes })), generated.create && hasCapability(capabilities.create) && (_jsx(ResourceImportButton, { code: code, name: name, surface: surface, writableFieldCodes: importWritableFieldCodes, onCompleted: () => state.list.query.refetch() })), _jsx(Button, { icon: _jsx(ExportOutlined, {}), loading: exporting, onClick: () => void handleExport(), children: "\u5BFC\u51FA" }), toolbarContributions.map((contribution) => (_jsx(Fragment, { children: contribution.render({
|
|
416
645
|
resource: code,
|
|
417
646
|
selectedRecords: selectedRows,
|
|
418
647
|
refresh: () => state.list.query.refetch(),
|
|
419
|
-
}) }, contribution.code)))] }), _jsxs(Space, { className: "oxa-list-toolbar-secondary", size: 4, children: [_jsx(Tooltip, { title: "\u5237\u65B0", children: _jsx(Button, { "aria-label": "\u5237\u65B0\u6570\u636E", icon: _jsx(ReloadOutlined, {}), loading: state.list.query.isFetching, onClick: () => void state.list.query.refetch(), type: "text" }) }), _jsx(Dropdown, { menu: columnMenu, trigger: ['click'], children: _jsx(Button, { icon: _jsx(SettingOutlined, {}), type: "text", children: "\u5217\u8BBE\u7F6E" }) }), _jsx(Dropdown, { menu: densityMenu, trigger: ['click'], children: _jsx(Button, { icon: _jsx(ColumnHeightOutlined, {}), type: "text", children: "\u5BC6\u5EA6" }) })] })] }), _jsx(ResourceBatchActions, { canDelete: Boolean(generated.delete && hasCapability(capabilities.delete)), code: code, name: name, onClear: () => setSelectedRowKeys([]), onCompleted: () => state.list.query.refetch(), rows: selectedRows, surface: surface, writableFields: batchWritableFields }), _jsx(Table, { columns: columns, dataSource: rows, loading: state.list.query.isFetching, locale: { emptyText: _jsx(Empty, { description: `暂无${name}` }) }, rowKey: "id", rowSelection: canBatch
|
|
648
|
+
}) }, contribution.code)))] }), _jsxs(Space, { className: "oxa-list-toolbar-secondary", size: 4, children: [preferenceDirty && (_jsx(Button, { icon: _jsx(SaveOutlined, {}), loading: preferenceSaving, onClick: () => void savePreference(), type: "primary", children: "\u4FDD\u5B58\u8BBE\u7F6E" })), hasSavedPreference && !preferenceDirty && (_jsx(Button, { icon: _jsx(UndoOutlined, {}), loading: preferenceSaving, onClick: () => void restorePreference(), type: "text", children: "\u6062\u590D\u9ED8\u8BA4" })), _jsx(Tooltip, { title: "\u5237\u65B0", children: _jsx(Button, { "aria-label": "\u5237\u65B0\u6570\u636E", icon: _jsx(ReloadOutlined, {}), loading: state.list.query.isFetching, onClick: () => void state.list.query.refetch(), type: "text" }) }), _jsx(Dropdown, { menu: columnMenu, trigger: ['click'], children: _jsx(Button, { icon: _jsx(SettingOutlined, {}), type: "text", children: "\u5217\u8BBE\u7F6E" }) }), _jsx(Dropdown, { menu: densityMenu, trigger: ['click'], children: _jsx(Button, { icon: _jsx(ColumnHeightOutlined, {}), type: "text", children: "\u5BC6\u5EA6" }) })] })] }), _jsx(ResourceBatchActions, { canDelete: Boolean(generated.delete && hasCapability(capabilities.delete)), code: code, name: name, onClear: () => setSelectedRowKeys([]), onCompleted: () => state.list.query.refetch(), rows: selectedRows, surface: surface, writableFields: batchWritableFields }), _jsx(Table, { columns: columns, dataSource: rows, loading: state.list.query.isFetching, locale: { emptyText: _jsx(Empty, { description: `暂无${name}` }) }, rowKey: "id", rowSelection: canBatch
|
|
420
649
|
? {
|
|
421
650
|
selectedRowKeys,
|
|
422
651
|
onChange: (keys) => {
|
|
@@ -682,7 +911,6 @@ function GeneratedResourceDetailPage({ definition, paths, variant }) {
|
|
|
682
911
|
resource: definition.code,
|
|
683
912
|
refresh: () => query.query.refetch(),
|
|
684
913
|
}) }, contribution.code))) })) : null,
|
|
685
|
-
auditTargetId: `${definition.code}-audit`,
|
|
686
914
|
backLabel: `返回${definition.name}`,
|
|
687
915
|
backPath: paths.list || paths.fallback,
|
|
688
916
|
editCapability: definition.surface.generated?.update
|
|
@@ -694,8 +922,6 @@ function GeneratedResourceDetailPage({ definition, paths, variant }) {
|
|
|
694
922
|
error: query.query.isError || (!query.query.isFetching && !record) ? query.query.error?.message || '记录不存在' : undefined,
|
|
695
923
|
hero,
|
|
696
924
|
loading: query.query.isFetching,
|
|
697
|
-
meta: record ? _jsxs("span", { children: ["\u6700\u8FD1\u66F4\u65B0 ", record.updated_at ? new Date(record.updated_at).toLocaleString('zh-CN') : '-'] }) : null,
|
|
698
|
-
onAuditOpen: () => setAuditExpanded(true),
|
|
699
925
|
readCapability: definition.capabilities.read,
|
|
700
926
|
resource: definition.code,
|
|
701
927
|
surface: definition.surface,
|