@rytass/bpm-core-react 0.20.1 → 0.21.1

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 (176) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/README.md +1 -1
  3. package/dist/approval-instance-list-page.css +1 -1
  4. package/dist/chunks/{FormBuilderView-CFRiw04B.js → FormBuilderView-6KdApi-D.js} +667 -584
  5. package/dist/chunks/FormBuilderView-6KdApi-D.js.map +1 -0
  6. package/dist/chunks/FormBuilderView-CGKkuVFi.cjs +4 -0
  7. package/dist/chunks/FormBuilderView-CGKkuVFi.cjs.map +1 -0
  8. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs → FormRendererView-B-xycC9S.cjs} +3 -3
  9. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs.map → FormRendererView-B-xycC9S.cjs.map} +1 -1
  10. package/dist/chunks/{FormRendererView-GfbVWEGa.js → FormRendererView-BcQKUi1A.js} +238 -238
  11. package/dist/chunks/{FormRendererView-GfbVWEGa.js.map → FormRendererView-BcQKUi1A.js.map} +1 -1
  12. package/dist/chunks/approval-instance-list-page-BI5fIXc-.js +724 -0
  13. package/dist/chunks/approval-instance-list-page-BI5fIXc-.js.map +1 -0
  14. package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs +2 -0
  15. package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs.map +1 -0
  16. package/dist/chunks/{categories-DQUtVEiV.cjs → categories-CyyqG6wG.cjs} +2 -2
  17. package/dist/chunks/{categories-DQUtVEiV.cjs.map → categories-CyyqG6wG.cjs.map} +1 -1
  18. package/dist/chunks/{categories-BAdxjNSA.js → categories-f7E-RJEc.js} +9 -9
  19. package/dist/chunks/{categories-BAdxjNSA.js.map → categories-f7E-RJEc.js.map} +1 -1
  20. package/dist/chunks/{compose-egQlRjuZ.js → compose-DFuLPmOA.js} +5 -5
  21. package/dist/chunks/{compose-egQlRjuZ.js.map → compose-DFuLPmOA.js.map} +1 -1
  22. package/dist/chunks/compose-DK3ocWwG.cjs +2 -0
  23. package/dist/chunks/compose-DK3ocWwG.cjs.map +1 -0
  24. package/dist/chunks/{delegations-CVmtpkRn.cjs → delegations-ClRCwD1I.cjs} +2 -2
  25. package/dist/chunks/{delegations-CVmtpkRn.cjs.map → delegations-ClRCwD1I.cjs.map} +1 -1
  26. package/dist/chunks/{delegations-9-yvWWws.js → delegations-CqND-Qtz.js} +5 -5
  27. package/dist/chunks/{delegations-9-yvWWws.js.map → delegations-CqND-Qtz.js.map} +1 -1
  28. package/dist/chunks/{delegations-CrfjsH94.cjs → delegations-D43VDSz1.cjs} +2 -2
  29. package/dist/chunks/{delegations-CrfjsH94.cjs.map → delegations-D43VDSz1.cjs.map} +1 -1
  30. package/dist/chunks/{delegations-CxnNvTCc.js → delegations-zisffLwk.js} +5 -5
  31. package/dist/chunks/{delegations-CxnNvTCc.js.map → delegations-zisffLwk.js.map} +1 -1
  32. package/dist/chunks/designer-CAUWEKJ4.cjs +69 -0
  33. package/dist/chunks/designer-CAUWEKJ4.cjs.map +1 -0
  34. package/dist/chunks/{designer-CZDlQ9Nf.js → designer-CCy5EbOe.js} +2380 -1786
  35. package/dist/chunks/designer-CCy5EbOe.js.map +1 -0
  36. package/dist/chunks/detail-C5KrUC7s.cjs +5 -0
  37. package/dist/chunks/detail-C5KrUC7s.cjs.map +1 -0
  38. package/dist/chunks/{detail-ByZV1XaI.js → detail-Dnc4PPWO.js} +804 -777
  39. package/dist/chunks/detail-Dnc4PPWO.js.map +1 -0
  40. package/dist/chunks/instance-error-message-BEM4O_Kj.js +208 -0
  41. package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +1 -0
  42. package/dist/chunks/instance-error-message-BpCLCOjp.cjs +2 -0
  43. package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +1 -0
  44. package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs +2 -0
  45. package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs.map +1 -0
  46. package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js +42 -0
  47. package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js.map +1 -0
  48. package/dist/chunks/{providers-BbCs23sk.js → providers-CQWekD7_.js} +197 -196
  49. package/dist/chunks/providers-CQWekD7_.js.map +1 -0
  50. package/dist/chunks/providers-VUOh6i0i.cjs +2 -0
  51. package/dist/chunks/providers-VUOh6i0i.cjs.map +1 -0
  52. package/dist/components/approval-instance-field-filter-controls.d.cts +12 -0
  53. package/dist/components/approval-instance-field-filter-controls.d.ts +12 -0
  54. package/dist/components/approval-instance-field-filters.d.cts +86 -0
  55. package/dist/components/approval-instance-field-filters.d.ts +86 -0
  56. package/dist/components/approval-instance-list-page.d.cts +4 -0
  57. package/dist/components/approval-instance-list-page.d.ts +4 -0
  58. package/dist/components/notification-drawer-options.d.cts +18 -0
  59. package/dist/components/notification-drawer-options.d.ts +18 -0
  60. package/dist/index.cjs +1 -1
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.d.cts +1 -0
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +23 -23
  65. package/dist/index.js.map +1 -1
  66. package/dist/lib/organization-time-zone-provider.d.cts +20 -0
  67. package/dist/lib/organization-time-zone-provider.d.ts +20 -0
  68. package/dist/lib/organization-time-zone.d.cts +8 -0
  69. package/dist/lib/organization-time-zone.d.ts +8 -0
  70. package/dist/lib/providers.d.cts +10 -1
  71. package/dist/lib/providers.d.ts +10 -1
  72. package/dist/next/BPMNextProviders.d.cts +8 -1
  73. package/dist/next/BPMNextProviders.d.ts +8 -1
  74. package/dist/next/index.cjs +1 -1
  75. package/dist/next/index.cjs.map +1 -1
  76. package/dist/next/index.js +12 -11
  77. package/dist/next/index.js.map +1 -1
  78. package/dist/next/workflow-chat-route.cjs +2 -2
  79. package/dist/next/workflow-chat-route.cjs.map +1 -1
  80. package/dist/next/workflow-chat-route.js +13 -13
  81. package/dist/pages/admin/delegations/index.cjs +1 -1
  82. package/dist/pages/admin/delegations/index.js +1 -1
  83. package/dist/pages/delegations/index.cjs +1 -1
  84. package/dist/pages/delegations/index.js +1 -1
  85. package/dist/pages/instances/detail/index.cjs +1 -1
  86. package/dist/pages/instances/detail/index.js +1 -1
  87. package/dist/pages/templates/categories/index.cjs +1 -1
  88. package/dist/pages/templates/categories/index.js +1 -1
  89. package/dist/pages/templates/compose/index.cjs +1 -1
  90. package/dist/pages/templates/compose/index.js +1 -1
  91. package/dist/pages/templates/designer/index.cjs +1 -1
  92. package/dist/pages/templates/designer/index.js +1 -1
  93. package/dist/views/admin/delegations/index.cjs +1 -1
  94. package/dist/views/admin/delegations/index.js +1 -1
  95. package/dist/views/admin/index.cjs +1 -1
  96. package/dist/views/admin/index.js +1 -1
  97. package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
  98. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  99. package/dist/views/admin/webhook-endpoints/index.js +60 -60
  100. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  101. package/dist/views/cc/index.cjs +1 -1
  102. package/dist/views/cc/index.js +1 -1
  103. package/dist/views/delegations/index.cjs +1 -1
  104. package/dist/views/delegations/index.js +1 -1
  105. package/dist/views/forms/builder/FormBuilderView.d.cts +8 -1
  106. package/dist/views/forms/builder/FormBuilderView.d.ts +8 -1
  107. package/dist/views/forms/builder/index.cjs +1 -1
  108. package/dist/views/forms/builder/index.js +1 -1
  109. package/dist/views/forms/renderer/index.cjs +1 -1
  110. package/dist/views/forms/renderer/index.js +1 -1
  111. package/dist/views/instances/approver-filled-form.d.cts +8 -5
  112. package/dist/views/instances/approver-filled-form.d.ts +8 -5
  113. package/dist/views/instances/detail/index.cjs +1 -1
  114. package/dist/views/instances/detail/index.js +1 -1
  115. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +2 -1
  116. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +2 -1
  117. package/dist/views/instances/detail/sections/shared.d.cts +0 -1
  118. package/dist/views/instances/detail/sections/shared.d.ts +0 -1
  119. package/dist/views/instances/new/index.cjs +1 -1
  120. package/dist/views/instances/new/index.cjs.map +1 -1
  121. package/dist/views/instances/new/index.js +8 -8
  122. package/dist/views/instances/new/index.js.map +1 -1
  123. package/dist/views/search/index.cjs +1 -1
  124. package/dist/views/search/index.js +1 -1
  125. package/dist/views/sent/index.cjs +1 -1
  126. package/dist/views/sent/index.js +1 -1
  127. package/dist/views/templates/categories/index.cjs +1 -1
  128. package/dist/views/templates/categories/index.js +1 -1
  129. package/dist/views/templates/compose/index.cjs +1 -1
  130. package/dist/views/templates/compose/index.js +1 -1
  131. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.cts +2 -0
  132. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.ts +2 -0
  133. package/dist/views/templates/designer/approver-resolver-model.d.cts +105 -1
  134. package/dist/views/templates/designer/approver-resolver-model.d.ts +105 -1
  135. package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +5 -0
  136. package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +5 -0
  137. package/dist/views/templates/designer/index.cjs +1 -1
  138. package/dist/views/templates/designer/index.js +1 -1
  139. package/dist/views/templates/designer/node-actor-resolver-options.d.cts +44 -1
  140. package/dist/views/templates/designer/node-actor-resolver-options.d.ts +44 -1
  141. package/dist/views/templates/designer/notify-recipient-options.d.cts +81 -0
  142. package/dist/views/templates/designer/notify-recipient-options.d.ts +81 -0
  143. package/dist/views/templates/designer/position-level-options.d.cts +3 -1
  144. package/dist/views/templates/designer/position-level-options.d.ts +3 -1
  145. package/dist/views/templates/designer/position-scope.d.cts +51 -0
  146. package/dist/views/templates/designer/position-scope.d.ts +51 -0
  147. package/dist/views/templates/index.cjs +1 -1
  148. package/dist/views/templates/index.cjs.map +1 -1
  149. package/dist/views/templates/index.js +7 -7
  150. package/package.json +3 -3
  151. package/dist/chunks/FormBuilderView-CFRiw04B.js.map +0 -1
  152. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +0 -3
  153. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +0 -1
  154. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js +0 -279
  155. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js.map +0 -1
  156. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs +0 -2
  157. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs.map +0 -1
  158. package/dist/chunks/compose-Bb5bUVFd.cjs +0 -2
  159. package/dist/chunks/compose-Bb5bUVFd.cjs.map +0 -1
  160. package/dist/chunks/designer-CX9bhYJS.cjs +0 -69
  161. package/dist/chunks/designer-CX9bhYJS.cjs.map +0 -1
  162. package/dist/chunks/designer-CZDlQ9Nf.js.map +0 -1
  163. package/dist/chunks/detail-ByZV1XaI.js.map +0 -1
  164. package/dist/chunks/detail-ChseSF55.cjs +0 -5
  165. package/dist/chunks/detail-ChseSF55.cjs.map +0 -1
  166. package/dist/chunks/instance-error-message-DTARGbGo.cjs +0 -2
  167. package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +0 -1
  168. package/dist/chunks/instance-error-message-q6gy5evy.js +0 -120
  169. package/dist/chunks/instance-error-message-q6gy5evy.js.map +0 -1
  170. package/dist/chunks/language-provider-Bdnx3Gxl.cjs +0 -2
  171. package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +0 -1
  172. package/dist/chunks/language-provider-phkWOapf.js +0 -17
  173. package/dist/chunks/language-provider-phkWOapf.js.map +0 -1
  174. package/dist/chunks/providers-BbCs23sk.js.map +0 -1
  175. package/dist/chunks/providers-D_KAgOOu.cjs +0 -2
  176. package/dist/chunks/providers-D_KAgOOu.cjs.map +0 -1
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/delegations-CrfjsH94.cjs");exports.DelegationsView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/delegations-D43VDSz1.cjs");exports.DelegationsView=e.t;
@@ -1 +1 @@
1
- export { t as DelegationsView } from "../../chunks/delegations-9-yvWWws.js";
1
+ export { t as DelegationsView } from "../../chunks/delegations-CqND-Qtz.js";
@@ -14,5 +14,12 @@ export interface FormBuilderViewProps {
14
14
  readonly schema: FormDefinitionSchema;
15
15
  readonly uiSchema: FormUiSchema;
16
16
  }) => void;
17
+ /**
18
+ * Template and form version this schema belongs to. With either given, the
19
+ * builder checks filterable fields against existing instances (ADR 25 §5.4)
20
+ * and shows issues; it never blocks a draft.
21
+ */
22
+ readonly formDefinitionId?: string | null;
23
+ readonly templateId?: string | null;
17
24
  }
18
- export declare function FormBuilderView({ onChange, value, }: FormBuilderViewProps): ReactElement;
25
+ export declare function FormBuilderView({ formDefinitionId, onChange, templateId, value, }: FormBuilderViewProps): ReactElement;
@@ -14,5 +14,12 @@ export interface FormBuilderViewProps {
14
14
  readonly schema: FormDefinitionSchema;
15
15
  readonly uiSchema: FormUiSchema;
16
16
  }) => void;
17
+ /**
18
+ * Template and form version this schema belongs to. With either given, the
19
+ * builder checks filterable fields against existing instances (ADR 25 §5.4)
20
+ * and shows issues; it never blocks a draft.
21
+ */
22
+ readonly formDefinitionId?: string | null;
23
+ readonly templateId?: string | null;
17
24
  }
18
- export declare function FormBuilderView({ onChange, value, }: FormBuilderViewProps): ReactElement;
25
+ export declare function FormBuilderView({ formDefinitionId, onChange, templateId, value, }: FormBuilderViewProps): ReactElement;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-CpUgbSbt.cjs");exports.FormBuilderView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-CGKkuVFi.cjs");exports.FormBuilderView=e.t;
@@ -1 +1 @@
1
- export { t as FormBuilderView } from "../../../chunks/FormBuilderView-CFRiw04B.js";
1
+ export { t as FormBuilderView } from "../../../chunks/FormBuilderView-6KdApi-D.js";
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-lYSaR8CQ.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.s,exports.readFileUploadSubmissionBlockMessage=e.a,exports.readFormDataSourceFieldStatusMessage=e.c,exports.readFormDataSourceSubmissionBlockMessage=e.l,exports.useFormDataSourceField=e.u;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-B-xycC9S.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.s,exports.readFileUploadSubmissionBlockMessage=e.a,exports.readFormDataSourceFieldStatusMessage=e.c,exports.readFormDataSourceSubmissionBlockMessage=e.l,exports.useFormDataSourceField=e.u;
@@ -1 +1 @@
1
- export { t as FormRenderer, t as FormRendererView, s as isFormDataSourceFieldSubmissionBlocked, a as readFileUploadSubmissionBlockMessage, c as readFormDataSourceFieldStatusMessage, l as readFormDataSourceSubmissionBlockMessage, u as useFormDataSourceField } from "../../../chunks/FormRendererView-GfbVWEGa.js";
1
+ export { t as FormRenderer, t as FormRendererView, s as isFormDataSourceFieldSubmissionBlocked, a as readFileUploadSubmissionBlockMessage, c as readFormDataSourceFieldStatusMessage, l as readFormDataSourceSubmissionBlockMessage, u as useFormDataSourceField } from "../../../chunks/FormRendererView-BcQKUi1A.js";
@@ -1,5 +1,5 @@
1
1
  import { UserTaskNode, WorkflowDefinition } from '@rytass/bpm-core-shared';
2
- import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
2
+ import { FormDefinitionSchema, FormDataIssue } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowFormData } from '@rytass/bpm-core-client/workflow';
4
4
  /**
5
5
  * The form as the applicant sees it: without the fields some approver fills in.
@@ -57,12 +57,15 @@ export declare function readFillChanges({ draft, node, schema, stored, values, }
57
57
  /** The server message of a fill against form data someone else changed. */
58
58
  export declare function isFillConflictMessage(message: string): boolean;
59
59
  /**
60
- * Turns the server's fill validation message (docs/08 §8.5, error table 2)
60
+ * Turns the server's fill validation refusal (docs/08 §8.5, error table 2)
61
61
  * into field errors keyed the way `FormRenderer` addresses them, so a check
62
- * the page missed still lands on the field. `null` when any part does not
63
- * parse — the caller then shows the message as it is.
62
+ * the page missed still lands on the field. `formDataIssues` is the refusal's
63
+ * structured list and wins when it is present: each issue names its value by
64
+ * path, so two fields sharing a label stay apart. Without it, the Chinese
65
+ * `message` is parsed. `null` when any part does not resolve to a fillable
66
+ * field — the caller then shows the message as it is.
64
67
  */
65
- export declare function readFillServerErrors(message: string, schema: FormDefinitionSchema, node: UserTaskNode): Readonly<Record<string, string>> | null;
68
+ export declare function readFillServerErrors(message: string, schema: FormDefinitionSchema, node: UserTaskNode, formDataIssues?: readonly FormDataIssue[]): Readonly<Record<string, string>> | null;
66
69
  export interface FillSummaryItem {
67
70
  readonly fieldKey: string;
68
71
  readonly label: string;
@@ -1,5 +1,5 @@
1
1
  import { UserTaskNode, WorkflowDefinition } from '@rytass/bpm-core-shared';
2
- import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
2
+ import { FormDefinitionSchema, FormDataIssue } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowFormData } from '@rytass/bpm-core-client/workflow';
4
4
  /**
5
5
  * The form as the applicant sees it: without the fields some approver fills in.
@@ -57,12 +57,15 @@ export declare function readFillChanges({ draft, node, schema, stored, values, }
57
57
  /** The server message of a fill against form data someone else changed. */
58
58
  export declare function isFillConflictMessage(message: string): boolean;
59
59
  /**
60
- * Turns the server's fill validation message (docs/08 §8.5, error table 2)
60
+ * Turns the server's fill validation refusal (docs/08 §8.5, error table 2)
61
61
  * into field errors keyed the way `FormRenderer` addresses them, so a check
62
- * the page missed still lands on the field. `null` when any part does not
63
- * parse — the caller then shows the message as it is.
62
+ * the page missed still lands on the field. `formDataIssues` is the refusal's
63
+ * structured list and wins when it is present: each issue names its value by
64
+ * path, so two fields sharing a label stay apart. Without it, the Chinese
65
+ * `message` is parsed. `null` when any part does not resolve to a fillable
66
+ * field — the caller then shows the message as it is.
64
67
  */
65
- export declare function readFillServerErrors(message: string, schema: FormDefinitionSchema, node: UserTaskNode): Readonly<Record<string, string>> | null;
68
+ export declare function readFillServerErrors(message: string, schema: FormDefinitionSchema, node: UserTaskNode, formDataIssues?: readonly FormDataIssue[]): Readonly<Record<string, string>> | null;
66
69
  export interface FillSummaryItem {
67
70
  readonly fieldKey: string;
68
71
  readonly label: string;
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/detail-ChseSF55.cjs");exports.InstanceAttachmentsSection=e.o,exports.InstanceDetailView=e.t,exports.InstanceFormSection=e.s,exports.InstanceHistorySection=e.r,exports.InstanceSignaturesSection=e.i,exports.InstanceTasksSection=e.a,exports.InstanceWebhookDeliveriesSection=e.n;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/detail-C5KrUC7s.cjs");exports.InstanceAttachmentsSection=e.o,exports.InstanceDetailView=e.t,exports.InstanceFormSection=e.s,exports.InstanceHistorySection=e.r,exports.InstanceSignaturesSection=e.i,exports.InstanceTasksSection=e.a,exports.InstanceWebhookDeliveriesSection=e.n;
@@ -1 +1 @@
1
- export { o as InstanceAttachmentsSection, t as InstanceDetailView, s as InstanceFormSection, r as InstanceHistorySection, i as InstanceSignaturesSection, a as InstanceTasksSection, n as InstanceWebhookDeliveriesSection } from "../../../chunks/detail-ByZV1XaI.js";
1
+ export { o as InstanceAttachmentsSection, t as InstanceDetailView, s as InstanceFormSection, r as InstanceHistorySection, i as InstanceSignaturesSection, a as InstanceTasksSection, n as InstanceWebhookDeliveriesSection } from "../../../chunks/detail-Dnc4PPWO.js";
@@ -1,4 +1,5 @@
1
1
  import { AdhocDirectiveRecord, ApprovalInstanceRecord, MemberProfileRecord, TaskRecord } from '@rytass/bpm-core-client/workflow';
2
+ import { FormDataIssue } from '@rytass/bpm-core-shared/form';
2
3
  import { FillSummaryItem } from '../../approver-filled-form.cjs';
3
4
  /**
4
5
  * Imperative handle exposed by InstanceTasksSection via ref.
@@ -50,7 +51,7 @@ export interface InstanceTasksSectionProps {
50
51
  * `true` means the container showed it (a conflict or field errors), so the
51
52
  * dialog closes instead of repeating it.
52
53
  */
53
- readonly onFillApproveError?: (message: string) => boolean;
54
+ readonly onFillApproveError?: (message: string, formDataIssues?: readonly FormDataIssue[]) => boolean;
54
55
  /** All tasks for this instance. */
55
56
  readonly tasks: readonly TaskRecord[];
56
57
  /** Ad-hoc directives recorded on this instance. */
@@ -1,4 +1,5 @@
1
1
  import { AdhocDirectiveRecord, ApprovalInstanceRecord, MemberProfileRecord, TaskRecord } from '@rytass/bpm-core-client/workflow';
2
+ import { FormDataIssue } from '@rytass/bpm-core-shared/form';
2
3
  import { FillSummaryItem } from '../../approver-filled-form.js';
3
4
  /**
4
5
  * Imperative handle exposed by InstanceTasksSection via ref.
@@ -50,7 +51,7 @@ export interface InstanceTasksSectionProps {
50
51
  * `true` means the container showed it (a conflict or field errors), so the
51
52
  * dialog closes instead of repeating it.
52
53
  */
53
- readonly onFillApproveError?: (message: string) => boolean;
54
+ readonly onFillApproveError?: (message: string, formDataIssues?: readonly FormDataIssue[]) => boolean;
54
55
  /** All tasks for this instance. */
55
56
  readonly tasks: readonly TaskRecord[];
56
57
  /** Ad-hoc directives recorded on this instance. */
@@ -123,7 +123,6 @@ export declare function readMemberOptionFromValue(value: unknown): MemberOption
123
123
  export declare function readUniqueMemberOption(searchText: string, options: readonly MemberOption[]): MemberOption | null;
124
124
  export declare function readTextDescriptionPart(text: string | null): ActivityStepDescriptionPart | null;
125
125
  export declare function readCommentDescriptionPart(label: string, text: string | null, tone?: 'danger' | 'neutral'): ActivityStepDescriptionPart | null;
126
- export declare function readMemberDescriptionPart(prefix: string, memberId: string | null, memberProfilesById: ReadonlyMap<string, MemberProfileRecord>, fallbackLabel: string): ActivityStepDescriptionPart;
127
126
  export declare function isActivityDescriptionPart(part: ActivityStepDescriptionPart | null): part is ActivityStepDescriptionPart;
128
127
  export declare function readCurrentActivityStep(activitySteps: readonly ActivityStepRecord[]): number;
129
128
  export declare function isUserMeaningfulActivity(activityLog: ActivityLogRecord): boolean;
@@ -123,7 +123,6 @@ export declare function readMemberOptionFromValue(value: unknown): MemberOption
123
123
  export declare function readUniqueMemberOption(searchText: string, options: readonly MemberOption[]): MemberOption | null;
124
124
  export declare function readTextDescriptionPart(text: string | null): ActivityStepDescriptionPart | null;
125
125
  export declare function readCommentDescriptionPart(label: string, text: string | null, tone?: 'danger' | 'neutral'): ActivityStepDescriptionPart | null;
126
- export declare function readMemberDescriptionPart(prefix: string, memberId: string | null, memberProfilesById: ReadonlyMap<string, MemberProfileRecord>, fallbackLabel: string): ActivityStepDescriptionPart;
127
126
  export declare function isActivityDescriptionPart(part: ActivityStepDescriptionPart | null): part is ActivityStepDescriptionPart;
128
127
  export declare function readCurrentActivityStep(activitySteps: readonly ActivityStepRecord[]): number;
129
128
  export declare function isUserMeaningfulActivity(activityLog: ActivityLogRecord): boolean;
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../../chunks/instance-error-message-DTARGbGo.cjs"),n=require("../../../chunks/format-date-time-D-cx5M8z.cjs"),r=require("../../../chunks/auth-provider-4BeCw7cI.cjs"),i=require("../../../chunks/router-adapter--gYs13E8.cjs"),a=require("../../../chunks/routes-config-C1j_vFKo.cjs"),o=require("../../../chunks/FormRendererView-lYSaR8CQ.cjs");let s=require("react"),c=require("@mezzanine-ui/react"),l=require("react/jsx-runtime"),u=require("@rytass/bpm-core-client/workflow"),d=require("@mezzanine-ui/react/ContentHeader");d=e.t(d,1);let f=require("@mezzanine-ui/icons"),p=require("@rytass/bpm-core-client/form");var m={display:`grid`,gap:16};function h(e={}){return(0,l.jsx)(s.Suspense,{fallback:(0,l.jsx)(_,{}),children:(0,l.jsx)(g,{templateId:e.templateId??void 0})})}function g({templateId:e}){let h=i.r(),g=a.r(),{member:_}=r.n(),v=_?.memberId??null,y=e??null,[b,x]=(0,s.useState)(null),[S,C]=(0,s.useState)({}),[w,T]=(0,s.useState)([]),[E,D]=(0,s.useState)(null),[O,k]=(0,s.useState)({}),[A,j]=(0,s.useState)(!0),[M,N]=(0,s.useState)(!1),[P,F]=(0,s.useState)({}),I=o.o(),L=(0,s.useMemo)(()=>b?t.r(b.formVersion.schema,b.templateVersion.workflowDefinition):null,[b]),R=(0,s.useCallback)((e,t)=>{F(n=>{let r=n[e];return r?.hasValue===t.hasValue&&r.selectionExpired===(t.selectionExpired===!0)&&r.status===t.status?n:{...n,[e]:{hasValue:t.hasValue,selectionExpired:t.selectionExpired===!0,status:t.status}}})},[]);(0,s.useEffect)(()=>{y?U(y):H()},[y]);let z=(0,s.useMemo)(()=>w.map(e=>({...e,key:e.id,updatedAt:n.t(e.updatedAt),versionLabel:`v${e.version}`})),[w]),B=(0,s.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:240},{dataIndex:`versionLabel`,key:`versionLabel`,title:`發布版本`,width:120},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),V=(0,s.useMemo)(()=>({render:e=>[{name:`發起`,onClick:()=>h.push(g.caseNew(e.id)),variant:`base-primary`}],variant:`base-secondary`,width:88}),[h]);async function H(){j(!0),D(null),x(null),F({});try{T(await(0,u.listLaunchableTemplates)())}catch(e){D(t.t(e))}finally{j(!1)}}async function U(e){j(!0),D(null),T([]),F({});try{x(await(0,u.readLaunchContext)(e))}catch(e){D(t.t(e))}finally{j(!1)}}async function W(){if(!b||!L||!v)return;N(!0),D(null),k({});let e=o.l(Object.values(P));if(e){D(e),N(!1);return}if(I.blockMessage){D(I.blockMessage),N(!1);return}let n=t.i((0,p.buildFormRendererValues)(L.fields,S),b.templateVersion.workflowDefinition);try{let e=await(0,p.validateFormRendererValuesInWorker)({schema:L,uiSchema:b.formVersion.uiSchema,values:n});if(!e.valid){k(e.errors),D(`請先修正表單中標示的欄位。`),e.firstInvalidFieldKey&&(0,p.focusFormRendererField)(e.firstInvalidFieldKey);return}let t=await(0,u.submitApprovalInstance)({formData:n,initiatorMemberId:v,templateId:b.template.id,title:(0,u.readFormDataCaseTitle)({fallbackTitle:b.template.name,formData:n,schema:L,uiSchema:b.formVersion.uiSchema})});h.push(g.caseDetail(t))}catch(e){D(t.t(e))}finally{N(!1)}}async function G(e,t){if(!v)throw Error(`尚未登入,無法上傳附件`);return{id:(await(0,u.uploadAttachment)({file:t,formFieldPath:`form.${e.fieldKey}`})).id}}return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.PageHeader,{children:(0,l.jsx)(d.default,{description:b?`${b.template.name} · 表單 v${b.formVersion.version}`:`選擇可發起的已發布模板後填寫表單內容。`,title:`發起簽核`,children:b?(0,l.jsx)(c.Button,{disabled:A||M,icon:f.CheckedIcon,iconType:`leading`,onClick:W,variant:`base-primary`,children:`送出`}):null})}),(0,l.jsx)(c.SectionGroup,{children:(0,l.jsx)(c.Section,{children:(0,l.jsxs)(`div`,{style:m,children:[E?(0,l.jsx)(c.Typography,{color:`text-error`,variant:`body`,children:E}):null,A?(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`}):null,b&&L?(0,l.jsx)(o.t,{dataSourceContext:{kind:`runtime`,templateId:b.template.id},errors:O,maxWidth:480,onChange:e=>{C(e),k({})},onDataSourceStateChange:R,onFileUploadStateChange:I.onFileUploadStateChange,onUploadAttachment:G,schema:L,singleColumn:!0,uiSchema:b.formVersion.uiSchema,value:S}):null,!y&&!A?z.length>0?(0,l.jsx)(c.Table,{actions:V,columns:B,dataSource:z,fullWidth:!0}):(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`目前沒有可發起的已發布模板。`}):null]})})})]})}function _(){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.PageHeader,{children:(0,l.jsx)(d.default,{description:`選擇可發起的已發布模板後填寫表單內容。`,title:`發起簽核`})}),(0,l.jsx)(c.SectionGroup,{children:(0,l.jsx)(c.Section,{children:(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`})})})]})}exports.InstanceNewView=h;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../../chunks/instance-error-message-BpCLCOjp.cjs"),n=require("../../../chunks/format-date-time-D-cx5M8z.cjs"),r=require("../../../chunks/auth-provider-4BeCw7cI.cjs"),i=require("../../../chunks/router-adapter--gYs13E8.cjs"),a=require("../../../chunks/routes-config-C1j_vFKo.cjs"),o=require("../../../chunks/FormRendererView-B-xycC9S.cjs");let s=require("react"),c=require("@mezzanine-ui/react"),l=require("react/jsx-runtime"),u=require("@rytass/bpm-core-client/workflow"),d=require("@mezzanine-ui/react/ContentHeader");d=e.t(d,1);let f=require("@rytass/bpm-core-client/form"),p=require("@mezzanine-ui/icons");var m={display:`grid`,gap:16};function h(e={}){return(0,l.jsx)(s.Suspense,{fallback:(0,l.jsx)(_,{}),children:(0,l.jsx)(g,{templateId:e.templateId??void 0})})}function g({templateId:e}){let h=i.r(),g=a.r(),{member:_}=r.n(),v=_?.memberId??null,y=e??null,[b,x]=(0,s.useState)(null),[S,C]=(0,s.useState)({}),[w,T]=(0,s.useState)([]),[E,D]=(0,s.useState)(null),[O,k]=(0,s.useState)({}),[A,j]=(0,s.useState)(!0),[M,N]=(0,s.useState)(!1),[P,F]=(0,s.useState)({}),I=o.o(),L=(0,s.useMemo)(()=>b?t.r(b.formVersion.schema,b.templateVersion.workflowDefinition):null,[b]),R=(0,s.useCallback)((e,t)=>{F(n=>{let r=n[e];return r?.hasValue===t.hasValue&&r.selectionExpired===(t.selectionExpired===!0)&&r.status===t.status?n:{...n,[e]:{hasValue:t.hasValue,selectionExpired:t.selectionExpired===!0,status:t.status}}})},[]);(0,s.useEffect)(()=>{y?U(y):H()},[y]);let z=(0,s.useMemo)(()=>w.map(e=>({...e,key:e.id,updatedAt:n.t(e.updatedAt),versionLabel:`v${e.version}`})),[w]),B=(0,s.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:240},{dataIndex:`versionLabel`,key:`versionLabel`,title:`發布版本`,width:120},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),V=(0,s.useMemo)(()=>({render:e=>[{name:`發起`,onClick:()=>h.push(g.caseNew(e.id)),variant:`base-primary`}],variant:`base-secondary`,width:88}),[h]);async function H(){j(!0),D(null),x(null),F({});try{T(await(0,u.listLaunchableTemplates)())}catch(e){D(t.t(e))}finally{j(!1)}}async function U(e){j(!0),D(null),T([]),F({});try{x(await(0,u.readLaunchContext)(e))}catch(e){D(t.t(e))}finally{j(!1)}}async function W(){if(!b||!L||!v)return;N(!0),D(null),k({});let e=o.l(Object.values(P));if(e){D(e),N(!1);return}if(I.blockMessage){D(I.blockMessage),N(!1);return}let n=t.i((0,f.buildFormRendererValues)(L.fields,S),b.templateVersion.workflowDefinition);try{let e=await(0,f.validateFormRendererValuesInWorker)({schema:L,uiSchema:b.formVersion.uiSchema,values:n});if(!e.valid){k(e.errors),D(`請先修正表單中標示的欄位。`),e.firstInvalidFieldKey&&(0,f.focusFormRendererField)(e.firstInvalidFieldKey);return}let t=await(0,u.submitApprovalInstance)({formData:n,initiatorMemberId:v,templateId:b.template.id,title:(0,u.readFormDataCaseTitle)({fallbackTitle:b.template.name,formData:n,schema:L,uiSchema:b.formVersion.uiSchema})});h.push(g.caseDetail(t))}catch(e){D(t.t(e))}finally{N(!1)}}async function G(e,t){if(!v)throw Error(`尚未登入,無法上傳附件`);return{id:(await(0,u.uploadAttachment)({file:t,formFieldPath:`form.${e.fieldKey}`})).id}}return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.PageHeader,{children:(0,l.jsx)(d.default,{description:b?`${b.template.name} · 表單 v${b.formVersion.version}`:`選擇可發起的已發布模板後填寫表單內容。`,title:`發起簽核`,children:b?(0,l.jsx)(c.Button,{disabled:A||M,icon:p.CheckedIcon,iconType:`leading`,onClick:W,variant:`base-primary`,children:`送出`}):null})}),(0,l.jsx)(c.SectionGroup,{children:(0,l.jsx)(c.Section,{children:(0,l.jsxs)(`div`,{style:m,children:[E?(0,l.jsx)(c.Typography,{color:`text-error`,variant:`body`,children:E}):null,A?(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`}):null,b&&L?(0,l.jsx)(o.t,{dataSourceContext:{kind:`runtime`,templateId:b.template.id},errors:O,maxWidth:480,onChange:e=>{C(e),k({})},onDataSourceStateChange:R,onFileUploadStateChange:I.onFileUploadStateChange,onUploadAttachment:G,schema:L,singleColumn:!0,uiSchema:b.formVersion.uiSchema,value:S}):null,!y&&!A?z.length>0?(0,l.jsx)(c.Table,{actions:V,columns:B,dataSource:z,fullWidth:!0}):(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`目前沒有可發起的已發布模板。`}):null]})})})]})}function _(){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.PageHeader,{children:(0,l.jsx)(d.default,{description:`選擇可發起的已發布模板後填寫表單內容。`,title:`發起簽核`})}),(0,l.jsx)(c.SectionGroup,{children:(0,l.jsx)(c.Section,{children:(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`})})})]})}exports.InstanceNewView=h;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Suspense","useRouterAdapter","useBPMRoutes","useAuth","useState","useFileUploadFieldStates","useMemo","readApplicantFormSchema","useCallback","formatDateTime","listLaunchableTemplates","readErrorMessage","readLaunchContext","readFormDataSourceSubmissionBlockMessage","readApplicantSubmission","buildFormRendererValues","validateFormRendererValuesInWorker","submitApprovalInstance","readFormDataCaseTitle","uploadAttachment","_Fragment","PageHeader","ContentHeader","Button","CheckedIcon","SectionGroup","Section","Typography","FormRenderer","Table","require_rolldown_runtime","require_instance_error_message","require_format_date_time","require_auth_provider","require_router_adapter","require_routes_config","require_FormRendererView","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_form","FORM_SECTION_STYLE","InstanceNewView","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","handleDataSourceStateChange","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","requestError","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","validation","instanceId","handleUploadAttachment","field","values"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Suspense","useRouterAdapter","useBPMRoutes","useAuth","useState","useFileUploadFieldStates","useMemo","readApplicantFormSchema","useCallback","formatDateTime","listLaunchableTemplates","readErrorMessage","readLaunchContext","readFormDataSourceSubmissionBlockMessage","readApplicantSubmission","buildFormRendererValues","validateFormRendererValuesInWorker","submitApprovalInstance","readFormDataCaseTitle","uploadAttachment","_Fragment","PageHeader","ContentHeader","Button","CheckedIcon","SectionGroup","Section","Typography","FormRenderer","Table","require_rolldown_runtime","require_instance_error_message","require_format_date_time","require_auth_provider","require_router_adapter","require_routes_config","require_FormRendererView","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_rytass_bpm_core_client_form","_mezzanine_ui_icons","FORM_SECTION_STYLE","InstanceNewView","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","handleDataSourceStateChange","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","requestError","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","validation","instanceId","handleUploadAttachment","field","values"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { i as e, r as t, t as n } from "../../../chunks/instance-error-message-q6gy5evy.js";
2
+ import { i as e, r as t, t as n } from "../../../chunks/instance-error-message-BEM4O_Kj.js";
3
3
  import { t as r } from "../../../chunks/format-date-time-B0LdmWg4.js";
4
4
  import { n as i } from "../../../chunks/auth-provider-C2b-5mGt.js";
5
5
  import { r as a } from "../../../chunks/router-adapter-CkxCyzf5.js";
6
6
  import { r as o } from "../../../chunks/routes-config-BcNaWJWJ.js";
7
- import { l as s, o as c, t as l } from "../../../chunks/FormRendererView-GfbVWEGa.js";
7
+ import { l as s, o as c, t as l } from "../../../chunks/FormRendererView-BcQKUi1A.js";
8
8
  import { Suspense as u, useCallback as d, useEffect as f, useMemo as p, useState as m } from "react";
9
9
  import { Button as ee, PageHeader as h, Section as g, SectionGroup as _, Table as v, Typography as y } from "@mezzanine-ui/react";
10
10
  import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
11
11
  import { listLaunchableTemplates as C, readFormDataCaseTitle as w, readLaunchContext as T, submitApprovalInstance as E, uploadAttachment as D } from "@rytass/bpm-core-client/workflow";
12
12
  import O from "@mezzanine-ui/react/ContentHeader";
13
- import { CheckedIcon as k } from "@mezzanine-ui/icons";
14
- import { buildFormRendererValues as te, focusFormRendererField as ne, validateFormRendererValuesInWorker as re } from "@rytass/bpm-core-client/form";
13
+ import { buildFormRendererValues as k, focusFormRendererField as te, validateFormRendererValuesInWorker as ne } from "@rytass/bpm-core-client/form";
14
+ import { CheckedIcon as re } from "@mezzanine-ui/icons";
15
15
  // src/views/instances/new/InstanceNewView.tsx
16
16
  var ie = {
17
17
  display: "grid",
@@ -105,15 +105,15 @@ function j({ templateId: u }) {
105
105
  H(X.blockMessage), J(!1);
106
106
  return;
107
107
  }
108
- let r = e(te(Z.fields, L), F.templateVersion.workflowDefinition);
108
+ let r = e(k(Z.fields, L), F.templateVersion.workflowDefinition);
109
109
  try {
110
- let e = await re({
110
+ let e = await ne({
111
111
  schema: Z,
112
112
  uiSchema: F.formVersion.uiSchema,
113
113
  values: r
114
114
  });
115
115
  if (!e.valid) {
116
- W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && ne(e.firstInvalidFieldKey);
116
+ W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && te(e.firstInvalidFieldKey);
117
117
  return;
118
118
  }
119
119
  let t = await E({
@@ -146,7 +146,7 @@ function j({ templateId: u }) {
146
146
  title: "發起簽核",
147
147
  children: F ? /* @__PURE__ */ x(ee, {
148
148
  disabled: G || q,
149
- icon: k,
149
+ icon: re,
150
150
  iconType: "leading",
151
151
  onClick: ue,
152
152
  variant: "base-primary",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-fqvmkBlg.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Cv5I1YPX.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BnI4t5mD.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-BI5fIXc-.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/search/SearchView.tsx
5
5
  function n() {
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-fqvmkBlg.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Cv5I1YPX.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BnI4t5mD.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-BI5fIXc-.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/sent/SentView.tsx
5
5
  function n() {
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/categories-DQUtVEiV.cjs");exports.TemplateCategoriesView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/categories-CyyqG6wG.cjs");exports.TemplateCategoriesView=e.t;
@@ -1 +1 @@
1
- export { t as TemplateCategoriesView } from "../../../chunks/categories-BAdxjNSA.js";
1
+ export { t as TemplateCategoriesView } from "../../../chunks/categories-f7E-RJEc.js";
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-Bb5bUVFd.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-DK3ocWwG.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
@@ -1 +1 @@
1
- export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-egQlRjuZ.js";
1
+ export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-DFuLPmOA.js";
@@ -12,6 +12,8 @@ export interface NotifyWebhookTargetsEditorProps {
12
12
  readonly onChange: (targets: readonly NotifyWebhookTarget[]) => void;
13
13
  readonly targets: readonly NotifyWebhookTarget[];
14
14
  }
15
+ /** Shown in place of the editor when the catalog has no usable endpoint. */
16
+ export declare const NOTIFY_WEBHOOK_NO_ENDPOINTS_MESSAGE = "\u76EE\u524D\u6C92\u6709\u53EF\u7528\u7684 Webhook \u7AEF\u9EDE\uFF0C\u8ACB\u6D3D BPM \u7BA1\u7406\u8005\u6216\u7CFB\u7D71\u6574\u5408\u4EBA\u54E1\u65B0\u589E\u7AEF\u9EDE\u5F8C\u518D\u8A2D\u5B9A\u3002";
15
17
  /**
16
18
  * Edits a NOTIFY node's webhook targets (ADR 18 §3.3). Parameters come from
17
19
  * the endpoint catalog, so the author only picks an endpoint and binds each
@@ -12,6 +12,8 @@ export interface NotifyWebhookTargetsEditorProps {
12
12
  readonly onChange: (targets: readonly NotifyWebhookTarget[]) => void;
13
13
  readonly targets: readonly NotifyWebhookTarget[];
14
14
  }
15
+ /** Shown in place of the editor when the catalog has no usable endpoint. */
16
+ export declare const NOTIFY_WEBHOOK_NO_ENDPOINTS_MESSAGE = "\u76EE\u524D\u6C92\u6709\u53EF\u7528\u7684 Webhook \u7AEF\u9EDE\uFF0C\u8ACB\u6D3D BPM \u7BA1\u7406\u8005\u6216\u7CFB\u7D71\u6574\u5408\u4EBA\u54E1\u65B0\u589E\u7AEF\u9EDE\u5F8C\u518D\u8A2D\u5B9A\u3002";
15
17
  /**
16
18
  * Edits a NOTIFY node's webhook targets (ADR 18 §3.3). Parameters come from
17
19
  * the endpoint catalog, so the author only picks an endpoint and binds each