openxiangda 2.62.1 → 2.65.0

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.
Files changed (197) hide show
  1. package/dist/browser/AuthoritativeSelector.d.ts +4 -3
  2. package/dist/browser/AuthoritativeSelector.d.ts.map +1 -1
  3. package/dist/browser/AuthoritativeSelector.js +25 -16
  4. package/dist/browser/AuthoritativeSelector.js.map +1 -1
  5. package/dist/browser/admin-contributions.d.ts +26 -0
  6. package/dist/browser/admin-contributions.d.ts.map +1 -1
  7. package/dist/browser/admin-contributions.js +30 -0
  8. package/dist/browser/admin-contributions.js.map +1 -1
  9. package/dist/browser/components/platform-fields/AttachmentFileList.d.ts +2 -1
  10. package/dist/browser/components/platform-fields/AttachmentFileList.d.ts.map +1 -1
  11. package/dist/browser/components/platform-fields/AttachmentFileList.js +3 -3
  12. package/dist/browser/components/platform-fields/AttachmentFileList.js.map +1 -1
  13. package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts +4 -2
  14. package/dist/browser/components/platform-fields/ResourceReferenceField.d.ts.map +1 -1
  15. package/dist/browser/components/platform-fields/ResourceReferenceField.js +4 -4
  16. package/dist/browser/components/platform-fields/ResourceReferenceField.js.map +1 -1
  17. package/dist/browser/components/platform-fields/address-value.d.ts +2 -12
  18. package/dist/browser/components/platform-fields/address-value.d.ts.map +1 -1
  19. package/dist/browser/components/platform-fields/address-value.js +1 -69
  20. package/dist/browser/components/platform-fields/address-value.js.map +1 -1
  21. package/dist/browser/components/platform-fields/cascade-value.d.ts +2 -5
  22. package/dist/browser/components/platform-fields/cascade-value.d.ts.map +1 -1
  23. package/dist/browser/components/platform-fields/cascade-value.js +1 -46
  24. package/dist/browser/components/platform-fields/cascade-value.js.map +1 -1
  25. package/dist/browser/components/platform-fields/resource-query.d.ts +3 -19
  26. package/dist/browser/components/platform-fields/resource-query.d.ts.map +1 -1
  27. package/dist/browser/components/platform-fields/resource-query.js +2 -153
  28. package/dist/browser/components/platform-fields/resource-query.js.map +1 -1
  29. package/dist/browser/components/resource/GeneratedResourceCrud.d.ts +393 -2
  30. package/dist/browser/components/resource/GeneratedResourceCrud.d.ts.map +1 -1
  31. package/dist/browser/components/resource/GeneratedResourceCrud.js +148 -71
  32. package/dist/browser/components/resource/GeneratedResourceCrud.js.map +1 -1
  33. package/dist/browser/components/resource/GeneratedResourceForm.d.ts.map +1 -1
  34. package/dist/browser/components/resource/GeneratedResourceForm.js +7 -1
  35. package/dist/browser/components/resource/GeneratedResourceForm.js.map +1 -1
  36. package/dist/browser/components/resource/RecordDetailFrame.d.ts +4 -1
  37. package/dist/browser/components/resource/RecordDetailFrame.d.ts.map +1 -1
  38. package/dist/browser/components/resource/RecordDetailFrame.js +4 -2
  39. package/dist/browser/components/resource/RecordDetailFrame.js.map +1 -1
  40. package/dist/browser/components/resource/SurfaceFields.d.ts +4 -1
  41. package/dist/browser/components/resource/SurfaceFields.d.ts.map +1 -1
  42. package/dist/browser/components/resource/SurfaceFields.js +8 -8
  43. package/dist/browser/components/resource/SurfaceFields.js.map +1 -1
  44. package/dist/browser/components/resource/useResourceFormDrafts.d.ts.map +1 -1
  45. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts +5 -2
  46. package/dist/browser/components/workflow/StandardWorkflowPages.d.ts.map +1 -1
  47. package/dist/browser/components/workflow/StandardWorkflowPages.js +107 -64
  48. package/dist/browser/components/workflow/StandardWorkflowPages.js.map +1 -1
  49. package/dist/browser/components/workflow/WorkflowBusinessStepEditor.d.ts +11 -0
  50. package/dist/browser/components/workflow/WorkflowBusinessStepEditor.d.ts.map +1 -0
  51. package/dist/browser/components/workflow/WorkflowBusinessStepEditor.js +55 -0
  52. package/dist/browser/components/workflow/WorkflowBusinessStepEditor.js.map +1 -0
  53. package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.d.ts.map +1 -1
  54. package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.js +13 -8
  55. package/dist/browser/components/workflow/WorkflowBusinessStepRecoveryPanel.js.map +1 -1
  56. package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.d.ts +18 -0
  57. package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.d.ts.map +1 -0
  58. package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.js +30 -0
  59. package/dist/browser/components/workflow/WorkflowConditionConfigurationEditor.js.map +1 -0
  60. package/dist/browser/components/workflow/WorkflowConditionEditor.d.ts +9 -0
  61. package/dist/browser/components/workflow/WorkflowConditionEditor.d.ts.map +1 -0
  62. package/dist/browser/components/workflow/WorkflowConditionEditor.js +33 -0
  63. package/dist/browser/components/workflow/WorkflowConditionEditor.js.map +1 -0
  64. package/dist/browser/components/workflow/WorkflowConditionExamples.d.ts +11 -0
  65. package/dist/browser/components/workflow/WorkflowConditionExamples.d.ts.map +1 -0
  66. package/dist/browser/components/workflow/WorkflowConditionExamples.js +52 -0
  67. package/dist/browser/components/workflow/WorkflowConditionExamples.js.map +1 -0
  68. package/dist/browser/components/workflow/WorkflowDesigner.d.ts +14 -0
  69. package/dist/browser/components/workflow/WorkflowDesigner.d.ts.map +1 -0
  70. package/dist/browser/components/workflow/WorkflowDesigner.js +586 -0
  71. package/dist/browser/components/workflow/WorkflowDesigner.js.map +1 -0
  72. package/dist/browser/components/workflow/WorkflowDesignerAssistant.d.ts +16 -0
  73. package/dist/browser/components/workflow/WorkflowDesignerAssistant.d.ts.map +1 -0
  74. package/dist/browser/components/workflow/WorkflowDesignerAssistant.js +75 -0
  75. package/dist/browser/components/workflow/WorkflowDesignerAssistant.js.map +1 -0
  76. package/dist/browser/components/workflow/WorkflowDiagram.d.ts +8 -2
  77. package/dist/browser/components/workflow/WorkflowDiagram.d.ts.map +1 -1
  78. package/dist/browser/components/workflow/WorkflowDiagram.js +6 -6
  79. package/dist/browser/components/workflow/WorkflowDiagram.js.map +1 -1
  80. package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.d.ts +19 -0
  81. package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.d.ts.map +1 -0
  82. package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.js +22 -0
  83. package/dist/browser/components/workflow/WorkflowDraftHandlingEditor.js.map +1 -0
  84. package/dist/browser/components/workflow/WorkflowFlowCanvas.d.ts +7 -0
  85. package/dist/browser/components/workflow/WorkflowFlowCanvas.d.ts.map +1 -1
  86. package/dist/browser/components/workflow/WorkflowFlowCanvas.js +84 -23
  87. package/dist/browser/components/workflow/WorkflowFlowCanvas.js.map +1 -1
  88. package/dist/browser/components/workflow/WorkflowNodeCard.d.ts +2 -1
  89. package/dist/browser/components/workflow/WorkflowNodeCard.d.ts.map +1 -1
  90. package/dist/browser/components/workflow/WorkflowNodeCard.js +12 -10
  91. package/dist/browser/components/workflow/WorkflowNodeCard.js.map +1 -1
  92. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.d.ts +13 -2
  93. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.d.ts.map +1 -1
  94. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js +70 -23
  95. package/dist/browser/components/workflow/WorkflowNodeConfigurationEditor.js.map +1 -1
  96. package/dist/browser/components/workflow/WorkflowNotificationEditor.d.ts +20 -0
  97. package/dist/browser/components/workflow/WorkflowNotificationEditor.d.ts.map +1 -0
  98. package/dist/browser/components/workflow/WorkflowNotificationEditor.js +18 -0
  99. package/dist/browser/components/workflow/WorkflowNotificationEditor.js.map +1 -0
  100. package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.d.ts +10 -0
  101. package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.d.ts.map +1 -0
  102. package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.js +24 -0
  103. package/dist/browser/components/workflow/WorkflowParallelConfigurationEditor.js.map +1 -0
  104. package/dist/browser/components/workflow/WorkflowPeopleSourceEditor.d.ts +9 -0
  105. package/dist/browser/components/workflow/WorkflowPeopleSourceEditor.d.ts.map +1 -0
  106. package/dist/browser/components/workflow/WorkflowPeopleSourceEditor.js +13 -0
  107. package/dist/browser/components/workflow/WorkflowPeopleSourceEditor.js.map +1 -0
  108. package/dist/browser/components/workflow/WorkflowReminderEditor.d.ts +9 -0
  109. package/dist/browser/components/workflow/WorkflowReminderEditor.d.ts.map +1 -0
  110. package/dist/browser/components/workflow/WorkflowReminderEditor.js +23 -0
  111. package/dist/browser/components/workflow/WorkflowReminderEditor.js.map +1 -0
  112. package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.d.ts +8 -0
  113. package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.d.ts.map +1 -0
  114. package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.js +34 -0
  115. package/dist/browser/components/workflow/WorkflowReturnPolicyEditor.js.map +1 -0
  116. package/dist/browser/components/workflow/WorkflowTaskForm.d.ts +1 -4
  117. package/dist/browser/components/workflow/WorkflowTaskForm.d.ts.map +1 -1
  118. package/dist/browser/components/workflow/WorkflowTaskForm.js +5 -6
  119. package/dist/browser/components/workflow/WorkflowTaskForm.js.map +1 -1
  120. package/dist/browser/components/workflow/workflow-approval-presentation.d.ts +13 -0
  121. package/dist/browser/components/workflow/workflow-approval-presentation.d.ts.map +1 -0
  122. package/dist/browser/components/workflow/workflow-approval-presentation.js +21 -0
  123. package/dist/browser/components/workflow/workflow-approval-presentation.js.map +1 -0
  124. package/dist/browser/components/workflow/workflow-designer-presentation.d.ts +13 -0
  125. package/dist/browser/components/workflow/workflow-designer-presentation.d.ts.map +1 -0
  126. package/dist/browser/components/workflow/workflow-designer-presentation.js +69 -0
  127. package/dist/browser/components/workflow/workflow-designer-presentation.js.map +1 -0
  128. package/dist/browser/components/workflow/workflow-flow-layout.d.ts +21 -11
  129. package/dist/browser/components/workflow/workflow-flow-layout.d.ts.map +1 -1
  130. package/dist/browser/components/workflow/workflow-flow-layout.js +28 -18
  131. package/dist/browser/components/workflow/workflow-flow-layout.js.map +1 -1
  132. package/dist/browser/components/workflow/workflow-operation-layout.d.ts +6 -0
  133. package/dist/browser/components/workflow/workflow-operation-layout.d.ts.map +1 -0
  134. package/dist/browser/components/workflow/workflow-operation-layout.js +17 -0
  135. package/dist/browser/components/workflow/workflow-operation-layout.js.map +1 -0
  136. package/dist/browser/components/workflow/workflow-parallel-layout.d.ts +37 -0
  137. package/dist/browser/components/workflow/workflow-parallel-layout.d.ts.map +1 -0
  138. package/dist/browser/components/workflow/workflow-parallel-layout.js +176 -0
  139. package/dist/browser/components/workflow/workflow-parallel-layout.js.map +1 -0
  140. package/dist/browser/platform-client.d.ts +71 -3
  141. package/dist/browser/platform-client.d.ts.map +1 -1
  142. package/dist/browser/platform-client.js +54 -4
  143. package/dist/browser/platform-client.js.map +1 -1
  144. package/dist/browser/record-detail.css +4 -3
  145. package/dist/browser/styles.css +386 -1
  146. package/dist/browser/workflow-approval.css +205 -0
  147. package/dist/browser/workflow-operation-input.d.ts.map +1 -1
  148. package/dist/browser/workflow-operation-input.js +1 -0
  149. package/dist/browser/workflow-operation-input.js.map +1 -1
  150. package/dist/config.d.ts +1 -0
  151. package/dist/config.d.ts.map +1 -1
  152. package/dist/core.d.ts +1 -0
  153. package/dist/core.d.ts.map +1 -1
  154. package/dist/core.js +1 -0
  155. package/dist/core.js.map +1 -1
  156. package/dist/react.d.ts +1 -0
  157. package/dist/react.d.ts.map +1 -1
  158. package/dist/react.js +1 -0
  159. package/dist/react.js.map +1 -1
  160. package/dist/resource.d.ts +22 -0
  161. package/dist/resource.d.ts.map +1 -0
  162. package/dist/resource.js +18 -0
  163. package/dist/resource.js.map +1 -0
  164. package/documentation/AGENTS.md +1 -1
  165. package/documentation/application-templates.md +37 -0
  166. package/documentation/field-components.md +10 -1
  167. package/documentation/frontend.md +14 -4
  168. package/documentation/getting-started.md +9 -7
  169. package/documentation/manifest.json +13 -7
  170. package/documentation/reference/cli.md +2 -0
  171. package/documentation/reference/mcp.md +238 -0
  172. package/documentation/workflow-events.md +33 -0
  173. package/package.json +26 -26
  174. package/releases/2.64.0.json +30 -0
  175. package/releases/2.65.0.json +30 -0
  176. package/skills/manifest.json +1 -1
  177. package/skills/openxiangda-v2/SKILL.md +7 -7
  178. package/skills/openxiangda-v2/references/application-templates.md +37 -0
  179. package/skills/openxiangda-v2/references/cli.md +2 -0
  180. package/skills/openxiangda-v2/references/field-components.md +10 -1
  181. package/skills/openxiangda-v2/references/frontend.md +14 -4
  182. package/skills/openxiangda-v2/references/getting-started.md +9 -7
  183. package/skills/openxiangda-v2/references/mcp.md +238 -0
  184. package/skills/openxiangda-v2/references/workflow-events.md +33 -0
  185. package/releases/2.20.1.json +0 -30
  186. package/releases/2.20.2.json +0 -30
  187. package/releases/2.20.3.json +0 -29
  188. package/releases/2.20.4.json +0 -30
  189. package/releases/2.31.5.json +0 -33
  190. package/releases/2.59.3.json +0 -36
  191. package/releases/2.60.0.json +0 -38
  192. package/releases/2.61.0.json +0 -39
  193. package/releases/2.61.1.json +0 -37
  194. package/releases/2.61.2.json +0 -32
  195. package/releases/2.61.3.json +0 -33
  196. package/releases/2.62.0.json +0 -40
  197. package/releases/2.62.1.json +0 -34
@@ -12,7 +12,7 @@ import { SurfaceFieldValue, } from './SurfaceFields';
12
12
  import { createNativeResourceClient, loadResourceListPreference, platformReadErrorMessage, resetResourceListPreference, saveResourceListPreference, } from '../../platform-client';
13
13
  import { useRuntime } from '../../runtime';
14
14
  import { ResourceBatchActions, ResourceImportButton, WorkflowResourceImportButton, } from './ResourceBatchActions';
15
- import { isAdminContributionAllowed, useAdminResourceContributions, } from '../../admin-contributions';
15
+ import { isAdminContributionAllowed, useAdminResourceContributions, useResourcePageContributions, } from '../../admin-contributions';
16
16
  import { SubtableValueDisplay, } from '../platform-fields/SubtableField';
17
17
  import { selectedSurfaceFields } from './resource-field-selection';
18
18
  import { ResourceRecordComments } from './ResourceRecordComments';
@@ -30,6 +30,7 @@ import { RecordDetailFrame, RecordDetailSections, detailTime } from './RecordDet
30
30
  import { RecordChangeHistory } from './RecordChangeHistory';
31
31
  import { WorkflowRecordEditor } from '../workflow/WorkflowRecordEditor';
32
32
  import { WorkflowRecordHistoryPanel } from '../workflow/WorkflowRecordHistoryPanel';
33
+ import { StandardUserSurfaceErrorBoundary } from '../../standard-user-surfaces';
33
34
  async function exportResourceRows(code, name, surface, fields, query, sorts) {
34
35
  const client = createNativeResourceClient(code, surface);
35
36
  const exported = await client.exportCsv({
@@ -105,9 +106,11 @@ function useGeneratedList(definition, readableFieldCodes) {
105
106
  sorts,
106
107
  };
107
108
  }
108
- export function GeneratedResourcePage({ resourceCode, viewCode, mode = 'list', variant = 'desktop', definition: providedDefinition, paths, }) {
109
+ export function GeneratedResourcePage({ resourceCode, viewCode, mode = 'list', variant = 'desktop', definition: providedDefinition, paths, ...lifecycle }) {
109
110
  const definitions = useResourceDefinitions();
110
111
  const params = useParams();
112
+ const { hasCapability, hasReadCapability } = useRuntime();
113
+ const pages = useResourcePageContributions(resourceCode, viewCode ?? providedDefinition?.viewCode);
111
114
  const definition = useMemo(() => {
112
115
  const base = providedDefinition || definitions[resourceCode];
113
116
  if (!base || viewCode === undefined)
@@ -126,17 +129,25 @@ export function GeneratedResourcePage({ resourceCode, viewCode, mode = 'list', v
126
129
  (generated.update && !paths.edit)) {
127
130
  return _jsx(Result, { status: "500", title: "\u751F\u6210\u8D44\u6E90\u8DEF\u7531\u5408\u540C\u4E0D\u5B8C\u6574" });
128
131
  }
129
- const pageKey = `${mode}:${resourceCode}:${viewCode || ""}:${params.id || ''}`;
132
+ const permitted = mode === 'list' || mode === 'detail'
133
+ ? hasReadCapability(definition.capabilities.read)
134
+ : hasCapability(definition.capabilities[mode === 'edit' ? 'update' : 'create']);
135
+ if (!permitted)
136
+ return _jsx(Result, { status: "403", title: "\u5F53\u524D\u5E73\u53F0\u7528\u6237\u65E0\u6B64\u9875\u9762\u6743\u9650" });
137
+ const Page = pages?.[mode === 'create' || mode === 'edit' ? 'form' : mode];
138
+ const pageKey = `${mode}:${resourceCode}:${viewCode || ""}:${lifecycle.recordId || params.id || ''}`;
139
+ if (Page)
140
+ return _jsx(StandardUserSurfaceErrorBoundary, { resetKey: pageKey, children: _jsx(Page, { definition: definition, paths: paths, variant: variant, mode: mode, ...lifecycle }) });
130
141
  if (mode === 'list')
131
142
  return _jsx(GeneratedResourceListPage, { definition: definition, paths: paths, variant: variant }, pageKey);
132
143
  if (mode === 'detail')
133
- return _jsx(GeneratedResourceDetailPage, { definition: definition, paths: paths, variant: variant }, pageKey);
134
- return _jsx(GeneratedResourceFormPage, { definition: definition, mode: mode, paths: paths, variant: variant }, pageKey);
144
+ return _jsx(GeneratedResourceDetailPage, { definition: definition, paths: paths, variant: variant, ...lifecycle }, pageKey);
145
+ return _jsx(GeneratedResourceFormPage, { definition: definition, mode: mode, paths: paths, variant: variant, ...lifecycle }, pageKey);
135
146
  }
136
147
  function GeneratedResourceListPage({ definition, paths, variant }) {
137
148
  return variant === 'mobile' ? _jsx(GeneratedMobileList, { definition: definition, paths: paths }) : _jsx(GeneratedDesktopList, { definition: definition, paths: paths });
138
149
  }
139
- function GeneratedDesktopList({ definition, paths }) {
150
+ export function useResourceListController({ definition, paths, columnRenderers }) {
140
151
  const navigate = useNavigate();
141
152
  const { message } = App.useApp();
142
153
  const { hasCapability, hasReadCapability, identity } = useRuntime();
@@ -321,7 +332,7 @@ function GeneratedDesktopList({ definition, paths }) {
321
332
  sorter: field.sortable ? { multiple: Math.max(1, fields.length - state.sorts.findIndex(sort => sort.field === field.key)) } : false,
322
333
  sortOrder: state.sorts.find(sort => sort.field === field.key)?.order === 'asc' ? 'ascend' : state.sorts.find(sort => sort.field === field.key)?.order === 'desc' ? 'descend' : null,
323
334
  render: (value, record) => {
324
- const rendered = (_jsx(SurfaceFieldValue, { field: field, resourceCode: code, value: value }));
335
+ const rendered = columnRenderers?.[field.key] ? columnRenderers[field.key]({ value, record, field }) : (_jsx(SurfaceFieldValue, { field: field, resourceCode: code, value: value }));
325
336
  return field.key === firstVisibleBusinessField?.key && generated.detail ? (_jsx("a", { onClick: () => setDetailId(record.id), children: rendered })) : rendered;
326
337
  },
327
338
  })),
@@ -364,6 +375,7 @@ function GeneratedDesktopList({ definition, paths }) {
364
375
  }) }, contribution.code)))] })),
365
376
  },
366
377
  ], [
378
+ columnRenderers,
367
379
  capabilities.delete,
368
380
  capabilities.update,
369
381
  code,
@@ -481,60 +493,101 @@ function GeneratedDesktopList({ definition, paths }) {
481
493
  label: `${fieldFor(surface, key).label}:${filterValueLabel(state.query.filters?.[key])}`,
482
494
  })),
483
495
  ];
484
- return (_jsxs(ResourceListPage, { createCapability: generated.create ? capabilities.create : undefined, createPath: generated.create ? paths.create : undefined, readCapability: capabilities.read, resource: code, surface: surface, title: name, children: [state.list.query.isError && (_jsx(Alert, { action: _jsx(Button, { onClick: () => void state.list.query.refetch(), size: "small", children: "\u91CD\u8BD5" }), description: state.list.query.error instanceof Error ? state.list.query.error.message : '请稍后重试或联系平台管理员', showIcon: true, title: "\u6570\u636E\u8BFB\u53D6\u5931\u8D25", type: "error" })), _jsx(ResourceAdvancedFilter, { open: moreFiltersOpen, fields: filterDefinitions, value: state.query.where, resourceCode: code, onClose: () => setMoreFiltersOpen(false), onApply: where => applyQuery({ ...state.query, filters: undefined, where }) }), _jsxs("div", { className: "oxa-list-toolbar", children: [_jsxs(Space, { className: "oxa-list-toolbar-primary", wrap: true, children: [standardWorkflow && _jsx(Button, { "aria-label": "\u65B0\u589E\u6D41\u7A0B\u7533\u8BF7", icon: _jsx(PlusOutlined, {}), type: "primary", onClick: () => setWorkflowOpen(true), children: "\u65B0\u589E" }), generated.create && hasCapability(capabilities.create) && (_jsx(Button, { "aria-label": "\u65B0\u589E", icon: _jsx(PlusOutlined, {}), onClick: () => setFormTarget({ mode: 'create' }), type: "primary", children: "\u65B0\u589E" })), surface.list?.actions?.import !== false && standardWorkflow?.processOperationCode && (_jsx(WorkflowResourceImportButton, { code: code, name: name, onCompleted: () => state.list.query.refetch(), processOperationCode: standardWorkflow.processOperationCode, surface: surface, workflowCode: standardWorkflow.code, writableFieldCodes: workflowImportFieldCodes })), surface.list?.actions?.import !== false && generated.create && hasCapability(capabilities.create) && (_jsx(ResourceImportButton, { code: code, name: name, surface: surface, writableFieldCodes: importWritableFieldCodes, onCompleted: () => state.list.query.refetch() })), surface.list?.actions?.export !== false && _jsx(Button, { "aria-label": "\u5BFC\u51FA", icon: _jsx(ExportOutlined, {}), loading: exporting, onClick: () => void handleExport(), children: "\u5BFC\u51FA" }), toolbarContributions.map((contribution) => (_jsx(Fragment, { children: contribution.render({
485
- resource: code,
486
- selectedRecords: selectedRows,
487
- refresh: () => state.list.query.refetch(),
488
- }) }, contribution.code)))] }), _jsxs(Space, { className: "oxa-list-toolbar-secondary", wrap: true, children: [displayDirty && _jsxs("span", { className: "oxa-list-dirty", children: ["\u4F60\u8C03\u6574\u4E86\u663E\u793A\u5217\u914D\u7F6E ", _jsx(Button, { type: "link", "aria-label": "\u4FDD\u5B58\u663E\u793A\u5217\u914D\u7F6E", loading: preferenceSaving, disabled: !visibleColumnKeys.length, onClick: () => void savePreference(), children: "\u4FDD\u5B58" })] }), searchableFields.length > 0 && _jsx(Input.Search, { className: "oxa-list-search", "aria-label": "\u641C\u7D22\u6570\u636E", allowClear: true, disabled: !preferenceReady, placeholder: keywordPlaceholder, value: state.draft.keyword, onChange: event => state.setDraft(current => ({ ...current, keyword: event.target.value })), onSearch: value => applyQuery({ ...state.query, keyword: value }) }), filterFields.length > 0 && _jsxs(Button, { "aria-label": "\u7B5B\u9009", icon: _jsx(FilterOutlined, {}), disabled: !preferenceReady, onClick: () => setMoreFiltersOpen(true), children: ["\u7B5B\u9009", activeAdditionalCount ? ` (${activeAdditionalCount})` : ''] }), _jsx(Popover, { trigger: "click", placement: "bottomRight", open: settingsOpen, onOpenChange: setSettingsOpen, destroyOnHidden: true, content: _jsx(ResourceListSettings, { columns: configurableColumns, value: display, disabled: preferenceSaving, onChange: changeDisplay, onReset: () => void restorePreference() }), children: _jsx(Button, { "aria-label": "\u663E\u793A\u5217", type: "text", icon: _jsx(SettingOutlined, {}), disabled: !preferenceReady, children: "\u663E\u793A\u5217" }) }), _jsx(Popover, { trigger: "click", placement: "bottomRight", open: sortsOpen, onOpenChange: setSortsOpen, destroyOnHidden: true, content: _jsx(ResourceSortSettings, { fields: sortFields, value: state.sorts, onApply: sorts => {
489
- void (async () => {
490
- try {
491
- await saveResourceListPreference(listKey, { ...preferencePayload(), ...JSON.parse(savedDisplay || displaySignature), sorts: sorts.map(sort => ({ field: sort.field, direction: sort.order === 'asc' ? 'ascend' : 'descend' })) });
492
- state.setSorts(sorts);
493
- state.setPage(1);
494
- setSortsOpen(false);
495
- }
496
- catch (error) {
497
- message.error(error instanceof Error ? error.message : '排序保存失败');
498
- }
499
- })();
500
- } }, String(sortsOpen)), children: _jsxs(Button, { "aria-label": "\u6392\u5E8F", type: "text", icon: _jsx(SortAscendingOutlined, {}), disabled: !preferenceReady, children: ["\u6392\u5E8F", state.sorts.length ? ` (${state.sorts.length})` : ''] }) }), _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() }) })] })] }), appliedConditions.length > 0 && (_jsxs("div", { className: "oxa-applied-filters", children: [_jsx("span", { children: "\u5DF2\u9009\u6761\u4EF6" }), _jsx("div", { className: "oxa-applied-filter-tags", children: appliedConditions.map(condition => (_jsx(Tag, { closable: true, onClose: (event) => {
501
- event.preventDefault();
502
- removeAppliedFilter(condition.key);
503
- }, children: condition.label }, condition.key))) }), _jsx(Button, { onClick: () => applyQuery({}), type: "link", children: "\u6E05\u7A7A\u5168\u90E8" })] })), correctionId && _jsx(WorkflowRecordEditor, { resourceCode: code, recordId: correctionId, drawerState: drawerState, onDismiss: () => { setCorrectionId(undefined); setEntryFullScreen(false); }, onSaved: id => { setCorrectionId(undefined); if (generated.detail)
496
+ return { definition, paths, navigate, message, hasCapability, hasReadCapability, identity, code, name, surface, capabilities, generated, workflowDefinitions, contributions, fields, readableFieldCodes, state, exporting, setExporting, moreFiltersOpen, setMoreFiltersOpen, settingsOpen, setSettingsOpen, formTarget, setFormTarget, detailId, setDetailId, workflowOpen, setWorkflowOpen, correctionId, setCorrectionId, entryFullScreen, setEntryFullScreen, drawerState, sortsOpen, setSortsOpen, frozenKeys, setFrozenKeys, columnOrder, setColumnOrder, savedDisplay, setSavedDisplay, density, setDensity, visibleColumnKeys, setVisibleColumnKeys, selectedRowKeys, setSelectedRowKeys, preferenceReady, setPreferenceReady, preferenceSaving, setPreferenceSaving, hasSavedPreference, setHasSavedPreference, remove, rows, formFields, importWritableFieldCodes, standardWorkflows, standardWorkflow, workflowImportFieldCodes, batchWritableFields, selectedRows, toolbarContributions, rowContributions, canBatch, configurableColumns, listKey, filterFields, filterDefinitions, sortFields, orderedKeys, display, displaySignature, displayDirty, preferencePayload, firstVisibleBusinessField, columns, handleExport, changeDisplay, savePreference, restorePreference, searchableFields, searchLabels, keywordPlaceholder, activeAdditionalCount, applyQuery, removeAppliedFilter, appliedConditions, total: state.list.result.total || 0, loading: state.list.query.isFetching, error: state.list.query.error, refresh: () => state.list.query.refetch() };
497
+ }
498
+ export function ResourceListContainer({ controller, children }) {
499
+ const { paths, code, name, surface, capabilities, generated } = controller;
500
+ return (_jsx(ResourceListPage, { createCapability: generated.create ? capabilities.create : undefined, createPath: generated.create ? paths.create : undefined, readCapability: capabilities.read, resource: code, surface: surface, title: name, children: children }));
501
+ }
502
+ export function ResourceListError({ controller }) {
503
+ const { message, state } = controller;
504
+ return (_jsx(_Fragment, { children: state.list.query.isError && (_jsx(Alert, { action: _jsx(Button, { onClick: () => void state.list.query.refetch(), size: "small", children: "\u91CD\u8BD5" }), description: state.list.query.error instanceof Error ? state.list.query.error.message : '请稍后重试或联系平台管理员', showIcon: true, title: "\u6570\u636E\u8BFB\u53D6\u5931\u8D25", type: "error" })) }));
505
+ }
506
+ export function ResourceListAdvancedFilter({ controller }) {
507
+ const { code, fields, state, moreFiltersOpen, setMoreFiltersOpen, filterDefinitions, applyQuery } = controller;
508
+ return (_jsx(_Fragment, { children: _jsx(ResourceAdvancedFilter, { open: moreFiltersOpen, fields: filterDefinitions, value: state.query.where, resourceCode: code, onClose: () => setMoreFiltersOpen(false), onApply: where => applyQuery({ ...state.query, filters: undefined, where }) }) }));
509
+ }
510
+ export function ResourceListActions({ controller }) {
511
+ const { hasCapability, code, name, surface, capabilities, generated, state, exporting, setFormTarget, setWorkflowOpen, importWritableFieldCodes, standardWorkflow, workflowImportFieldCodes, selectedRows, toolbarContributions, handleExport } = controller;
512
+ return (_jsxs(Space, { className: "oxa-list-toolbar-primary", wrap: true, children: [standardWorkflow && _jsx(Button, { "aria-label": "\u65B0\u589E\u6D41\u7A0B\u7533\u8BF7", icon: _jsx(PlusOutlined, {}), type: "primary", onClick: () => setWorkflowOpen(true), children: "\u65B0\u589E" }), generated.create && hasCapability(capabilities.create) && (_jsx(Button, { "aria-label": "\u65B0\u589E", icon: _jsx(PlusOutlined, {}), onClick: () => setFormTarget({ mode: 'create' }), type: "primary", children: "\u65B0\u589E" })), surface.list?.actions?.import !== false && standardWorkflow?.processOperationCode && (_jsx(WorkflowResourceImportButton, { code: code, name: name, onCompleted: () => state.list.query.refetch(), processOperationCode: standardWorkflow.processOperationCode, surface: surface, workflowCode: standardWorkflow.code, writableFieldCodes: workflowImportFieldCodes })), surface.list?.actions?.import !== false && generated.create && hasCapability(capabilities.create) && (_jsx(ResourceImportButton, { code: code, name: name, surface: surface, writableFieldCodes: importWritableFieldCodes, onCompleted: () => state.list.query.refetch() })), surface.list?.actions?.export !== false && _jsx(Button, { "aria-label": "\u5BFC\u51FA", icon: _jsx(ExportOutlined, {}), loading: exporting, onClick: () => void handleExport(), children: "\u5BFC\u51FA" }), toolbarContributions.map((contribution) => (_jsx(Fragment, { children: contribution.render({
513
+ resource: code,
514
+ selectedRecords: selectedRows,
515
+ refresh: () => state.list.query.refetch(),
516
+ }) }, contribution.code)))] }));
517
+ }
518
+ export function ResourceListQueryBar({ controller }) {
519
+ const { message, fields, state, setMoreFiltersOpen, settingsOpen, setSettingsOpen, sortsOpen, setSortsOpen, savedDisplay, visibleColumnKeys, preferenceReady, preferenceSaving, configurableColumns, listKey, filterFields, sortFields, display, displaySignature, displayDirty, preferencePayload, columns, changeDisplay, savePreference, restorePreference, searchableFields, keywordPlaceholder, activeAdditionalCount, applyQuery } = controller;
520
+ return (_jsxs(Space, { className: "oxa-list-toolbar-secondary", wrap: true, children: [displayDirty && _jsxs("span", { className: "oxa-list-dirty", children: ["\u4F60\u8C03\u6574\u4E86\u663E\u793A\u5217\u914D\u7F6E ", _jsx(Button, { type: "link", "aria-label": "\u4FDD\u5B58\u663E\u793A\u5217\u914D\u7F6E", loading: preferenceSaving, disabled: !visibleColumnKeys.length, onClick: () => void savePreference(), children: "\u4FDD\u5B58" })] }), searchableFields.length > 0 && _jsx(Input.Search, { className: "oxa-list-search", "aria-label": "\u641C\u7D22\u6570\u636E", allowClear: true, disabled: !preferenceReady, placeholder: keywordPlaceholder, value: state.draft.keyword, onChange: event => state.setDraft(current => ({ ...current, keyword: event.target.value })), onSearch: value => applyQuery({ ...state.query, keyword: value }) }), filterFields.length > 0 && _jsxs(Button, { "aria-label": "\u7B5B\u9009", icon: _jsx(FilterOutlined, {}), disabled: !preferenceReady, onClick: () => setMoreFiltersOpen(true), children: ["\u7B5B\u9009", activeAdditionalCount ? ` (${activeAdditionalCount})` : ''] }), _jsx(Popover, { trigger: "click", placement: "bottomRight", open: settingsOpen, onOpenChange: setSettingsOpen, destroyOnHidden: true, content: _jsx(ResourceListSettings, { columns: configurableColumns, value: display, disabled: preferenceSaving, onChange: changeDisplay, onReset: () => void restorePreference() }), children: _jsx(Button, { "aria-label": "\u663E\u793A\u5217", type: "text", icon: _jsx(SettingOutlined, {}), disabled: !preferenceReady, children: "\u663E\u793A\u5217" }) }), _jsx(Popover, { trigger: "click", placement: "bottomRight", open: sortsOpen, onOpenChange: setSortsOpen, destroyOnHidden: true, content: _jsx(ResourceSortSettings, { fields: sortFields, value: state.sorts, onApply: sorts => {
521
+ void (async () => {
522
+ try {
523
+ await saveResourceListPreference(listKey, { ...preferencePayload(), ...JSON.parse(savedDisplay || displaySignature), sorts: sorts.map(sort => ({ field: sort.field, direction: sort.order === 'asc' ? 'ascend' : 'descend' })) });
524
+ state.setSorts(sorts);
525
+ state.setPage(1);
526
+ setSortsOpen(false);
527
+ }
528
+ catch (error) {
529
+ message.error(error instanceof Error ? error.message : '排序保存失败');
530
+ }
531
+ })();
532
+ } }, String(sortsOpen)), children: _jsxs(Button, { "aria-label": "\u6392\u5E8F", type: "text", icon: _jsx(SortAscendingOutlined, {}), disabled: !preferenceReady, children: ["\u6392\u5E8F", state.sorts.length ? ` (${state.sorts.length})` : ''] }) }), _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() }) })] }));
533
+ }
534
+ export function ResourceListToolbar({ controller }) { return _jsxs("div", { className: "oxa-list-toolbar", children: [_jsx(ResourceListActions, { controller: controller }), _jsx(ResourceListQueryBar, { controller: controller })] }); }
535
+ export function ResourceListAppliedFilters({ controller }) {
536
+ const { applyQuery, removeAppliedFilter, appliedConditions } = controller;
537
+ return (_jsx(_Fragment, { children: appliedConditions.length > 0 && (_jsxs("div", { className: "oxa-applied-filters", children: [_jsx("span", { children: "\u5DF2\u9009\u6761\u4EF6" }), _jsx("div", { className: "oxa-applied-filter-tags", children: appliedConditions.map(condition => (_jsx(Tag, { closable: true, onClose: (event) => {
538
+ event.preventDefault();
539
+ removeAppliedFilter(condition.key);
540
+ }, children: condition.label }, condition.key))) }), _jsx(Button, { onClick: () => applyQuery({}), type: "link", children: "\u6E05\u7A7A\u5168\u90E8" })] })) }));
541
+ }
542
+ export function ResourceListOverlays({ controller }) {
543
+ const { definition, paths, code, surface, generated, state, formTarget, setFormTarget, detailId, setDetailId, workflowOpen, setWorkflowOpen, correctionId, setCorrectionId, setEntryFullScreen, drawerState, standardWorkflow } = controller;
544
+ return (_jsxs(_Fragment, { children: [correctionId && _jsx(WorkflowRecordEditor, { resourceCode: code, recordId: correctionId, drawerState: drawerState, onDismiss: () => { setCorrectionId(undefined); setEntryFullScreen(false); }, onSaved: id => { setCorrectionId(undefined); if (generated.detail)
504
545
  setDetailId(id); void state.list.query.refetch(); } }), workflowOpen && standardWorkflow && _jsx(WorkflowSubmissionPage, { workflowCode: standardWorkflow.code, onDismiss: () => setWorkflowOpen(false), onCompleted: id => { setWorkflowOpen(false); if (generated.detail)
505
- setDetailId(id); void state.list.query.refetch(); } }), detailId && _jsx(GeneratedResourceDetailPage, { definition: definition, paths: paths, variant: "desktop", recordId: detailId, drawerState: drawerState, onDismiss: () => { setDetailId(undefined); setEntryFullScreen(false); }, onEdit: () => { if (surface.mutationOwner === 'workflow')
546
+ setDetailId(id); void state.list.query.refetch(); } }), detailId && _jsx(GeneratedResourcePage, { resourceCode: code, definition: definition, mode: "detail", paths: paths, variant: "desktop", recordId: detailId, drawerState: drawerState, onDismiss: () => { setDetailId(undefined); setEntryFullScreen(false); }, onEdit: () => { if (surface.mutationOwner === 'workflow')
506
547
  setCorrectionId(detailId);
507
548
  else
508
- setFormTarget({ mode: 'edit', id: detailId }); setDetailId(undefined); } }), formTarget && _jsx(GeneratedResourceFormPage, { definition: definition, paths: paths, variant: "desktop", mode: formTarget.mode, recordId: formTarget.id, drawerState: drawerState, onDismiss: () => { setFormTarget(undefined); setEntryFullScreen(false); }, onSaved: id => { setFormTarget(undefined); if (generated.detail)
509
- setDetailId(id); void state.list.query.refetch(); } }, `${formTarget.mode}:${formTarget.id || ''}`), _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.filter(column => column.key !== 'actions')].sort((a, b) => orderedKeys.indexOf(String(a.key)) - orderedKeys.indexOf(String(b.key))).sort((a, b) => Number(b.fixed === 'left') - Number(a.fixed === 'left')).concat(columns.filter(column => column.key === 'actions')), dataSource: rows, loading: state.list.query.isFetching, locale: { emptyText: _jsx(Empty, { description: visibleColumnKeys.length ? `暂无${name}` : '请选择至少一列' }) }, rowKey: "id", rowSelection: canBatch
510
- ? {
511
- selectedRowKeys,
512
- onChange: (keys) => {
513
- const next = keys.map(String);
514
- if (next.length > 100)
515
- message.warning('单次最多选择 100 条记录');
516
- setSelectedRowKeys(next.slice(0, 100));
517
- },
518
- }
519
- : undefined, scroll: { x: 'max-content' }, size: density, onChange: (_, __, sorter, extra) => {
520
- if (extra.action !== 'sort')
521
- return;
522
- const items = Array.isArray(sorter) ? sorter : [sorter];
523
- state.setPage(1);
524
- state.setSorts(items.filter(item => item.field && item.order).map(item => ({ field: String(item.field), order: item.order === 'ascend' ? 'asc' : 'desc' })));
525
- }, pagination: {
526
- current: state.page,
527
- pageSize: state.pageSize,
528
- total: state.list.result.total || 0,
529
- showSizeChanger: true,
530
- showTotal: total => `共 ${total} 条`,
531
- onChange: (next, size) => {
532
- state.setPage(next);
533
- state.setPageSize(size);
549
+ setFormTarget({ mode: 'edit', id: detailId }); setDetailId(undefined); } }), formTarget && _jsx(GeneratedResourcePage, { resourceCode: code, definition: definition, paths: paths, variant: "desktop", mode: formTarget.mode, recordId: formTarget.id, drawerState: drawerState, onDismiss: () => { setFormTarget(undefined); setEntryFullScreen(false); }, onSaved: id => { setFormTarget(undefined); if (generated.detail)
550
+ setDetailId(id); void state.list.query.refetch(); } }, `${formTarget.mode}:${formTarget.id || ''}`)] }));
551
+ }
552
+ export function ResourceListBatchBar({ controller }) {
553
+ const { hasCapability, code, name, surface, capabilities, generated, state, setSelectedRowKeys, rows, batchWritableFields, selectedRows } = controller;
554
+ return (_jsx(_Fragment, { children: _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 }) }));
555
+ }
556
+ export function ResourceListTable({ controller }) {
557
+ const { message, name, state, density, visibleColumnKeys, selectedRowKeys, setSelectedRowKeys, rows, canBatch, orderedKeys, columns } = controller;
558
+ return (_jsx(_Fragment, { children: _jsx(Table, { columns: [...columns.filter(column => column.key !== 'actions')].sort((a, b) => orderedKeys.indexOf(String(a.key)) - orderedKeys.indexOf(String(b.key))).sort((a, b) => Number(b.fixed === 'left') - Number(a.fixed === 'left')).concat(columns.filter(column => column.key === 'actions')), dataSource: rows, loading: state.list.query.isFetching, locale: { emptyText: _jsx(Empty, { description: visibleColumnKeys.length ? `暂无${name}` : '请选择至少一列' }) }, rowKey: "id", rowSelection: canBatch
559
+ ? {
560
+ selectedRowKeys,
561
+ onChange: (keys) => {
562
+ const next = keys.map(String);
563
+ if (next.length > 100)
564
+ message.warning('单次最多选择 100 条记录');
565
+ setSelectedRowKeys(next.slice(0, 100));
534
566
  },
535
- } })] }));
567
+ }
568
+ : undefined, scroll: { x: 'max-content' }, size: density, onChange: (_, __, sorter, extra) => {
569
+ if (extra.action !== 'sort')
570
+ return;
571
+ const items = Array.isArray(sorter) ? sorter : [sorter];
572
+ state.setPage(1);
573
+ state.setSorts(items.filter(item => item.field && item.order).map(item => ({ field: String(item.field), order: item.order === 'ascend' ? 'asc' : 'desc' })));
574
+ }, pagination: {
575
+ current: state.page,
576
+ pageSize: state.pageSize,
577
+ total: state.list.result.total || 0,
578
+ showSizeChanger: true,
579
+ showTotal: total => `共 ${total} 条`,
580
+ onChange: (next, size) => {
581
+ state.setPage(next);
582
+ state.setPageSize(size);
583
+ },
584
+ } }) }));
585
+ }
586
+ function GeneratedDesktopList(props) {
587
+ const controller = useResourceListController(props);
588
+ return _jsxs(ResourceListContainer, { controller: controller, children: [_jsx(ResourceListError, { controller: controller }), _jsx(ResourceListAdvancedFilter, { controller: controller }), _jsx(ResourceListToolbar, { controller: controller }), _jsx(ResourceListAppliedFilters, { controller: controller }), _jsx(ResourceListOverlays, { controller: controller }), _jsx(ResourceListBatchBar, { controller: controller }), _jsx(ResourceListTable, { controller: controller })] });
536
589
  }
537
- function GeneratedMobileList({ definition, paths }) {
590
+ export function useMobileResourceListController({ definition, paths, mobileFields }) {
538
591
  const navigate = useNavigate();
539
592
  const { hasCapability, hasReadCapability, identity } = useRuntime();
540
593
  const { message } = App.useApp();
@@ -546,9 +599,9 @@ function GeneratedMobileList({ definition, paths }) {
546
599
  const state = useGeneratedList(definition, readableFieldCodes);
547
600
  const [exporting, setExporting] = useState(false);
548
601
  const rows = (state.list.result.data || []);
549
- const fields = selectedSurfaceFields(surface, 'list')
550
- .filter((field) => fieldReadable(field, hasReadCapability, identity.isAppSuperAdmin))
551
- .slice(0, 4);
602
+ const availableFields = selectedSurfaceFields(surface, 'list')
603
+ .filter((field) => fieldReadable(field, hasReadCapability, identity.isAppSuperAdmin));
604
+ const fields = mobileFields ? [...new Set(mobileFields)].flatMap(key => availableFields.filter(field => field.key === key)) : availableFields.slice(0, 4);
552
605
  const handleExport = async () => {
553
606
  setExporting(true);
554
607
  try {
@@ -562,19 +615,43 @@ function GeneratedMobileList({ definition, paths }) {
562
615
  setExporting(false);
563
616
  }
564
617
  };
565
- return (_jsxs(MobileResourceListPage, { createCapability: generated.create ? capabilities.create : undefined, createPath: generated.create ? paths.create : undefined, description: `${code} 资源`, onExport: surface.list?.actions?.export !== false ? () => void handleExport() : undefined, readCapability: capabilities.read, resource: code, surface: surface, title: name, children: [state.list.query.isError && (_jsx(Alert, { action: _jsx(Button, { onClick: () => void state.list.query.refetch(), size: "small", children: "\u91CD\u8BD5" }), description: state.list.query.error instanceof Error ? state.list.query.error.message : '请稍后重试或联系平台管理员', showIcon: true, title: "\u6570\u636E\u8BFB\u53D6\u5931\u8D25", type: "error" })), _jsxs("div", { className: "oxa-mobile-filter", children: [_jsx(Input, { allowClear: true, placeholder: "\u5173\u952E\u8BCD", value: state.draft.keyword, onChange: (event) => state.setDraft((item) => ({ ...item, keyword: event.target.value })), onPressEnter: () => {
566
- state.setPage(1);
567
- state.setQuery(state.draft);
568
- } }), _jsx(Button, { loading: state.list.query.isFetching, icon: _jsx(SearchOutlined, {}), onClick: () => {
569
- state.setPage(1);
570
- state.setQuery(state.draft);
571
- }, type: "primary", children: "\u67E5\u8BE2" })] }), state.list.query.isFetching ? (_jsx("div", { className: "oxa-page-loading", children: _jsx(Spin, {}) })) : rows.length ? (_jsx("div", { className: "oxa-mobile-record-list", children: rows.map((record) => {
572
- const primaryField = fields[0];
573
- const primaryValue = primaryField ? (_jsx(SurfaceFieldValue, { field: primaryField, resourceCode: code, value: record[primaryField.key] })) : (_jsx(_Fragment, { children: record.id }));
574
- return (_jsxs(Card, { className: "oxa-mobile-record-card", size: "small", children: [_jsx("div", { className: "oxa-mobile-record-heading", children: generated.detail ? (_jsx("a", { onClick: () => navigate(resourceRecordPath(paths.detail, record.id)), children: primaryValue })) : (primaryValue) }), _jsx("div", { className: "oxa-mobile-record-fields", children: fields.slice(1).map((field) => (_jsxs("div", { children: [_jsx(Typography.Text, { type: "secondary", children: field.label }), _jsx("div", { children: _jsx(SurfaceFieldValue, { field: field, resourceCode: code, value: record[field.key] }) })] }, field.key))) }), _jsxs(Space, { children: [generated.detail && (_jsx(Button, { onClick: () => navigate(resourceRecordPath(paths.detail, record.id)), size: "small", children: "\u67E5\u770B" })), generated.update && hasCapability(capabilities.update) && (_jsx(Button, { onClick: () => navigate(resourceRecordPath(paths.edit, record.id)), size: "small", children: "\u7F16\u8F91" }))] })] }, record.id));
575
- }) })) : (_jsx(Card, { children: _jsx(Empty, { description: `暂无${name}` }) })), _jsxs("div", { className: "oxa-mobile-pagination", children: [_jsx(Button, { disabled: state.page <= 1, onClick: () => state.setPage((item) => item - 1), children: "\u4E0A\u4E00\u9875" }), _jsxs(Typography.Text, { children: ["\u7B2C ", state.page, " \u9875"] }), _jsx(Button, { disabled: rows.length < (surface.list?.defaultPageSize || 20), onClick: () => state.setPage((item) => item + 1), children: "\u4E0B\u4E00\u9875" })] })] }));
618
+ return { definition, paths, navigate, hasCapability, hasReadCapability, identity, message, code, name, surface, capabilities, generated, readableFieldCodes, state, exporting, setExporting, rows, fields, handleExport, total: state.list.result.total || 0, loading: state.list.query.isFetching, error: state.list.query.error, refresh: () => state.list.query.refetch() };
619
+ }
620
+ export function MobileResourceListContainer({ controller, children, description }) {
621
+ const { paths, code, name, surface, capabilities, generated, handleExport } = controller;
622
+ return (_jsx(MobileResourceListPage, { createCapability: generated.create ? capabilities.create : undefined, createPath: generated.create ? paths.create : undefined, description: description === false ? undefined : description ?? `${code} 资源`, onExport: surface.list?.actions?.export !== false ? () => void handleExport() : undefined, readCapability: capabilities.read, resource: code, surface: surface, title: name, children: children }));
623
+ }
624
+ export function MobileResourceListError({ controller }) {
625
+ const { message, state } = controller;
626
+ return (_jsx(_Fragment, { children: state.list.query.isError && (_jsx(Alert, { action: _jsx(Button, { onClick: () => void state.list.query.refetch(), size: "small", children: "\u91CD\u8BD5" }), description: state.list.query.error instanceof Error ? state.list.query.error.message : '请稍后重试或联系平台管理员', showIcon: true, title: "\u6570\u636E\u8BFB\u53D6\u5931\u8D25", type: "error" })) }));
627
+ }
628
+ export function MobileResourceListQueryBar({ controller }) {
629
+ const { state } = controller;
630
+ return (_jsx(_Fragment, { children: _jsxs("div", { className: "oxa-mobile-filter", children: [_jsx(Input, { allowClear: true, placeholder: "\u5173\u952E\u8BCD", value: state.draft.keyword, onChange: (event) => state.setDraft((item) => ({ ...item, keyword: event.target.value })), onPressEnter: () => {
631
+ state.setPage(1);
632
+ state.setQuery(state.draft);
633
+ } }), _jsx(Button, { loading: state.list.query.isFetching, icon: _jsx(SearchOutlined, {}), onClick: () => {
634
+ state.setPage(1);
635
+ state.setQuery(state.draft);
636
+ }, type: "primary", children: "\u67E5\u8BE2" })] }) }));
637
+ }
638
+ export function MobileResourceListCards({ controller }) {
639
+ const { paths, navigate, hasCapability, code, name, capabilities, generated, state, rows, fields } = controller;
640
+ return (_jsx(_Fragment, { children: state.list.query.isFetching ? (_jsx("div", { className: "oxa-page-loading", children: _jsx(Spin, {}) })) : rows.length ? (_jsx("div", { className: "oxa-mobile-record-list", children: rows.map((record) => {
641
+ const primaryField = fields[0];
642
+ const primaryValue = primaryField ? (_jsx(SurfaceFieldValue, { field: primaryField, resourceCode: code, value: record[primaryField.key] })) : (_jsx(_Fragment, { children: record.id }));
643
+ return (_jsxs(Card, { className: "oxa-mobile-record-card", size: "small", children: [_jsx("div", { className: "oxa-mobile-record-heading", children: generated.detail ? (_jsx("a", { onClick: () => navigate(resourceRecordPath(paths.detail, record.id)), children: primaryValue })) : (primaryValue) }), _jsx("div", { className: "oxa-mobile-record-fields", children: fields.slice(1).map((field) => (_jsxs("div", { children: [_jsx(Typography.Text, { type: "secondary", children: field.label }), _jsx("div", { children: _jsx(SurfaceFieldValue, { field: field, resourceCode: code, value: record[field.key] }) })] }, field.key))) }), _jsxs(Space, { children: [generated.detail && (_jsx(Button, { onClick: () => navigate(resourceRecordPath(paths.detail, record.id)), size: "small", children: "\u67E5\u770B" })), generated.update && hasCapability(capabilities.update) && (_jsx(Button, { onClick: () => navigate(resourceRecordPath(paths.edit, record.id)), size: "small", children: "\u7F16\u8F91" }))] })] }, record.id));
644
+ }) })) : (_jsx(Card, { children: _jsx(Empty, { description: `暂无${name}` }) })) }));
645
+ }
646
+ export function MobileResourceListPagination({ controller }) {
647
+ const { surface, state, rows } = controller;
648
+ return (_jsx(_Fragment, { children: _jsxs("div", { className: "oxa-mobile-pagination", children: [_jsx(Button, { disabled: state.page <= 1, onClick: () => state.setPage((item) => item - 1), children: "\u4E0A\u4E00\u9875" }), _jsxs(Typography.Text, { children: ["\u7B2C ", state.page, " \u9875"] }), _jsx(Button, { disabled: rows.length < (surface.list?.defaultPageSize || 20), onClick: () => state.setPage((item) => item + 1), children: "\u4E0B\u4E00\u9875" })] }) }));
649
+ }
650
+ function GeneratedMobileList(props) {
651
+ const controller = useMobileResourceListController(props);
652
+ return _jsxs(MobileResourceListContainer, { controller: controller, children: [_jsx(MobileResourceListError, { controller: controller }), _jsx(MobileResourceListQueryBar, { controller: controller }), _jsx(MobileResourceListCards, { controller: controller }), _jsx(MobileResourceListPagination, { controller: controller })] });
576
653
  }
577
- function GeneratedResourceDetailPage({ definition, paths, variant, recordId, onDismiss, onEdit, drawerState }) {
654
+ export function GeneratedResourceDetailPage({ definition, paths, variant, recordId, onDismiss, onEdit, drawerState }) {
578
655
  if (definition.surface.mutationOwner === 'workflow')
579
656
  return _jsx(WorkflowRecordDetailPage, { resourceCode: definition.code, recordId: recordId, variant: variant, onDismiss: onDismiss, drawerState: drawerState });
580
657
  return _jsx(NativeResourceDetailPage, { definition: definition, paths: paths, variant: variant, recordId: recordId, onDismiss: onDismiss, onEdit: onEdit, drawerState: drawerState });