@rytass/bpm-core-react 0.14.0 → 0.16.2

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 (247) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/chunks/{FormBuilderView-BYLN6W-P.js → FormBuilderView-BYL42M0d.js} +499 -476
  3. package/dist/chunks/FormBuilderView-BYL42M0d.js.map +1 -0
  4. package/dist/chunks/FormBuilderView-aBcA-_tt.cjs +3 -0
  5. package/dist/chunks/FormBuilderView-aBcA-_tt.cjs.map +1 -0
  6. package/dist/chunks/FormRendererView-DRFi_IH7.cjs +4 -0
  7. package/dist/chunks/FormRendererView-DRFi_IH7.cjs.map +1 -0
  8. package/dist/chunks/FormRendererView-cZGOOjU5.js +986 -0
  9. package/dist/chunks/FormRendererView-cZGOOjU5.js.map +1 -0
  10. package/dist/chunks/{admin-pickers-DLlG_1du.js → admin-pickers-DxhzECkD.js} +52 -51
  11. package/dist/chunks/admin-pickers-DxhzECkD.js.map +1 -0
  12. package/dist/chunks/admin-pickers-qe3j--gX.cjs +2 -0
  13. package/dist/chunks/admin-pickers-qe3j--gX.cjs.map +1 -0
  14. package/dist/chunks/approval-instance-list-page-CPXMP3PL.js.map +1 -1
  15. package/dist/chunks/approval-instance-list-page-ax0pm8bt.cjs.map +1 -1
  16. package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -1
  17. package/dist/chunks/auth-provider-B5oPmvk2.js.map +1 -1
  18. package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -1
  19. package/dist/chunks/bpm-form-field-Cao0rMol.js.map +1 -1
  20. package/dist/chunks/{categories-DGlxuC6X.js → categories-1gKxeEqw.js} +4 -10
  21. package/dist/chunks/categories-1gKxeEqw.js.map +1 -0
  22. package/dist/chunks/{categories-Yid05WAX.cjs → categories-DjENouRm.cjs} +2 -2
  23. package/dist/chunks/categories-DjENouRm.cjs.map +1 -0
  24. package/dist/chunks/{compose-CSWbRgJJ.js → compose-DO6n0NJi.js} +5 -5
  25. package/dist/chunks/compose-DO6n0NJi.js.map +1 -0
  26. package/dist/chunks/compose-DUH9cQ-L.cjs +2 -0
  27. package/dist/chunks/compose-DUH9cQ-L.cjs.map +1 -0
  28. package/dist/chunks/dashboard-page-BWQBSGDq.cjs +2 -0
  29. package/dist/chunks/dashboard-page-BWQBSGDq.cjs.map +1 -0
  30. package/dist/chunks/{dashboard-page-CeCLV1tp.js → dashboard-page-DdBvV6YI.js} +15 -16
  31. package/dist/chunks/dashboard-page-DdBvV6YI.js.map +1 -0
  32. package/dist/chunks/delegations-BLzYnOae.cjs +2 -0
  33. package/dist/chunks/delegations-BLzYnOae.cjs.map +1 -0
  34. package/dist/chunks/delegations-Ckf03icM.cjs +2 -0
  35. package/dist/chunks/delegations-Ckf03icM.cjs.map +1 -0
  36. package/dist/chunks/{delegations-DRupxJ4_.js → delegations-MxF3uJGW.js} +205 -215
  37. package/dist/chunks/delegations-MxF3uJGW.js.map +1 -0
  38. package/dist/chunks/{delegations-B8gLSt0i.js → delegations-_b4_xBit.js} +167 -173
  39. package/dist/chunks/delegations-_b4_xBit.js.map +1 -0
  40. package/dist/chunks/designer-2YvjP_GU.cjs +65 -0
  41. package/dist/chunks/designer-2YvjP_GU.cjs.map +1 -0
  42. package/dist/chunks/{designer-BtsIL0BB.js → designer-B-cfiob9.js} +1334 -1254
  43. package/dist/chunks/designer-B-cfiob9.js.map +1 -0
  44. package/dist/chunks/{detail-C8NOqY0p.js → detail-C6NdVijG.js} +852 -841
  45. package/dist/chunks/detail-C6NdVijG.js.map +1 -0
  46. package/dist/chunks/detail-DKobK4Cg.cjs +2 -0
  47. package/dist/chunks/detail-DKobK4Cg.cjs.map +1 -0
  48. package/dist/chunks/format-date-time-CB-LxzqT.js.map +1 -1
  49. package/dist/chunks/format-date-time-D-cx5M8z.cjs.map +1 -1
  50. package/dist/chunks/format-member-label-DudVI55w.js +13 -0
  51. package/dist/chunks/format-member-label-DudVI55w.js.map +1 -0
  52. package/dist/chunks/format-member-label-t7ANTF62.cjs +2 -0
  53. package/dist/chunks/format-member-label-t7ANTF62.cjs.map +1 -0
  54. package/dist/chunks/login-AtVxZBsC.cjs.map +1 -1
  55. package/dist/chunks/login-C6qlTC6F.js.map +1 -1
  56. package/dist/chunks/notifications-Bc4mgSds.cjs.map +1 -1
  57. package/dist/chunks/notifications-DJ5wzCye.js.map +1 -1
  58. package/dist/chunks/{orgs-BpqVu5ka.js → orgs-Bpp1U60k.js} +538 -557
  59. package/dist/chunks/orgs-Bpp1U60k.js.map +1 -0
  60. package/dist/chunks/orgs-ywaE1_02.cjs +2 -0
  61. package/dist/chunks/orgs-ywaE1_02.cjs.map +1 -0
  62. package/dist/chunks/providers-DHtDZFNA.cjs.map +1 -1
  63. package/dist/chunks/providers-J5eyByQj.js.map +1 -1
  64. package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -1
  65. package/dist/chunks/router-adapter-DftlFTOd.js.map +1 -1
  66. package/dist/chunks/routes-config-C1j_vFKo.cjs.map +1 -1
  67. package/dist/chunks/routes-config-yZbESPlw.js.map +1 -1
  68. package/dist/chunks/task-node-label-BF6UllxP.cjs +2 -0
  69. package/dist/chunks/task-node-label-BF6UllxP.cjs.map +1 -0
  70. package/dist/chunks/task-node-label-CWZgOBj0.js +9 -0
  71. package/dist/chunks/task-node-label-CWZgOBj0.js.map +1 -0
  72. package/dist/chunks/use-bpm-member-D57LKe_u.js.map +1 -1
  73. package/dist/chunks/use-bpm-member-DpNAQtNC.cjs.map +1 -1
  74. package/dist/chunks/users-BSVo_eNe.js +215 -0
  75. package/dist/chunks/users-BSVo_eNe.js.map +1 -0
  76. package/dist/chunks/users-DFSBTDMy.cjs +2 -0
  77. package/dist/chunks/users-DFSBTDMy.cjs.map +1 -0
  78. package/dist/index.cjs +1 -1
  79. package/dist/index.cjs.map +1 -1
  80. package/dist/index.js +2 -2
  81. package/dist/index.js.map +1 -1
  82. package/dist/lib/format-member-label.d.ts +12 -0
  83. package/dist/lib/member-profile-resolution.d.ts +48 -0
  84. package/dist/lib/routes-config.d.ts +1 -1
  85. package/dist/lib/task-node-label.d.ts +10 -0
  86. package/dist/next/index.cjs.map +1 -1
  87. package/dist/next/index.js.map +1 -1
  88. package/dist/next/workflow-chat-route.cjs.map +1 -1
  89. package/dist/next/workflow-chat-route.js.map +1 -1
  90. package/dist/pages/admin/delegations/index.cjs +1 -1
  91. package/dist/pages/admin/delegations/index.cjs.map +1 -1
  92. package/dist/pages/admin/delegations/index.js +1 -1
  93. package/dist/pages/admin/delegations/index.js.map +1 -1
  94. package/dist/pages/admin/orgs/index.cjs +1 -1
  95. package/dist/pages/admin/orgs/index.cjs.map +1 -1
  96. package/dist/pages/admin/orgs/index.js +1 -1
  97. package/dist/pages/admin/orgs/index.js.map +1 -1
  98. package/dist/pages/admin/users/index.cjs +1 -1
  99. package/dist/pages/admin/users/index.cjs.map +1 -1
  100. package/dist/pages/admin/users/index.js +1 -1
  101. package/dist/pages/admin/users/index.js.map +1 -1
  102. package/dist/pages/admin/webhook-endpoints/index.cjs.map +1 -1
  103. package/dist/pages/admin/webhook-endpoints/index.js.map +1 -1
  104. package/dist/pages/cc/index.cjs.map +1 -1
  105. package/dist/pages/cc/index.js.map +1 -1
  106. package/dist/pages/dashboard/index.cjs.map +1 -1
  107. package/dist/pages/dashboard/index.js.map +1 -1
  108. package/dist/pages/delegations/index.cjs +1 -1
  109. package/dist/pages/delegations/index.cjs.map +1 -1
  110. package/dist/pages/delegations/index.js +1 -1
  111. package/dist/pages/delegations/index.js.map +1 -1
  112. package/dist/pages/inbox/index.cjs.map +1 -1
  113. package/dist/pages/inbox/index.js.map +1 -1
  114. package/dist/pages/instances/detail/index.cjs +1 -1
  115. package/dist/pages/instances/detail/index.cjs.map +1 -1
  116. package/dist/pages/instances/detail/index.js +1 -1
  117. package/dist/pages/instances/detail/index.js.map +1 -1
  118. package/dist/pages/instances/new/index.cjs.map +1 -1
  119. package/dist/pages/instances/new/index.js.map +1 -1
  120. package/dist/pages/login/index.cjs.map +1 -1
  121. package/dist/pages/login/index.js.map +1 -1
  122. package/dist/pages/root/index.cjs.map +1 -1
  123. package/dist/pages/root/index.js.map +1 -1
  124. package/dist/pages/search/index.cjs.map +1 -1
  125. package/dist/pages/search/index.js.map +1 -1
  126. package/dist/pages/sent/index.cjs.map +1 -1
  127. package/dist/pages/sent/index.js.map +1 -1
  128. package/dist/pages/settings/notifications/index.cjs.map +1 -1
  129. package/dist/pages/settings/notifications/index.js.map +1 -1
  130. package/dist/pages/templates/categories/index.cjs +1 -1
  131. package/dist/pages/templates/categories/index.cjs.map +1 -1
  132. package/dist/pages/templates/categories/index.js +1 -1
  133. package/dist/pages/templates/categories/index.js.map +1 -1
  134. package/dist/pages/templates/compose/index.cjs +1 -1
  135. package/dist/pages/templates/compose/index.cjs.map +1 -1
  136. package/dist/pages/templates/compose/index.js +1 -1
  137. package/dist/pages/templates/compose/index.js.map +1 -1
  138. package/dist/pages/templates/designer/index.cjs +1 -1
  139. package/dist/pages/templates/designer/index.cjs.map +1 -1
  140. package/dist/pages/templates/designer/index.js +1 -1
  141. package/dist/pages/templates/designer/index.js.map +1 -1
  142. package/dist/pages/templates/index.cjs.map +1 -1
  143. package/dist/pages/templates/index.js.map +1 -1
  144. package/dist/pages/templates/versions/index.cjs.map +1 -1
  145. package/dist/pages/templates/versions/index.js.map +1 -1
  146. package/dist/views/admin/delegations/index.cjs +1 -1
  147. package/dist/views/admin/delegations/index.js +1 -2
  148. package/dist/views/admin/index.cjs +1 -1
  149. package/dist/views/admin/index.js +3 -3
  150. package/dist/views/admin/orgs/index.cjs +1 -1
  151. package/dist/views/admin/orgs/index.js +1 -2
  152. package/dist/views/admin/users/index.cjs +1 -1
  153. package/dist/views/admin/users/index.js +1 -2
  154. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  155. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  156. package/dist/views/cc/index.cjs.map +1 -1
  157. package/dist/views/cc/index.js.map +1 -1
  158. package/dist/views/dashboard/index.cjs +1 -1
  159. package/dist/views/dashboard/index.cjs.map +1 -1
  160. package/dist/views/dashboard/index.js +1 -1
  161. package/dist/views/dashboard/index.js.map +1 -1
  162. package/dist/views/delegations/index.cjs +1 -1
  163. package/dist/views/delegations/index.js +1 -2
  164. package/dist/views/forms/builder/index.cjs +1 -1
  165. package/dist/views/forms/builder/index.js +1 -2
  166. package/dist/views/forms/renderer/form-field-link.d.ts +16 -0
  167. package/dist/views/forms/renderer/index.cjs +1 -1
  168. package/dist/views/forms/renderer/index.js +1 -2
  169. package/dist/views/forms/renderer/member-field-options.d.ts +39 -0
  170. package/dist/views/forms/renderer/member-field.d.ts +21 -0
  171. package/dist/views/inbox/index.cjs +1 -1
  172. package/dist/views/inbox/index.cjs.map +1 -1
  173. package/dist/views/inbox/index.js +101 -102
  174. package/dist/views/inbox/index.js.map +1 -1
  175. package/dist/views/instances/detail/index.cjs +1 -1
  176. package/dist/views/instances/detail/index.js +1 -2
  177. package/dist/views/instances/detail/sections/container-helpers.d.ts +3 -2
  178. package/dist/views/instances/detail/submitted-by.d.ts +23 -0
  179. package/dist/views/instances/index.js +1 -2
  180. package/dist/views/instances/new/index.cjs +1 -1
  181. package/dist/views/instances/new/index.cjs.map +1 -1
  182. package/dist/views/instances/new/index.js +4 -11
  183. package/dist/views/instances/new/index.js.map +1 -1
  184. package/dist/views/login/index.js +1 -2
  185. package/dist/views/search/index.cjs.map +1 -1
  186. package/dist/views/search/index.js.map +1 -1
  187. package/dist/views/sent/SentView.d.ts +1 -1
  188. package/dist/views/sent/index.cjs +1 -1
  189. package/dist/views/sent/index.cjs.map +1 -1
  190. package/dist/views/sent/index.js +2 -2
  191. package/dist/views/sent/index.js.map +1 -1
  192. package/dist/views/settings/index.js +1 -2
  193. package/dist/views/settings/notifications/index.js +1 -2
  194. package/dist/views/templates/categories/index.cjs +1 -1
  195. package/dist/views/templates/categories/index.js +1 -2
  196. package/dist/views/templates/compose/index.cjs +1 -1
  197. package/dist/views/templates/compose/index.js +1 -2
  198. package/dist/views/templates/designer/designer-version-labels.d.ts +12 -0
  199. package/dist/views/templates/designer/dry-run-assignee-label.d.ts +28 -0
  200. package/dist/views/templates/designer/dry-run-sample-data.d.ts +9 -0
  201. package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +35 -0
  202. package/dist/views/templates/designer/index.cjs +1 -1
  203. package/dist/views/templates/designer/index.js +1 -2
  204. package/dist/views/templates/index.cjs +1 -1
  205. package/dist/views/templates/index.cjs.map +1 -1
  206. package/dist/views/templates/index.js +1 -1
  207. package/dist/views/templates/index.js.map +1 -1
  208. package/dist/views/templates/versions/index.cjs.map +1 -1
  209. package/dist/views/templates/versions/index.js.map +1 -1
  210. package/package.json +5 -5
  211. package/dist/chunks/FormBuilderView-BYLN6W-P.js.map +0 -1
  212. package/dist/chunks/FormBuilderView-VmdPVbg7.cjs +0 -3
  213. package/dist/chunks/FormBuilderView-VmdPVbg7.cjs.map +0 -1
  214. package/dist/chunks/FormRendererView-Bs8lTb4k.cjs +0 -2
  215. package/dist/chunks/FormRendererView-Bs8lTb4k.cjs.map +0 -1
  216. package/dist/chunks/FormRendererView-UPowZZgw.js +0 -798
  217. package/dist/chunks/FormRendererView-UPowZZgw.js.map +0 -1
  218. package/dist/chunks/admin-pickers-Btvij1at.cjs +0 -2
  219. package/dist/chunks/admin-pickers-Btvij1at.cjs.map +0 -1
  220. package/dist/chunks/admin-pickers-DLlG_1du.js.map +0 -1
  221. package/dist/chunks/categories-DGlxuC6X.js.map +0 -1
  222. package/dist/chunks/categories-Yid05WAX.cjs.map +0 -1
  223. package/dist/chunks/compose-CHZoX-H0.cjs +0 -2
  224. package/dist/chunks/compose-CHZoX-H0.cjs.map +0 -1
  225. package/dist/chunks/compose-CSWbRgJJ.js.map +0 -1
  226. package/dist/chunks/dashboard-page-CeCLV1tp.js.map +0 -1
  227. package/dist/chunks/dashboard-page-DooFJsxM.cjs +0 -2
  228. package/dist/chunks/dashboard-page-DooFJsxM.cjs.map +0 -1
  229. package/dist/chunks/delegations-8LsxcQM4.cjs +0 -2
  230. package/dist/chunks/delegations-8LsxcQM4.cjs.map +0 -1
  231. package/dist/chunks/delegations-B8gLSt0i.js.map +0 -1
  232. package/dist/chunks/delegations-DRupxJ4_.js.map +0 -1
  233. package/dist/chunks/delegations-DlYwMiAW.cjs +0 -2
  234. package/dist/chunks/delegations-DlYwMiAW.cjs.map +0 -1
  235. package/dist/chunks/designer-BtsIL0BB.js.map +0 -1
  236. package/dist/chunks/designer-Dm6cX2kZ.cjs +0 -65
  237. package/dist/chunks/designer-Dm6cX2kZ.cjs.map +0 -1
  238. package/dist/chunks/detail-C8NOqY0p.js.map +0 -1
  239. package/dist/chunks/detail-CX-3hZoL.cjs +0 -2
  240. package/dist/chunks/detail-CX-3hZoL.cjs.map +0 -1
  241. package/dist/chunks/orgs-BpqVu5ka.js.map +0 -1
  242. package/dist/chunks/orgs-D0-5BaHT.cjs +0 -2
  243. package/dist/chunks/orgs-D0-5BaHT.cjs.map +0 -1
  244. package/dist/chunks/users-C9LA-Rd7.cjs +0 -2
  245. package/dist/chunks/users-C9LA-Rd7.cjs.map +0 -1
  246. package/dist/chunks/users-FWrb3ehW.js +0 -214
  247. package/dist/chunks/users-FWrb3ehW.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"FormRendererView-Bs8lTb4k.cjs","names":[],"sources":["../../src/views/forms/renderer/form-data-source-field.ts","../../src/views/forms/renderer/FormRendererView.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FormDataSourceValueSnapshots,\n FormDefinitionSchema,\n FormFieldDefinition,\n FormFieldOption,\n FormFieldValue,\n FormUiSchema,\n isFormDataSourceFieldDefinition,\n} from '@rytass/bpm-core-shared/form';\nimport {\n FormDataSourceErrorCode,\n FormDataSourceFieldStatus,\n FormRendererValues,\n mergeFormDataSourceOptions,\n previewResolveFormFieldOptions,\n readFormDataSourceErrorCode,\n readFormDataSourceErrorMessage,\n readMissingFormDataSourceDependencies,\n readMissingFormDataSourceOptionValues,\n previewFormFieldOptions,\n readFormDataSourceSelectedValues,\n readFormDataSourceValueSignature,\n readSelectedFormDataSourceOptions,\n readFormFieldOptions,\n resolveFormFieldOptions,\n} from '@rytass/bpm-core-client/form';\n\nexport type FormRendererDataSourceContext =\n | { readonly kind: 'preview' }\n | {\n readonly instanceId?: string | null;\n readonly kind: 'runtime';\n readonly templateId?: string | null;\n };\n\nexport interface FormDataSourceFieldState {\n /**\n * False when nothing can be re-requested — a read-only or context-less field\n * has no query to retry, so the view must not offer a dead retry action.\n */\n readonly canRetry: boolean;\n readonly error: string | null;\n readonly hasValue: boolean;\n readonly hasNextPage: boolean;\n readonly invalidValues: readonly string[];\n readonly onReachBottom: () => void;\n readonly onSearch: (searchText: string) => void;\n readonly options: readonly FormFieldOption[];\n readonly retry: () => void;\n readonly status: FormDataSourceFieldStatus;\n}\n\n/**\n * What makes a table cell different from a top-level field: it is addressed by\n * a schema path, snapshotted under an instance path, and its `ROW_FIELD`\n * bindings read from its own row rather than the form (ADR 16 §3.3, §3.5).\n */\nexport interface UseFormDataSourceFieldRow {\n /** The row as it was loaded, so a returned case can tell what changed. */\n readonly initialValues?: FormRendererValues;\n readonly values: FormRendererValues;\n}\n\nexport interface UseFormDataSourceFieldInput {\n readonly context?: FormRendererDataSourceContext;\n readonly field: FormFieldDefinition;\n /** Schema path used to address the field; defaults to its own key. */\n readonly fieldPath?: string;\n readonly formData: FormRendererValues;\n readonly initialFormData?: FormRendererValues;\n readonly initialValue?: FormFieldValue | undefined;\n readonly optionSnapshots?: FormDataSourceValueSnapshots;\n readonly readonly: boolean;\n /** Set only for a table cell. */\n readonly row?: UseFormDataSourceFieldRow;\n readonly schema: FormDefinitionSchema;\n /** Snapshot map key; defaults to the field key. */\n readonly snapshotKey?: string;\n readonly uiSchema: FormUiSchema;\n}\n\ninterface FormDataSourceResolution {\n readonly signature: string;\n readonly unresolvedValues: readonly string[];\n}\n\nconst EMPTY_FIELD_STATE: FormDataSourceFieldState = {\n canRetry: false,\n error: null,\n hasValue: false,\n hasNextPage: false,\n invalidValues: [],\n onReachBottom: (): void => undefined,\n onSearch: (): void => undefined,\n options: [],\n retry: (): void => undefined,\n status: 'IDLE',\n};\n\nconst NO_INVALID_VALUES: readonly string[] = [];\n\n/**\n * A dropdown only fires `onReachBottom` once its content overflows. A source\n * whose first page is smaller than the menu is therefore unreachable past page\n * one — `demo.cost-centers` serves 3 at a time, which fits exactly, so nothing\n * ever scrolls and the remaining options cannot be selected at all. Keep\n * pulling pages until there are enough rows to scroll, or the source runs out.\n */\nconst MIN_SCROLLABLE_OPTION_COUNT = 10;\n\n/**\n * Failures the filler can clear on their own by typing differently. They are\n * reported as an inline hint and never turn the field unavailable, because a\n * short search string says nothing about the validity of an existing value.\n */\nconst RECOVERABLE_ERROR_CODES: readonly FormDataSourceErrorCode[] = [\n 'FORM_DATA_SOURCE_SEARCH_NOT_SUPPORTED',\n 'FORM_DATA_SOURCE_SEARCH_TOO_SHORT',\n];\n\nexport function useFormDataSourceField(\n input: UseFormDataSourceFieldInput,\n): FormDataSourceFieldState {\n const dynamicField = isFormDataSourceFieldDefinition(input.field)\n ? input.field\n : null;\n const queryFieldKey = input.fieldPath ?? dynamicField?.fieldKey ?? '';\n const snapshot = dynamicField\n ? input.optionSnapshots?.[input.snapshotKey ?? dynamicField.fieldKey]\n : undefined;\n // The field object is rebuilt on every parent render, so depending on its\n // identity re-ran the load effect three extra times per change — each request\n // aborting the last. Depend on what actually decides the query instead.\n const dynamicFieldSignature = dynamicField\n ? JSON.stringify({\n dataSource: dynamicField.dataSource,\n fieldKey: dynamicField.fieldKey,\n type: dynamicField.type,\n })\n : '';\n const snapshotSignature = JSON.stringify(snapshot ?? null);\n const snapshotOptions = useMemo(\n (): readonly FormFieldOption[] => snapshot?.options ?? [],\n [snapshotSignature],\n );\n const formDataSignature = JSON.stringify(input.formData);\n const initialFormDataSignature = JSON.stringify(input.initialFormData ?? {});\n const schemaSignature = JSON.stringify(input.schema);\n const uiSchemaSignature = JSON.stringify(input.uiSchema);\n const contextKind = input.context?.kind;\n const contextInstanceId =\n input.context?.kind === 'runtime' ? input.context.instanceId : undefined;\n const contextTemplateId =\n input.context?.kind === 'runtime' ? input.context.templateId : undefined;\n const rowValuesSignature = JSON.stringify(input.row?.values ?? null);\n const initialRowValuesSignature = JSON.stringify(\n input.row?.initialValues ?? null,\n );\n // A cell's value lives on its row, never on the form data — a top-level field\n // may even share the column's key.\n const currentValue = dynamicField\n ? input.row\n ? input.row.values[dynamicField.fieldKey]\n : input.formData[dynamicField.fieldKey]\n : undefined;\n const currentValueSignature = readFormDataSourceValueSignature(currentValue);\n const selectedValues = useMemo(\n (): readonly string[] => readFormDataSourceSelectedValues(currentValue),\n [currentValueSignature],\n );\n const hasValue = selectedValues.length > 0;\n const dataSourceRefreshSignature = dynamicField\n ? JSON.stringify({\n bindings: dynamicField.dataSource.bindings.map((binding) =>\n binding.from.kind === 'FIELD'\n ? {\n fieldKey: binding.from.fieldKey,\n value: input.formData[binding.from.fieldKey],\n }\n : binding.from.kind === 'CONSTANT'\n ? { value: binding.from.value }\n : {\n columnKey: binding.from.columnKey,\n value: input.row?.values[binding.from.columnKey],\n },\n ),\n value:\n typeof input.initialFormData !== 'undefined' ||\n typeof input.initialValue !== 'undefined'\n ? currentValue\n : undefined,\n })\n : '';\n const effectiveContext = useMemo(\n (): FormRendererDataSourceContext | undefined => {\n if (contextKind === 'preview') {\n return { kind: 'preview' };\n }\n\n if (contextKind === 'runtime' && !input.readonly) {\n return {\n instanceId: contextInstanceId,\n kind: 'runtime',\n templateId: contextTemplateId,\n };\n }\n\n return undefined;\n },\n [\n contextInstanceId,\n contextKind,\n contextTemplateId,\n input.readonly,\n ],\n );\n const valueChanged = dynamicField\n ? (typeof input.initialFormData !== 'undefined' ||\n typeof input.initialValue !== 'undefined') &&\n readFormDataSourceValueSignature(input.initialValue) !==\n currentValueSignature\n : false;\n const bindingsChanged = dynamicField\n ? typeof input.initialFormData !== 'undefined' &&\n dynamicField.dataSource.bindings.some((binding) => {\n if (binding.from.kind === 'FIELD') {\n return (\n readFormDataSourceValueSignature(\n input.initialFormData?.[binding.from.fieldKey],\n ) !==\n readFormDataSourceValueSignature(\n input.formData[binding.from.fieldKey],\n )\n );\n }\n\n if (binding.from.kind === 'ROW_FIELD' && input.row?.initialValues) {\n return (\n readFormDataSourceValueSignature(\n input.row.initialValues[binding.from.columnKey],\n ) !==\n readFormDataSourceValueSignature(\n input.row.values[binding.from.columnKey],\n )\n );\n }\n\n return false;\n })\n : false;\n const isStale = Boolean(\n (snapshot || hasValue) && (valueChanged || bindingsChanged),\n );\n // A stale field with a value is only trustworthy once the host has resolved\n // it: display options may still carry the value through the snapshot merge.\n const needsResolve = Boolean(dynamicField && effectiveContext && isStale && hasValue);\n const quiescentStatus = readQuiescentFormDataSourceStatus({\n hasSnapshot: Boolean(snapshot),\n hasValue,\n isStale,\n readonly: input.readonly,\n });\n // AutoComplete only queries on search, so every other control is the one that\n // loads by itself as soon as it has a context.\n const autoQueries = Boolean(\n dynamicField && effectiveContext && dynamicField.type !== 'autocomplete',\n );\n // Optimistic, and only until the first answer arrives: a binding pointing at\n // an empty field is usually blocking, and showing the control as usable for\n // one round trip would flash an enabled, empty list. AutoComplete is excluded\n // because nothing would ever correct the guess — it cannot be searched while\n // disabled, so an optional binding would lock it for good.\n const waitsForDependencies =\n autoQueries &&\n dynamicField !== null &&\n readMissingFormDataSourceDependencies(\n dynamicField,\n input.formData,\n input.row?.values,\n ).length > 0;\n const pendingQueryStatus = readPendingQueryStatus(isStale, waitsForDependencies);\n const [remoteOptions, setRemoteOptions] = useState<readonly FormFieldOption[]>(\n [],\n );\n const [searchText, setSearchText] = useState('');\n const [nextCursor, setNextCursor] = useState<string | null>(null);\n const [resolution, setResolution] = useState<FormDataSourceResolution | null>(\n null,\n );\n const [status, setStatus] = useState<FormDataSourceFieldStatus>(\n (): FormDataSourceFieldStatus => {\n if (!dynamicField) {\n return 'IDLE';\n }\n\n // The very first paint already reflects the query the effect is about to\n // fire, so the control never appears usable before its options exist.\n return autoQueries ? pendingQueryStatus : quiescentStatus;\n },\n );\n const [error, setError] = useState<string | null>(null);\n const loadedOptionCount = useRef(0);\n const requestSequence = useRef(0);\n const resolveSequence = useRef(0);\n const optionsAbort = useRef<AbortController | null>(null);\n const resolveAbort = useRef<AbortController | null>(null);\n const lastRequest = useRef<{ readonly cursor: string | null; readonly searchText: string }>({\n cursor: null,\n searchText: '',\n });\n\n const queryFormData = useMemo(\n (): Readonly<Record<string, FormFieldValue>> =>\n readDefinedValues(input.formData),\n [formDataSignature],\n );\n const queryRowValues = useMemo(\n (): Readonly<Record<string, FormFieldValue>> | undefined =>\n input.row ? readDefinedValues(input.row.values) : undefined,\n [rowValuesSignature],\n );\n const mergedOptions = useMemo(\n (): readonly FormFieldOption[] =>\n mergeFormDataSourceOptions(snapshotOptions, remoteOptions),\n [remoteOptions, snapshotOptions],\n );\n const currentResolution =\n resolution && resolution.signature === dataSourceRefreshSignature\n ? resolution\n : null;\n const resolvePending = needsResolve && !currentResolution;\n const invalidValues = readInvalidFormDataSourceValues({\n options: mergedOptions,\n resolution: currentResolution,\n resolvePending,\n value: currentValue,\n });\n\n const loadOptions = useCallback(\n (nextSearchTextToLoad: string, cursor: string | null): void => {\n if (!dynamicField || !effectiveContext) {\n return;\n }\n\n const requestId = requestSequence.current + 1;\n requestSequence.current = requestId;\n lastRequest.current = {\n cursor,\n searchText: nextSearchTextToLoad,\n };\n optionsAbort.current?.abort();\n const controller = new AbortController();\n optionsAbort.current = controller;\n setStatus(pendingQueryStatus);\n setError(null);\n\n const request =\n effectiveContext.kind === 'preview'\n ? previewFormFieldOptions({\n cursor,\n fieldKey: queryFieldKey,\n formData: queryFormData,\n rowValues: queryRowValues,\n schema: input.schema,\n searchText: nextSearchTextToLoad,\n signal: controller.signal,\n uiSchema: input.uiSchema,\n })\n : readFormFieldOptions({\n cursor,\n fieldKey: queryFieldKey,\n formData: queryFormData,\n instanceId: effectiveContext.instanceId ?? null,\n rowValues: queryRowValues,\n searchText: nextSearchTextToLoad,\n signal: controller.signal,\n templateId: effectiveContext.templateId ?? null,\n });\n\n void request\n .then((result): void => {\n if (isSupersededRequest(controller, requestSequence, requestId)) {\n return;\n }\n\n setRemoteOptions((currentOptions) => {\n const selectedOptions = readSelectedFormDataSourceOptions(\n currentValue,\n currentOptions,\n );\n\n return mergeFormDataSourceOptions(\n selectedOptions,\n cursor ? currentOptions : [],\n result.options,\n );\n });\n setNextCursor(result.nextCursor);\n setError(null);\n loadedOptionCount.current = cursor\n ? loadedOptionCount.current + result.options.length\n : result.options.length;\n\n // An empty page that still hands back a cursor would loop forever.\n if (\n result.nextCursor &&\n result.options.length > 0 &&\n loadedOptionCount.current < MIN_SCROLLABLE_OPTION_COUNT\n ) {\n loadOptionsRef.current(nextSearchTextToLoad, result.nextCursor);\n }\n\n // Only the host knows which bound parameters are required, so a\n // control is disabled on its answer instead of on a browser guess.\n setStatus(\n result.waitingForFieldKeys.length\n ? 'WAITING_FOR_DEPENDENCIES'\n : 'VALID',\n );\n })\n .catch((requestError: unknown): void => {\n if (isSupersededRequest(controller, requestSequence, requestId)) {\n return;\n }\n\n // Anything that is not a DataSource code — a transport failure, or a\n // server-side error the host deliberately reduced to a generic\n // message — must not be rendered verbatim; it is English technical\n // copy the filler cannot act on.\n const message =\n readFormDataSourceErrorMessage(requestError) ??\n '選項來源暫時無法使用。';\n const code = readFormDataSourceErrorCode(requestError);\n\n setError(message);\n setStatus(\n readFailedQueryStatus(\n Boolean(code && RECOVERABLE_ERROR_CODES.includes(code)),\n hasValue,\n ),\n );\n });\n },\n [\n currentValueSignature,\n dynamicFieldSignature,\n effectiveContext,\n hasValue,\n pendingQueryStatus,\n queryFieldKey,\n queryFormData,\n queryRowValues,\n schemaSignature,\n uiSchemaSignature,\n ],\n );\n const loadOptionsRef = useRef(loadOptions);\n loadOptionsRef.current = loadOptions;\n\n const runResolve = useCallback((): void => {\n if (!dynamicField || !effectiveContext || selectedValues.length === 0) {\n return;\n }\n\n const signature = dataSourceRefreshSignature;\n const requestId = resolveSequence.current + 1;\n resolveSequence.current = requestId;\n resolveAbort.current?.abort();\n const controller = new AbortController();\n resolveAbort.current = controller;\n setError(null);\n\n const request =\n effectiveContext.kind === 'preview'\n ? previewResolveFormFieldOptions({\n fieldKey: queryFieldKey,\n formData: queryFormData,\n rowValues: queryRowValues,\n schema: input.schema,\n signal: controller.signal,\n uiSchema: input.uiSchema,\n values: selectedValues,\n })\n : resolveFormFieldOptions({\n fieldKey: queryFieldKey,\n formData: queryFormData,\n instanceId: effectiveContext.instanceId ?? null,\n rowValues: queryRowValues,\n signal: controller.signal,\n templateId: effectiveContext.templateId ?? null,\n values: selectedValues,\n });\n\n void request\n .then((result): void => {\n if (isSupersededRequest(controller, resolveSequence, requestId)) {\n return;\n }\n\n if (result.waitingForFieldKeys.length) {\n // The host could not consult the provider, so this is no answer about\n // the value: leave the field waiting rather than call it resolved.\n setStatus('WAITING_FOR_DEPENDENCIES');\n\n return;\n }\n\n // Authoritative labels for the values that survived, merged so the old\n // snapshot label of an unresolved value stays visible for recognition.\n setRemoteOptions((currentOptions) =>\n mergeFormDataSourceOptions(currentOptions, result.options),\n );\n setResolution({\n signature,\n unresolvedValues: result.unresolvedValues,\n });\n // `invalidValues` turns this into `INVALID` when anything went missing.\n setStatus('VALID');\n })\n .catch((requestError: unknown): void => {\n if (isSupersededRequest(controller, resolveSequence, requestId)) {\n return;\n }\n\n setStatus('UNAVAILABLE');\n setError(\n readFormDataSourceErrorMessage(requestError) ??\n '選項來源暫時無法使用。',\n );\n });\n }, [\n dataSourceRefreshSignature,\n dynamicFieldSignature,\n effectiveContext,\n queryFieldKey,\n queryFormData,\n queryRowValues,\n schemaSignature,\n selectedValues,\n uiSchemaSignature,\n ]);\n const runResolveRef = useRef(runResolve);\n runResolveRef.current = runResolve;\n\n useEffect((): void => {\n requestSequence.current += 1;\n optionsAbort.current?.abort();\n setRemoteOptions((currentOptions) =>\n readSelectedFormDataSourceOptions(currentValue, currentOptions),\n );\n setNextCursor((currentCursor) =>\n currentCursor === null ? currentCursor : null,\n );\n setSearchText((currentSearchText) =>\n currentSearchText ? '' : currentSearchText,\n );\n setError((currentError) => (currentError ? null : currentError));\n\n if (!dynamicField) {\n setStatus('IDLE');\n\n return;\n }\n\n if (!autoQueries) {\n // AutoComplete queries on search only, so it stays quiescent until the\n // filler types; a context-less field has nothing to query at all.\n setStatus(quiescentStatus);\n\n return;\n }\n\n loadOptionsRef.current('', null);\n }, [\n autoQueries,\n dynamicFieldSignature,\n effectiveContext,\n dataSourceRefreshSignature,\n initialFormDataSignature,\n initialRowValuesSignature,\n input.readonly,\n pendingQueryStatus,\n quiescentStatus,\n snapshotSignature,\n ]);\n\n useEffect((): void => {\n if (!needsResolve) {\n return;\n }\n\n runResolveRef.current();\n }, [dataSourceRefreshSignature, effectiveContext, needsResolve]);\n\n useEffect((): (() => void) => {\n return (): void => {\n optionsAbort.current?.abort();\n resolveAbort.current?.abort();\n };\n }, []);\n\n const onSearch = useCallback(\n (nextSearchTextToLoad: string): void => {\n setSearchText(nextSearchTextToLoad);\n setRemoteOptions((currentOptions) =>\n readSelectedFormDataSourceOptions(currentValue, currentOptions),\n );\n setNextCursor(null);\n loadOptions(nextSearchTextToLoad, null);\n },\n [loadOptions],\n );\n const onReachBottom = useCallback((): void => {\n if (nextCursor) {\n loadOptions(searchText, nextCursor);\n }\n }, [loadOptions, nextCursor, searchText]);\n const retry = useCallback((): void => {\n if (!effectiveContext) {\n return;\n }\n\n loadOptions(lastRequest.current.searchText, lastRequest.current.cursor);\n\n if (needsResolve) {\n runResolveRef.current();\n }\n }, [effectiveContext, loadOptions, needsResolve]);\n\n if (!dynamicField) {\n return EMPTY_FIELD_STATE;\n }\n\n return {\n canRetry: Boolean(effectiveContext),\n error,\n hasValue,\n hasNextPage: Boolean(nextCursor),\n invalidValues,\n onReachBottom,\n onSearch,\n options: mergedOptions,\n retry,\n status: readFormDataSourceExposedStatus({\n invalidValues,\n resolvePending,\n status,\n }),\n };\n}\n\nexport function readFormDataSourceFieldStatusMessage(\n state: FormDataSourceFieldState,\n): string | null {\n switch (state.status) {\n case 'WAITING_FOR_DEPENDENCIES':\n return '請先填寫相依欄位。';\n case 'STALE':\n return '選項需要重新載入或驗證。';\n case 'INVALID':\n return state.invalidValues.length\n ? `無法辨識選項:${state.invalidValues.join('、')}`\n : '目前選項已失效,請重新選擇。';\n case 'UNAVAILABLE':\n return state.error ?? '選項來源暫時無法使用。';\n case 'VALID':\n // A recoverable search hint outranks the empty-result copy: it is what\n // tells the filler how to get results at all.\n return state.error ?? (state.options.length ? null : '目前沒有可用選項。');\n default:\n return state.error;\n }\n}\n\nexport function isFormDataSourceFieldSubmissionBlocked(\n state: Pick<FormDataSourceFieldState, 'hasValue' | 'status'>,\n): boolean {\n return state.hasValue && state.status !== 'VALID';\n}\n\n/**\n * The copy to show when a submission is refused because of dynamic options.\n * `LOADING` and `STALE` clear on their own once the pending query answers, so\n * saying \"finish validating\" reads as a dead end for what is really a \"wait a\n * moment\"; the caller would otherwise show the same permanent-sounding line for\n * both cases.\n *\n * Returns `null` when nothing blocks the submission.\n */\nexport function readFormDataSourceSubmissionBlockMessage(\n states: readonly Pick<FormDataSourceFieldState, 'hasValue' | 'status'>[],\n): string | null {\n const blocked = states.filter(isFormDataSourceFieldSubmissionBlocked);\n\n if (blocked.length === 0) {\n return null;\n }\n\n return blocked.every(\n (state) => state.status === 'LOADING' || state.status === 'STALE',\n )\n ? '選項驗證中,請稍候再送出。'\n : '請先完成動態選項驗證。';\n}\n\n/**\n * The values the field holds that no option accounts for.\n *\n * A completed resolve is the authority — the loaded pages are not, because the\n * option snapshot is merged into them for display and would vouch for a value\n * the source has already dropped.\n */\nfunction readInvalidFormDataSourceValues(input: {\n readonly options: readonly FormFieldOption[];\n readonly resolution: FormDataSourceResolution | null;\n readonly resolvePending: boolean;\n readonly value: FormFieldValue | undefined;\n}): readonly string[] {\n if (input.resolution) {\n return input.resolution.unresolvedValues;\n }\n\n // While the host is being asked, its answer is the only one worth showing.\n if (input.resolvePending) {\n return NO_INVALID_VALUES;\n }\n\n return readMissingFormDataSourceOptionValues(input.value, input.options);\n}\n\n/**\n * Status of a field nobody is querying — read-only history, a Designer preview\n * before the first search, or a control the host gave no context for.\n */\nfunction readQuiescentFormDataSourceStatus(input: {\n readonly hasSnapshot: boolean;\n readonly hasValue: boolean;\n readonly isStale: boolean;\n readonly readonly: boolean;\n}): FormDataSourceFieldStatus {\n if (input.isStale) {\n return 'STALE';\n }\n\n if (input.hasSnapshot) {\n return 'VALID';\n }\n\n // A read-only value with no snapshot cannot be labelled from anywhere, which\n // is worth saying. An empty read-only field is simply blank — warning about a\n // source nobody is going to query would be noise.\n return input.readonly && input.hasValue ? 'UNAVAILABLE' : 'IDLE';\n}\n\n/**\n * Status held while a query is in flight.\n *\n * `waiting` is the browser's optimistic guess and only survives until the host\n * answers: `waitingForFieldKeys` from the response replaces it either way, so an\n * optional binding left empty clears within one round trip instead of locking\n * the control.\n */\nfunction readPendingQueryStatus(\n isStale: boolean,\n waiting: boolean,\n): FormDataSourceFieldStatus {\n if (waiting) {\n return 'WAITING_FOR_DEPENDENCIES';\n }\n\n return isStale ? 'STALE' : 'LOADING';\n}\n\n/**\n * Status after a rejected query. A recoverable failure leaves the field as\n * usable as it was — only a broken source makes it unavailable.\n */\nfunction readFailedQueryStatus(\n recoverable: boolean,\n hasValue: boolean,\n): FormDataSourceFieldStatus {\n if (!recoverable) {\n return 'UNAVAILABLE';\n }\n\n return hasValue ? 'VALID' : 'IDLE';\n}\n\nfunction readFormDataSourceExposedStatus(input: {\n readonly invalidValues: readonly string[];\n readonly resolvePending: boolean;\n readonly status: FormDataSourceFieldStatus;\n}): FormDataSourceFieldStatus {\n if (\n input.status === 'LOADING' ||\n input.status === 'UNAVAILABLE' ||\n input.status === 'WAITING_FOR_DEPENDENCIES'\n ) {\n return input.status;\n }\n\n if (input.invalidValues.length) {\n return 'INVALID';\n }\n\n return input.resolvePending ? 'STALE' : input.status;\n}\n\n/**\n * True when a response no longer belongs to the field: its request was aborted\n * by a newer one, or a newer one started before it settled. Such a response\n * must not touch state — an aborted request is not a failure to report.\n */\nfunction isSupersededRequest(\n controller: AbortController,\n sequence: { readonly current: number },\n requestId: number,\n): boolean {\n return controller.signal.aborted || sequence.current !== requestId;\n}\n\nfunction readDefinedValues(\n values: FormRendererValues,\n): Readonly<Record<string, FormFieldValue>> {\n return Object.entries(values).reduce<\n Readonly<Record<string, FormFieldValue>>\n >((defined, [key, value]) => {\n if (typeof value === 'undefined') {\n return defined;\n }\n\n return { ...defined, [key]: value };\n }, {});\n}\n","'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Button,\n CheckboxGroup,\n DatePicker,\n DateTimePicker,\n Input,\n RadioGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n Upload,\n} from '@mezzanine-ui/react';\nimport type { UploadFile } from '@mezzanine-ui/react/Upload';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport {\n FormDataSourceOptionFieldDefinition,\n FormDataSourceValueSnapshots,\n FormDefinitionSchema,\n FormFieldDefinition,\n FormFieldValue,\n FormTableRowValue,\n FormUiSchema,\n TableColumnDefinition,\n TableFieldDefinition,\n isFormDataSourceFieldDefinition,\n isFormStaticOptionFieldDefinition,\n isFormTableCellValue,\n isTableFieldDefinition,\n readFormFieldSelectionMode,\n} from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n clampOptionalNumber,\n createFormTableRow,\n formatDatePickerValue,\n formatDateTimePickerValue,\n FormRendererValues,\n isFormRendererFieldReadonly,\n isFormRendererFieldRequired,\n parseOptionalNumberInput,\n readDatePickerValue,\n readFieldOptionAsSelectOption,\n readFormTableCellPath,\n readFormTableRowBounds,\n readFormTableRows,\n readSelectedFormDataSourceOptions,\n readSelectOption,\n readVisibleFormRendererFields,\n} from '@rytass/bpm-core-client/form';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport {\n FormDataSourceFieldState,\n FormRendererDataSourceContext,\n readFormDataSourceFieldStatusMessage,\n useFormDataSourceField,\n} from './form-data-source-field';\n\nexport interface FormRendererProps {\n readonly dataSourceContext?: FormRendererDataSourceContext;\n readonly dataSourceInitialValues?: FormRendererValues;\n readonly emptyText?: string;\n readonly errors?: Readonly<Record<string, string>>;\n readonly maxWidth?: CSSProperties['maxWidth'];\n readonly onChange?: (values: FormRendererValues) => void;\n readonly onDataSourceStateChange?: (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'status'\n >,\n ) => void;\n readonly onUploadAttachment?: (\n field: FormFieldDefinition,\n file: File,\n ) => Promise<{ readonly id: string }>;\n readonly optionSnapshots?: FormDataSourceValueSnapshots;\n readonly readonly?: boolean;\n readonly schema: FormDefinitionSchema;\n readonly singleColumn?: boolean;\n readonly uiSchema: FormUiSchema;\n readonly value?: FormRendererValues;\n}\n\n/**\n * Controls inside a table cell take the table's own `sub` size, so a row is\n * sized by its cells rather than by whichever control kept the default.\n * `DatePicker` and `DateTimePicker` accept no size, so a date column stays at\n * the default height — a Mezzanine limitation, not a choice.\n */\ntype ControlSize = 'main' | 'sub';\n\nconst FORM_RENDERER_GRID_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'grid',\n gap: 12,\n gridTemplateColumns: 'repeat(12, minmax(0, 1fr))',\n};\n\nconst FORM_RENDERER_EMPTY_STYLE: CSSProperties = {\n gridColumn: '1 / -1',\n};\n\nconst FORM_RENDERER_FIELD_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'grid',\n gap: 8,\n minWidth: 0,\n};\n\nconst TEXTAREA_STYLE: CSSProperties = {\n minWidth: '100%',\n width: '100%',\n};\n\nfunction applyFullWidthTextareaHost(element: HTMLDivElement | null): void {\n if (!element) {\n return;\n }\n\n element.style.width = '100%';\n}\n\nexport function FormRenderer({\n dataSourceContext,\n dataSourceInitialValues,\n emptyText = '尚未建立欄位。',\n errors = {},\n maxWidth,\n onChange,\n onDataSourceStateChange,\n onUploadAttachment,\n optionSnapshots,\n readonly = false,\n schema,\n singleColumn = false,\n uiSchema,\n value,\n}: FormRendererProps): ReactElement {\n const [internalValues, setInternalValues] = useState<FormRendererValues>(() =>\n buildFormRendererValues(schema.fields, value ?? {}),\n );\n const values = useMemo(\n (): FormRendererValues =>\n buildFormRendererValues(schema.fields, value ?? internalValues),\n [internalValues, schema.fields, value],\n );\n const valuesRef = useRef<FormRendererValues>(values);\n const visibleFields = useMemo(\n (): readonly FormFieldDefinition[] =>\n readVisibleFormRendererFields(schema, uiSchema, values),\n [schema, uiSchema, values],\n );\n\n useEffect((): void => {\n valuesRef.current = values;\n }, [values]);\n\n useEffect((): void => {\n setInternalValues((currentValues) =>\n buildFormRendererValues(schema.fields, value ?? currentValues),\n );\n }, [schema.fields, value]);\n\n function updateValue(\n fieldKey: string,\n nextValue: FormFieldValue | undefined,\n ): void {\n const nextValues = {\n ...valuesRef.current,\n [fieldKey]: nextValue,\n };\n valuesRef.current = nextValues;\n\n if (!value) {\n setInternalValues(nextValues);\n }\n\n onChange?.(nextValues);\n }\n\n if (!visibleFields.length) {\n return (\n <div style={FORM_RENDERER_GRID_STYLE}>\n <Typography\n color=\"text-neutral\"\n style={FORM_RENDERER_EMPTY_STYLE}\n variant=\"body\"\n >\n {schema.fields.length > 0 ? '目前條件下沒有可填寫欄位。' : emptyText}\n </Typography>\n </div>\n );\n }\n\n return (\n <div\n style={{\n ...FORM_RENDERER_GRID_STYLE,\n // `maxWidth` is applied per field rather than to the grid, so a table\n // field can use the full content width while every other field keeps\n // the single-column reading width (docs/17 P4).\n ...(singleColumn ? { width: '100%' } : {}),\n }}\n >\n {visibleFields.map((field) => (\n <FormRendererField\n dataSourceContext={dataSourceContext}\n dataSourceInitialValues={dataSourceInitialValues}\n field={field}\n error={errors[field.fieldKey] ?? null}\n errors={errors}\n fields={schema.fields}\n key={field.fieldKey}\n onChange={updateValue}\n onDataSourceStateChange={onDataSourceStateChange}\n onUploadAttachment={onUploadAttachment}\n optionSnapshots={optionSnapshots}\n readonly={readonly}\n schema={schema}\n style={{\n ...FORM_RENDERER_FIELD_STYLE,\n gridColumn: `span ${\n singleColumn ? 12 : readFieldColumnSpan(field, uiSchema)\n }`,\n ...(singleColumn && !isTableFieldDefinition(field)\n ? { maxWidth }\n : {}),\n }}\n value={values[field.fieldKey]}\n values={values}\n uiSchema={uiSchema}\n />\n ))}\n </div>\n );\n}\n\nfunction FormRendererField({\n dataSourceContext,\n dataSourceInitialValues,\n error,\n errors,\n field,\n fields,\n onChange,\n onDataSourceStateChange,\n onUploadAttachment,\n optionSnapshots,\n readonly,\n schema,\n style,\n value,\n values,\n uiSchema,\n}: {\n readonly dataSourceContext?: FormRendererDataSourceContext;\n readonly dataSourceInitialValues?: FormRendererValues;\n readonly error: string | null;\n /**\n * The whole error map, not just this field's line: a table addresses its\n * cells by instance path, so it needs the keys of its own rows too\n * (ADR 16 §3.3).\n */\n readonly errors: Readonly<Record<string, string>>;\n readonly field: FormFieldDefinition;\n readonly fields: readonly FormFieldDefinition[];\n readonly onChange: (\n fieldKey: string,\n value: FormFieldValue | undefined,\n ) => void;\n readonly onDataSourceStateChange?: (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'status'\n >,\n ) => void;\n readonly onUploadAttachment?:\n | ((\n field: FormFieldDefinition,\n file: File,\n ) => Promise<{ readonly id: string }>)\n | undefined;\n readonly optionSnapshots?: FormDataSourceValueSnapshots;\n readonly readonly: boolean;\n readonly schema: FormDefinitionSchema;\n readonly style: CSSProperties;\n readonly uiSchema: FormUiSchema;\n readonly value: FormFieldValue | undefined;\n readonly values: FormRendererValues;\n}): ReactElement {\n const required = isFormRendererFieldRequired(field, fields, values);\n const fieldReadonly =\n readonly || isFormRendererFieldReadonly(field, fields, values);\n const dataSourceState = useFormDataSourceField({\n context: dataSourceContext,\n field,\n formData: values,\n initialFormData: dataSourceInitialValues,\n initialValue: dataSourceInitialValues?.[field.fieldKey],\n optionSnapshots,\n readonly: fieldReadonly,\n schema,\n uiSchema,\n });\n const dataSourceStatusMessage = readFormDataSourceFieldStatusMessage(\n dataSourceState,\n );\n const dataSourceStateSignature = JSON.stringify({\n hasValue: dataSourceState.hasValue,\n invalidValues: dataSourceState.invalidValues,\n status: dataSourceState.status,\n });\n\n useEffect((): void => {\n if (!isFormDataSourceFieldDefinition(field)) {\n return;\n }\n\n onDataSourceStateChange?.(field.fieldKey, {\n hasValue: dataSourceState.hasValue,\n invalidValues: dataSourceState.invalidValues,\n status: dataSourceState.status,\n });\n }, [\n dataSourceStateSignature,\n field.fieldKey,\n onDataSourceStateChange,\n ]);\n\n return (\n <div data-form-field-key={field.fieldKey} style={style}>\n <BPMFormField\n label={field.label}\n name={field.fieldKey}\n required={required}\n >\n {isTableFieldDefinition(field) ? (\n <FormTableField\n dataSourceContext={dataSourceContext}\n dataSourceInitialValues={dataSourceInitialValues}\n errors={errors}\n field={field}\n onChange={onChange}\n onDataSourceStateChange={onDataSourceStateChange}\n optionSnapshots={optionSnapshots}\n readonly={fieldReadonly}\n schema={schema}\n uiSchema={uiSchema}\n value={value}\n values={values}\n />\n ) : (\n renderControl(\n field,\n value,\n fieldReadonly,\n onChange,\n onUploadAttachment,\n dataSourceContext,\n dataSourceState,\n )\n )}\n </BPMFormField>\n {error ? (\n <Typography color=\"text-error\" variant=\"caption\">\n {error}\n </Typography>\n ) : null}\n {dataSourceStatusMessage ? (\n <div style={DATA_SOURCE_FEEDBACK_STYLE}>\n <Typography\n color={\n dataSourceState.status === 'INVALID' ||\n dataSourceState.status === 'UNAVAILABLE'\n ? 'text-error'\n : 'text-neutral'\n }\n variant=\"caption\"\n >\n {dataSourceStatusMessage}\n </Typography>\n {dataSourceState.status === 'UNAVAILABLE' && dataSourceState.canRetry ? (\n <Button\n onClick={dataSourceState.retry}\n size=\"sub\"\n type=\"button\"\n variant=\"base-ghost\"\n >\n 重試\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\nconst DATA_SOURCE_FEEDBACK_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n gap: 8,\n};\n\nconst TABLE_FIELD_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n minWidth: 0,\n width: '100%',\n};\n\nconst TABLE_FIELD_ACTIONS_STYLE: CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-start',\n};\n\nconst TABLE_SCROLLER_STYLE: CSSProperties = {\n maxWidth: '100%',\n overflowX: 'auto',\n};\n\n// Mezzanine `Table` fills whatever box it is given, so an `overflow-x: auto`\n// wrapper on its own never scrolls: the columns just keep shrinking. Keeping\n// the table out of the single-column reading width is what stops a control\n// from overflowing its own cell; this floor is the defence for tables wide\n// enough that even the full width would squeeze them, and it is what makes the\n// wrapper actually scroll when that happens.\nconst TABLE_COLUMN_MIN_WIDTH = 160;\nconst TABLE_ACTIONS_COLUMN_WIDTH = 56;\n\nconst TABLE_CELL_STYLE: CSSProperties = {\n display: 'grid',\n gap: 4,\n minWidth: 0,\n};\n\ntype FormTableRowRecord = Readonly<\n Record<string, unknown> & {\n index: number;\n key: string;\n }\n>;\n\n/**\n * Rows carry no identity in `formData` — array order is display order\n * (ADR 16 §3.2) — so the React key and, from P3, the per-cell DataSource state\n * key come from an ephemeral id minted here and never written to the value.\n */\nfunction FormTableField({\n dataSourceContext,\n dataSourceInitialValues,\n errors,\n field,\n onChange,\n onDataSourceStateChange,\n optionSnapshots,\n readonly,\n schema,\n uiSchema,\n value,\n values,\n}: {\n readonly dataSourceContext?: FormRendererDataSourceContext;\n readonly dataSourceInitialValues?: FormRendererValues;\n readonly errors: Readonly<Record<string, string>>;\n readonly field: TableFieldDefinition;\n readonly onChange: (\n fieldKey: string,\n value: FormFieldValue | undefined,\n ) => void;\n readonly onDataSourceStateChange?: (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'status'\n >,\n ) => void;\n readonly optionSnapshots?: FormDataSourceValueSnapshots;\n readonly readonly: boolean;\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n readonly value: FormFieldValue | undefined;\n readonly values: FormRendererValues;\n}): ReactElement {\n const rows = readFormTableRows(value);\n const bounds = readFormTableRowBounds(field);\n const rowIdSequenceRef = useRef(0);\n const [rowIds, setRowIds] = useState<readonly string[]>(() =>\n rows.map((): string => createRowId(rowIdSequenceRef)),\n );\n\n // The value can also change from outside (a parent reset, a returned case\n // loading its saved rows). Re-mint ids only then, so ordinary edits keep the\n // per-row identity stable.\n useEffect((): void => {\n if (rowIds.length === rows.length) {\n return;\n }\n\n setRowIds(rows.map((): string => createRowId(rowIdSequenceRef)));\n }, [rowIds.length, rows.length]);\n\n function commitRows(nextRows: readonly FormTableRowValue[]): void {\n onChange(field.fieldKey, nextRows);\n }\n\n function handleAddRow(): void {\n setRowIds([...rowIds, createRowId(rowIdSequenceRef)]);\n commitRows([...rows, createFormTableRow(field.columns)]);\n }\n\n function handleRemoveRow(rowIndex: number): void {\n setRowIds(rowIds.filter((_, index) => index !== rowIndex));\n commitRows(rows.filter((_, index) => index !== rowIndex));\n }\n\n function handleCellChange(\n rowIndex: number,\n columnKey: string,\n cellValue: FormFieldValue | undefined,\n ): void {\n commitRows(\n rows.map((row, index) =>\n index === rowIndex\n ? readNextTableRow(row, columnKey, cellValue)\n : row,\n ),\n );\n }\n\n const dataSource: readonly FormTableRowRecord[] = rows.map((row, index) => ({\n ...row,\n index,\n key: rowIds[index] ?? `row-${index}`,\n }));\n const columns: TableColumn<FormTableRowRecord>[] = field.columns.map(\n (column) => ({\n key: column.fieldKey,\n render: (row): ReactElement => (\n <FormTableCell\n column={column}\n dataSourceContext={dataSourceContext}\n error={\n errors[\n readFormTableCellPath(field.fieldKey, row.index, column.fieldKey)\n ] ?? null\n }\n fieldPath={`${field.fieldKey}.${column.fieldKey}`}\n formData={values}\n initialFormData={dataSourceInitialValues}\n initialRowValues={readInitialTableRow(\n dataSourceInitialValues?.[field.fieldKey],\n row.index,\n )}\n // Keyed by the ephemeral row id, so a cell's DataSource state follows\n // its row rather than its position (ADR 16 §3.9).\n key={`${rowIds[row.index] ?? row.index}-${column.fieldKey}`}\n onChange={(cellValue): void =>\n handleCellChange(row.index, column.fieldKey, cellValue)\n }\n onDataSourceStateChange={onDataSourceStateChange}\n optionSnapshots={optionSnapshots}\n path={readFormTableCellPath(\n field.fieldKey,\n row.index,\n column.fieldKey,\n )}\n readonly={readonly}\n rowValues={rows[row.index] ?? {}}\n schema={schema}\n uiSchema={uiSchema}\n />\n ),\n title: column.label || column.fieldKey,\n }),\n );\n const actions: TableActions<FormTableRowRecord> | undefined = readonly\n ? undefined\n : {\n render: (row): ReturnType<TableActions<FormTableRowRecord>['render']> => [\n {\n disabled: (): boolean => rows.length <= bounds.minRows,\n icon: TrashIcon,\n iconType: 'icon-only',\n name: '刪除此列',\n onClick: (): void => handleRemoveRow(row.index),\n variant: 'destructive-ghost',\n },\n ],\n width: 56,\n };\n\n return (\n <div style={TABLE_FIELD_STYLE}>\n {/*\n Mezzanine `Table`'s `scroll` is vertical only, so a wide table is kept\n inside its own horizontal scroller rather than pushing the page sideways.\n The wrapper adds no styling of its own to the table (ADR 16 §3.9 assumed\n `scroll` covered this; see docs/17).\n */}\n <div style={TABLE_SCROLLER_STYLE}>\n <div\n style={{\n minWidth:\n field.columns.length * TABLE_COLUMN_MIN_WIDTH +\n (actions ? TABLE_ACTIONS_COLUMN_WIDTH : 0),\n }}\n >\n <Table\n {...(actions ? { actions } : {})}\n columns={columns}\n dataSource={[...dataSource]}\n // Cells carry form controls rather than text, so the row height\n // comes from the roomy container token, not the compact default.\n rowHeightPreset=\"roomy\"\n showHeader\n size=\"sub\"\n />\n </div>\n </div>\n {readonly ? null : (\n <div style={TABLE_FIELD_ACTIONS_STYLE}>\n <Button\n disabled={rows.length >= bounds.maxRows}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={handleAddRow}\n size=\"sub\"\n type=\"button\"\n variant=\"base-secondary\"\n >\n {field.addRowLabel || '新增一列'}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction FormTableCell({\n column,\n dataSourceContext,\n error,\n fieldPath,\n formData,\n initialFormData,\n initialRowValues,\n onChange,\n onDataSourceStateChange,\n optionSnapshots,\n path,\n readonly,\n rowValues,\n schema,\n uiSchema,\n}: {\n readonly column: TableColumnDefinition;\n readonly dataSourceContext?: FormRendererDataSourceContext;\n readonly error: string | null;\n readonly fieldPath: string;\n readonly formData: FormRendererValues;\n readonly initialFormData?: FormRendererValues;\n readonly initialRowValues?: FormTableRowValue;\n readonly onChange: (value: FormFieldValue | undefined) => void;\n readonly onDataSourceStateChange?: (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'status'\n >,\n ) => void;\n readonly optionSnapshots?: FormDataSourceValueSnapshots;\n readonly path: string;\n readonly readonly: boolean;\n readonly rowValues: FormTableRowValue;\n readonly schema: FormDefinitionSchema;\n readonly uiSchema: FormUiSchema;\n}): ReactElement {\n const value = readTableCellValue(rowValues, column.fieldKey);\n const dataSourceState = useFormDataSourceField({\n context: dataSourceContext,\n field: column,\n fieldPath,\n formData,\n initialFormData,\n initialValue: initialRowValues\n ? readTableCellValue(initialRowValues, column.fieldKey)\n : undefined,\n optionSnapshots,\n readonly,\n row: {\n initialValues: initialRowValues,\n values: rowValues,\n },\n schema,\n snapshotKey: path,\n uiSchema,\n });\n const statusMessage = readFormDataSourceFieldStatusMessage(dataSourceState);\n const stateSignature = JSON.stringify({\n hasValue: dataSourceState.hasValue,\n invalidValues: dataSourceState.invalidValues,\n status: dataSourceState.status,\n });\n\n useEffect((): (() => void) | void => {\n if (!isFormDataSourceFieldDefinition(column)) {\n return;\n }\n\n onDataSourceStateChange?.(path, {\n hasValue: dataSourceState.hasValue,\n invalidValues: dataSourceState.invalidValues,\n status: dataSourceState.status,\n });\n\n // A deleted row must stop blocking the submit it can no longer be fixed in.\n return (): void => {\n onDataSourceStateChange?.(path, {\n hasValue: false,\n invalidValues: [],\n status: 'IDLE',\n });\n };\n }, [onDataSourceStateChange, path, stateSignature]);\n\n return (\n <div data-form-field-key={path} style={TABLE_CELL_STYLE}>\n {renderControl(\n column,\n value,\n readonly,\n (_columnKey, nextValue): void => onChange(nextValue),\n undefined,\n dataSourceContext,\n dataSourceState,\n 'sub',\n )}\n {error ? (\n <Typography color=\"text-error\" variant=\"caption\">\n {error}\n </Typography>\n ) : null}\n {statusMessage ? (\n <div style={DATA_SOURCE_FEEDBACK_STYLE}>\n <Typography\n color={\n dataSourceState.status === 'INVALID' ||\n dataSourceState.status === 'UNAVAILABLE'\n ? 'text-error'\n : 'text-neutral'\n }\n variant=\"caption\"\n >\n {statusMessage}\n </Typography>\n {dataSourceState.status === 'UNAVAILABLE' &&\n dataSourceState.canRetry ? (\n <Button\n onClick={dataSourceState.retry}\n size=\"sub\"\n type=\"button\"\n variant=\"base-ghost\"\n >\n 重試\n </Button>\n ) : null}\n </div>\n ) : null}\n </div>\n );\n}\n\n/**\n * The row as it was loaded, used to tell a returned case's stored values from\n * edits. Absent when the table itself is new.\n */\nfunction readInitialTableRow(\n value: FormFieldValue | undefined,\n rowIndex: number,\n): FormTableRowValue | undefined {\n return readFormTableRows(value)[rowIndex];\n}\n\nfunction createRowId(sequenceRef: { current: number }): string {\n sequenceRef.current += 1;\n\n return `table-row-${sequenceRef.current}`;\n}\n\n/**\n * Clearing a cell removes the key instead of storing `undefined`: the row is\n * serialised to JSON, where `undefined` would vanish anyway, and an absent key\n * is what an untouched cell looks like.\n */\nfunction readNextTableRow(\n row: FormTableRowValue,\n columnKey: string,\n value: FormFieldValue | undefined,\n): FormTableRowValue {\n if (typeof value === 'undefined' || !isFormTableCellValue(value)) {\n return Object.fromEntries(\n Object.entries(row).filter(([key]) => key !== columnKey),\n );\n }\n\n return { ...row, [columnKey]: value };\n}\n\nfunction readTableCellValue(\n row: FormTableRowValue | undefined,\n columnKey: string,\n): FormFieldValue | undefined {\n if (!row || !Object.prototype.hasOwnProperty.call(row, columnKey)) {\n return undefined;\n }\n\n return row[columnKey];\n}\n\nfunction renderControl(\n field: FormFieldDefinition,\n value: FormFieldValue | undefined,\n readonly: boolean,\n onChange: (fieldKey: string, value: FormFieldValue | undefined) => void,\n onUploadAttachment:\n | ((\n field: FormFieldDefinition,\n file: File,\n ) => Promise<{ readonly id: string }>)\n | undefined,\n dataSourceContext: FormRendererDataSourceContext | undefined,\n dataSourceState: FormDataSourceFieldState,\n size: ControlSize = 'main',\n): ReactElement {\n if (isFormDataSourceFieldDefinition(field)) {\n return renderDynamicOptionControl(\n field,\n value,\n readonly,\n onChange,\n dataSourceContext,\n dataSourceState,\n size,\n );\n }\n\n return renderStaticControl(\n field,\n value,\n readonly,\n onChange,\n onUploadAttachment,\n size,\n );\n}\n\n/**\n * Every control that does not depend on a DataSource. Split out of\n * {@link renderControl} so a table cell can reuse the same controls without\n * carrying a field-level DataSource state it has no use for (ADR 16 §3.9).\n */\nfunction renderStaticControl(\n field: FormFieldDefinition,\n value: FormFieldValue | undefined,\n readonly: boolean,\n onChange: (fieldKey: string, value: FormFieldValue | undefined) => void,\n onUploadAttachment:\n | ((\n field: FormFieldDefinition,\n file: File,\n ) => Promise<{ readonly id: string }>)\n | undefined,\n size: ControlSize = 'main',\n): ReactElement {\n if (field.type === 'textarea') {\n return (\n <Textarea\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n onChange(field.fieldKey, event.target.value)\n }\n placeholder={field.placeholder ?? '請輸入多行文字'}\n readOnly={readonly}\n ref={applyFullWidthTextareaHost}\n rows={3}\n style={TEXTAREA_STYLE}\n value={readStringValue(value)}\n />\n );\n }\n\n if (field.type === 'boolean') {\n return (\n <Toggle\n checked={value === true}\n disabled={readonly}\n label=\"啟用\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(field.fieldKey, event.target.checked)\n }\n size={size}\n />\n );\n }\n\n if (isFormStaticOptionFieldDefinition(field) && field.type === 'checkbox') {\n const options = field.options.map(readFieldOptionAsSelectOption);\n\n return (\n <Select\n mode=\"multiple\"\n onChange={(options): void =>\n onChange(\n field.fieldKey,\n options?.length\n ? options.map((option) => option.id)\n : undefined,\n )\n }\n options={options}\n placeholder={field.placeholder ?? '請選擇一或多個選項'}\n readOnly={readonly}\n size={size}\n value={options.filter((option) =>\n readStringArrayValue(value).includes(option.id),\n )}\n />\n );\n }\n\n if (isFormStaticOptionFieldDefinition(field)) {\n const options = field.options.map(readFieldOptionAsSelectOption);\n\n return (\n <Select\n onChange={(option): void =>\n onChange(field.fieldKey, option?.id ?? undefined)\n }\n options={options}\n placeholder={field.placeholder ?? '請選擇'}\n readOnly={readonly}\n size={size}\n value={readSelectOption(options, readStringValue(value))}\n />\n );\n }\n\n if (field.type === 'file_upload') {\n return (\n <Upload\n accept={field.acceptedMimeTypes?.join(',')}\n disabled={readonly}\n maxFiles={field.maxFiles}\n mode=\"button-list\"\n {...((field.maxFiles ?? 1) > 1 ? { multiple: true } : {})}\n onChange={(files): void =>\n onChange(\n field.fieldKey,\n files.length ? files.map((file) => file.id) : undefined,\n )\n }\n onUpload={async (files): Promise<UploadFile[]> =>\n Promise.all(\n files.map(async (file): Promise<UploadFile> => {\n const uploadedFile = onUploadAttachment\n ? await onUploadAttachment(field, file)\n : { id: `${file.name}-${file.lastModified}` };\n\n return {\n file,\n id: uploadedFile.id,\n progress: 100,\n status: 'done',\n };\n }),\n )\n }\n size=\"sub\"\n />\n );\n }\n\n if (field.type === 'date') {\n return (\n <DatePicker\n format=\"YYYY-MM-DD\"\n fullWidth\n onChange={(nextValue): void =>\n onChange(field.fieldKey, formatDatePickerValue(nextValue))\n }\n placeholder={field.placeholder ?? readInputPlaceholder(field.type)}\n readOnly={readonly}\n value={readDatePickerValue(value)}\n />\n );\n }\n\n if (field.type === 'datetime') {\n return (\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n fullWidth\n hideSecond\n onChange={(nextValue): void =>\n onChange(field.fieldKey, formatDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"選擇日期\"\n placeholderRight=\"選擇時間\"\n readOnly={readonly}\n value={readDatePickerValue(value)}\n />\n );\n }\n\n if (field.type === 'number' || field.type === 'money') {\n return (\n <Input\n fullWidth\n max={field.maximum}\n min={field.minimum}\n size={size}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(\n field.fieldKey,\n clampOptionalNumber(parseOptionalNumberInput(event.target.value), {\n max: field.maximum,\n min: field.minimum,\n }),\n )\n }\n placeholder={field.placeholder ?? readInputPlaceholder(field.type)}\n {...(readonly ? { readonly: true as const } : {})}\n showSpinner\n value={readNumberInputValue(value)}\n variant=\"measure\"\n />\n );\n }\n\n return (\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(field.fieldKey, event.target.value)\n }\n placeholder={field.placeholder ?? readInputPlaceholder(field.type)}\n {...(readonly ? { readonly: true as const } : {})}\n size={size}\n value={readStringValue(value)}\n variant=\"base\"\n />\n );\n}\n\nfunction renderDynamicOptionControl(\n field: FormDataSourceOptionFieldDefinition,\n value: FormFieldValue | undefined,\n readonly: boolean,\n onChange: (fieldKey: string, value: FormFieldValue | undefined) => void,\n dataSourceContext: FormRendererDataSourceContext | undefined,\n dataSourceState: FormDataSourceFieldState,\n size: ControlSize = 'main',\n): ReactElement {\n const options = dataSourceState.options.map(readFieldOptionAsSelectOption);\n const selectedOptions = readSelectedFormDataSourceOptions(\n value,\n dataSourceState.options,\n ).map(readFieldOptionAsSelectOption);\n const loading = dataSourceState.status === 'LOADING';\n const waitingForDependencies =\n dataSourceState.status === 'WAITING_FOR_DEPENDENCIES';\n const interactiveSearch = Boolean(dataSourceContext) && !readonly;\n const optionControlDisabled = readonly || waitingForDependencies;\n // AutoComplete alone has no pre-query gate — it only learns a dependency is\n // missing from the answer to a search the filler already typed. Disabling it\n // at that point strands that text in a locked input with no way to clear it,\n // so it stays editable and reports the wait through the status line instead.\n const autoCompleteDisabled = readonly;\n\n if (field.type === 'autocomplete') {\n if (readFormFieldSelectionMode(field) === 'multiple') {\n return (\n <AutoComplete\n asyncData={interactiveSearch}\n clearSearchText\n disabled={autoCompleteDisabled}\n disabledOptionsFilter={interactiveSearch}\n globalPortal\n loading={loading}\n mode=\"multiple\"\n onChange={(nextOptions): void =>\n onChange(\n field.fieldKey,\n nextOptions.length\n ? nextOptions.map((option) => option.id)\n : undefined,\n )\n }\n onReachBottom={\n dataSourceState.hasNextPage\n ? dataSourceState.onReachBottom\n : undefined\n }\n onSearch={interactiveSearch ? dataSourceState.onSearch : undefined}\n options={options}\n placeholder={field.placeholder ?? '請輸入或選擇'}\n readOnly={readonly}\n searchDebounceTime={300}\n size={size}\n value={selectedOptions}\n />\n );\n }\n\n return (\n <AutoComplete\n asyncData={interactiveSearch}\n clearSearchText\n disabled={autoCompleteDisabled}\n disabledOptionsFilter={interactiveSearch}\n globalPortal\n loading={loading}\n mode=\"single\"\n onChange={(nextOption): void =>\n onChange(field.fieldKey, nextOption?.id ?? undefined)\n }\n onReachBottom={\n dataSourceState.hasNextPage\n ? dataSourceState.onReachBottom\n : undefined\n }\n onSearch={interactiveSearch ? dataSourceState.onSearch : undefined}\n options={options}\n placeholder={field.placeholder ?? '請輸入或選擇'}\n readOnly={readonly}\n searchDebounceTime={300}\n size={size}\n value={selectedOptions[0] ?? null}\n />\n );\n }\n\n if (field.type === 'radio') {\n return (\n <RadioGroup\n disabled={optionControlDisabled}\n name={field.fieldKey}\n onChange={(event): void =>\n onChange(field.fieldKey, event.target.value || undefined)\n }\n options={options}\n value={readStringValue(value)}\n />\n );\n }\n\n if (field.type === 'checkbox') {\n return (\n <CheckboxGroup\n disabled={optionControlDisabled}\n name={field.fieldKey}\n onChange={(event): void =>\n onChange(\n field.fieldKey,\n event.target.values.length ? event.target.values : undefined,\n )\n }\n options={options.map((option) => ({\n label: option.name,\n value: option.id,\n }))}\n value={[...readStringArrayValue(value)]}\n />\n );\n }\n\n if (readFormFieldSelectionMode(field) === 'multiple') {\n return (\n <Select\n disabled={optionControlDisabled}\n loading={loading}\n mode=\"multiple\"\n onChange={(nextOptions): void =>\n onChange(\n field.fieldKey,\n nextOptions.length\n ? nextOptions.map((option) => option.id)\n : undefined,\n )\n }\n onReachBottom={\n dataSourceState.hasNextPage\n ? dataSourceState.onReachBottom\n : undefined\n }\n options={options}\n placeholder={field.placeholder ?? '請選擇一或多個選項'}\n readOnly={readonly}\n size={size}\n value={selectedOptions}\n />\n );\n }\n\n return (\n <Select\n disabled={optionControlDisabled}\n loading={loading}\n onChange={(nextOption): void =>\n onChange(field.fieldKey, nextOption?.id ?? undefined)\n }\n onReachBottom={\n dataSourceState.hasNextPage\n ? dataSourceState.onReachBottom\n : undefined\n }\n options={options}\n placeholder={field.placeholder ?? '請選擇'}\n readOnly={readonly}\n size={size}\n value={selectedOptions[0] ?? null}\n />\n );\n}\n\nfunction readFieldColumnSpan(\n field: FormFieldDefinition,\n uiSchema: FormUiSchema,\n): number {\n const width =\n uiSchema.layout.find((item) => item.fieldKey === field.fieldKey)?.width ??\n 'FULL';\n const spans: Readonly<Record<typeof width, number>> = {\n FULL: 12,\n HALF: 6,\n THIRD: 4,\n };\n\n return spans[width];\n}\n\nfunction readStringValue(value: FormFieldValue | undefined): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction readStringArrayValue(\n value: FormFieldValue | undefined,\n): readonly string[] {\n // A table value is also an array, so the element check is what separates a\n // multi-select value from table rows here.\n return Array.isArray(value) && value.every((item) => typeof item === 'string')\n ? value\n : [];\n}\n\nfunction readNumberInputValue(value: FormFieldValue | undefined): string {\n return typeof value === 'number' ? String(value) : '';\n}\n\nfunction readInputPlaceholder(type: FormFieldDefinition['type']): string {\n const placeholders: Readonly<Record<FormFieldDefinition['type'], string>> = {\n boolean: '',\n autocomplete: '請輸入或選擇',\n checkbox: '請選擇一或多個選項',\n date: '請選擇日期',\n datetime: '請選擇日期與時間',\n file_upload: '請上傳附件',\n money: '請輸入金額',\n number: '請輸入數字',\n radio: '請選擇一個選項',\n select: '請選擇一個選項',\n table: '',\n text: '請輸入文字',\n textarea: '請輸入多行文字',\n };\n\n return placeholders[type];\n}\n\nexport { FormRenderer as FormRendererView };\n"],"mappings":"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"}