@rytass/bpm-core-react 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/chunks/{FormBuilderView-vQfVc08Z.js → FormBuilderView-Djlm3y4S.js} +2 -2
  3. package/dist/chunks/{FormBuilderView-vQfVc08Z.js.map → FormBuilderView-Djlm3y4S.js.map} +1 -1
  4. package/dist/chunks/{FormBuilderView-CHaAQL5v.cjs → FormBuilderView-G6uRSywl.cjs} +2 -2
  5. package/dist/chunks/{FormBuilderView-CHaAQL5v.cjs.map → FormBuilderView-G6uRSywl.cjs.map} +1 -1
  6. package/dist/chunks/{FormRendererView-CTLlG13b.js → FormRendererView-DHfVgbo6.js} +391 -265
  7. package/dist/chunks/FormRendererView-DHfVgbo6.js.map +1 -0
  8. package/dist/chunks/FormRendererView-DwfFbaip.cjs +6 -0
  9. package/dist/chunks/FormRendererView-DwfFbaip.cjs.map +1 -0
  10. package/dist/chunks/{compose-D9ipJpF_.js → compose-D6zBIc2Z.js} +4 -4
  11. package/dist/chunks/{compose-D9ipJpF_.js.map → compose-D6zBIc2Z.js.map} +1 -1
  12. package/dist/chunks/{compose-DtfX8DQ9.cjs → compose-NH6dsFXD.cjs} +2 -2
  13. package/dist/chunks/{compose-DtfX8DQ9.cjs.map → compose-NH6dsFXD.cjs.map} +1 -1
  14. package/dist/chunks/{designer-Df79YzUn.cjs → designer-Be9UI9Tg.cjs} +2 -2
  15. package/dist/chunks/{designer-Df79YzUn.cjs.map → designer-Be9UI9Tg.cjs.map} +1 -1
  16. package/dist/chunks/{designer-ubnZbP-A.js → designer-uhC_7m2i.js} +3 -3
  17. package/dist/chunks/{designer-ubnZbP-A.js.map → designer-uhC_7m2i.js.map} +1 -1
  18. package/dist/chunks/detail-6uw5dmTi.cjs +5 -0
  19. package/dist/chunks/detail-6uw5dmTi.cjs.map +1 -0
  20. package/dist/chunks/{detail-C6XKZjlF.js → detail-_GeKqNC-.js} +851 -839
  21. package/dist/chunks/detail-_GeKqNC-.js.map +1 -0
  22. package/dist/chunks/{approver-filled-form-B4zPg9kz.cjs → instance-error-message-DTARGbGo.cjs} +2 -2
  23. package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +1 -0
  24. package/dist/chunks/{approver-filled-form-Bgazhbvd.js → instance-error-message-q6gy5evy.js} +44 -36
  25. package/dist/chunks/instance-error-message-q6gy5evy.js.map +1 -0
  26. package/dist/pages/instances/detail/index.cjs +1 -1
  27. package/dist/pages/instances/detail/index.js +1 -1
  28. package/dist/pages/templates/compose/index.cjs +1 -1
  29. package/dist/pages/templates/compose/index.js +1 -1
  30. package/dist/pages/templates/designer/index.cjs +1 -1
  31. package/dist/pages/templates/designer/index.js +1 -1
  32. package/dist/views/forms/builder/index.cjs +1 -1
  33. package/dist/views/forms/builder/index.js +1 -1
  34. package/dist/views/forms/renderer/FormRendererView.d.cts +24 -1
  35. package/dist/views/forms/renderer/FormRendererView.d.ts +24 -1
  36. package/dist/views/forms/renderer/file-upload-field.d.cts +84 -0
  37. package/dist/views/forms/renderer/file-upload-field.d.ts +84 -0
  38. package/dist/views/forms/renderer/form-value-readers.d.cts +7 -0
  39. package/dist/views/forms/renderer/form-value-readers.d.ts +7 -0
  40. package/dist/views/forms/renderer/index.cjs +1 -1
  41. package/dist/views/forms/renderer/index.d.cts +1 -0
  42. package/dist/views/forms/renderer/index.d.ts +1 -0
  43. package/dist/views/forms/renderer/index.js +1 -1
  44. package/dist/views/instances/detail/index.cjs +1 -1
  45. package/dist/views/instances/detail/index.js +1 -1
  46. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +19 -2
  47. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +19 -2
  48. package/dist/views/instances/detail/sections/shared.d.cts +1 -2
  49. package/dist/views/instances/detail/sections/shared.d.ts +1 -2
  50. package/dist/views/instances/instance-error-message.d.cts +5 -0
  51. package/dist/views/instances/instance-error-message.d.ts +5 -0
  52. package/dist/views/instances/new/index.cjs +1 -1
  53. package/dist/views/instances/new/index.cjs.map +1 -1
  54. package/dist/views/instances/new/index.js +77 -75
  55. package/dist/views/instances/new/index.js.map +1 -1
  56. package/dist/views/templates/compose/index.cjs +1 -1
  57. package/dist/views/templates/compose/index.js +1 -1
  58. package/dist/views/templates/designer/index.cjs +1 -1
  59. package/dist/views/templates/designer/index.js +1 -1
  60. package/package.json +3 -3
  61. package/dist/chunks/FormRendererView-CTLlG13b.js.map +0 -1
  62. package/dist/chunks/FormRendererView-ChmM_4Yc.cjs +0 -4
  63. package/dist/chunks/FormRendererView-ChmM_4Yc.cjs.map +0 -1
  64. package/dist/chunks/approver-filled-form-B4zPg9kz.cjs.map +0 -1
  65. package/dist/chunks/approver-filled-form-Bgazhbvd.js.map +0 -1
  66. package/dist/chunks/detail-BBC9kqXd.cjs +0 -5
  67. package/dist/chunks/detail-BBC9kqXd.cjs.map +0 -1
  68. package/dist/chunks/detail-C6XKZjlF.js.map +0 -1
@@ -0,0 +1,7 @@
1
+ import { FormFieldValue } from '@rytass/bpm-core-shared/form';
2
+ /**
3
+ * A multi-value field's ids or option values, or `[]` for anything else.
4
+ * A table value is also an array, so the element check is what separates a
5
+ * multi-select or `file_upload` value from table rows.
6
+ */
7
+ export declare function readStringArrayValue(value: FormFieldValue | undefined): readonly string[];
@@ -0,0 +1,7 @@
1
+ import { FormFieldValue } from '@rytass/bpm-core-shared/form';
2
+ /**
3
+ * A multi-value field's ids or option values, or `[]` for anything else.
4
+ * A table value is also an array, so the element check is what separates a
5
+ * multi-select or `file_upload` value from table rows.
6
+ */
7
+ export declare function readStringArrayValue(value: FormFieldValue | undefined): readonly string[];
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-ChmM_4Yc.cjs");exports.FormRenderer=e.t,exports.FormRendererView=e.t,exports.isFormDataSourceFieldSubmissionBlocked=e.a,exports.readFormDataSourceFieldStatusMessage=e.o,exports.readFormDataSourceSubmissionBlockMessage=e.s,exports.useFormDataSourceField=e.c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormRendererView-DwfFbaip.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,2 +1,3 @@
1
1
  export * from './FormRendererView.cjs';
2
2
  export * from './form-data-source-field.cjs';
3
+ export { readFileUploadSubmissionBlockMessage, type FileUploadFieldState, type FormRendererAttachment, } from './file-upload-field.cjs';
@@ -1,2 +1,3 @@
1
1
  export * from './FormRendererView.js';
2
2
  export * from './form-data-source-field.js';
3
+ export { readFileUploadSubmissionBlockMessage, type FileUploadFieldState, type FormRendererAttachment, } from './file-upload-field.js';
@@ -1 +1 @@
1
- export { t as FormRenderer, t as FormRendererView, a as isFormDataSourceFieldSubmissionBlocked, o as readFormDataSourceFieldStatusMessage, s as readFormDataSourceSubmissionBlockMessage, c as useFormDataSourceField } from "../../../chunks/FormRendererView-CTLlG13b.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-DHfVgbo6.js";
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/detail-BBC9kqXd.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-6uw5dmTi.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-C6XKZjlF.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-_GeKqNC-.js";
@@ -3,6 +3,7 @@ import { ResolvedFieldAccess } from '@rytass/bpm-core-shared';
3
3
  import { FormDefinitionSchema, FormFieldDefinition } from '@rytass/bpm-core-shared/form';
4
4
  import { ApprovalInstanceRecord, WorkflowFormData } from '@rytass/bpm-core-client/workflow';
5
5
  import { FormDataSourceFieldState } from '../../../forms/renderer/form-data-source-field.cjs';
6
+ import { FileUploadFieldState, FormRendererAttachment } from '../../../forms/renderer/file-upload-field.cjs';
6
7
  /** The fill state of the viewer's own task at a node that fills in fields. */
7
8
  export interface InstanceFormSectionFill {
8
9
  /** Field errors from the page's check or the server's, keyed by path. */
@@ -59,7 +60,23 @@ export interface InstanceFormSectionProps {
59
60
  readonly resubmitComment?: string;
60
61
  /** Called when the applicant edits the resubmission comment. */
61
62
  readonly onResubmitCommentChange?: ((value: string) => void) | null;
62
- /** Called when an attachment upload is requested via the form field. */
63
+ /**
64
+ * The instance's attachments, so a `file_upload` field lists the files its
65
+ * value holds by name.
66
+ */
67
+ readonly attachments?: readonly FormRendererAttachment[];
68
+ /** Opens an attachment a `file_upload` field lists. */
69
+ readonly onDownloadAttachment?: (attachmentId: string) => void;
70
+ /**
71
+ * Called when a `file_upload` field starts or settles an upload, so the
72
+ * container can refuse to resubmit while one is unsettled.
73
+ */
74
+ readonly onFileUploadStateChange?: (fieldKey: string, state: FileUploadFieldState) => void;
75
+ /**
76
+ * Uploads a file picked in a `file_upload` field while resubmitting. A fill
77
+ * node never edits one: an approver cannot fill in a `file_upload` field
78
+ * (ADR 20, refused at publish).
79
+ */
63
80
  readonly onUploadAttachment: (field: FormFieldDefinition, file: File) => Promise<{
64
81
  readonly id: string;
65
82
  }>;
@@ -69,4 +86,4 @@ export interface InstanceFormSectionProps {
69
86
  * Displays the form in read-only mode normally, or editable mode when the
70
87
  * instance has been returned and the current member can resubmit it.
71
88
  */
72
- export declare function InstanceFormSection({ canResubmitInstance, deciding, error, fieldAccess, fieldLabelMarkers, fill, instance, loading, onDataSourceStateChange, onResubmitFormChange, onReloadAfterConflict, onResubmitCommentChange, onResubmitInstance, onUploadAttachment, resubmitComment, resubmitFormData, resubmitFormErrors, }: InstanceFormSectionProps): ReactElement;
89
+ export declare function InstanceFormSection({ attachments, canResubmitInstance, deciding, error, fieldAccess, fieldLabelMarkers, fill, instance, loading, onDataSourceStateChange, onDownloadAttachment, onFileUploadStateChange, onResubmitFormChange, onReloadAfterConflict, onResubmitCommentChange, onResubmitInstance, onUploadAttachment, resubmitComment, resubmitFormData, resubmitFormErrors, }: InstanceFormSectionProps): ReactElement;
@@ -3,6 +3,7 @@ import { ResolvedFieldAccess } from '@rytass/bpm-core-shared';
3
3
  import { FormDefinitionSchema, FormFieldDefinition } from '@rytass/bpm-core-shared/form';
4
4
  import { ApprovalInstanceRecord, WorkflowFormData } from '@rytass/bpm-core-client/workflow';
5
5
  import { FormDataSourceFieldState } from '../../../forms/renderer/form-data-source-field.js';
6
+ import { FileUploadFieldState, FormRendererAttachment } from '../../../forms/renderer/file-upload-field.js';
6
7
  /** The fill state of the viewer's own task at a node that fills in fields. */
7
8
  export interface InstanceFormSectionFill {
8
9
  /** Field errors from the page's check or the server's, keyed by path. */
@@ -59,7 +60,23 @@ export interface InstanceFormSectionProps {
59
60
  readonly resubmitComment?: string;
60
61
  /** Called when the applicant edits the resubmission comment. */
61
62
  readonly onResubmitCommentChange?: ((value: string) => void) | null;
62
- /** Called when an attachment upload is requested via the form field. */
63
+ /**
64
+ * The instance's attachments, so a `file_upload` field lists the files its
65
+ * value holds by name.
66
+ */
67
+ readonly attachments?: readonly FormRendererAttachment[];
68
+ /** Opens an attachment a `file_upload` field lists. */
69
+ readonly onDownloadAttachment?: (attachmentId: string) => void;
70
+ /**
71
+ * Called when a `file_upload` field starts or settles an upload, so the
72
+ * container can refuse to resubmit while one is unsettled.
73
+ */
74
+ readonly onFileUploadStateChange?: (fieldKey: string, state: FileUploadFieldState) => void;
75
+ /**
76
+ * Uploads a file picked in a `file_upload` field while resubmitting. A fill
77
+ * node never edits one: an approver cannot fill in a `file_upload` field
78
+ * (ADR 20, refused at publish).
79
+ */
63
80
  readonly onUploadAttachment: (field: FormFieldDefinition, file: File) => Promise<{
64
81
  readonly id: string;
65
82
  }>;
@@ -69,4 +86,4 @@ export interface InstanceFormSectionProps {
69
86
  * Displays the form in read-only mode normally, or editable mode when the
70
87
  * instance has been returned and the current member can resubmit it.
71
88
  */
72
- export declare function InstanceFormSection({ canResubmitInstance, deciding, error, fieldAccess, fieldLabelMarkers, fill, instance, loading, onDataSourceStateChange, onResubmitFormChange, onReloadAfterConflict, onResubmitCommentChange, onResubmitInstance, onUploadAttachment, resubmitComment, resubmitFormData, resubmitFormErrors, }: InstanceFormSectionProps): ReactElement;
89
+ export declare function InstanceFormSection({ attachments, canResubmitInstance, deciding, error, fieldAccess, fieldLabelMarkers, fill, instance, loading, onDataSourceStateChange, onDownloadAttachment, onFileUploadStateChange, onResubmitFormChange, onReloadAfterConflict, onResubmitCommentChange, onResubmitInstance, onUploadAttachment, resubmitComment, resubmitFormData, resubmitFormErrors, }: InstanceFormSectionProps): ReactElement;
@@ -72,7 +72,7 @@ export declare function readNumberField(record: Readonly<Record<string, unknown>
72
72
  export declare function isPresentText(value: string | null): value is string;
73
73
  export declare function isRecord(value: unknown): value is Readonly<Record<string, unknown>>;
74
74
  export declare function isPendingTask(task: TaskRecord): boolean;
75
- export declare function readErrorMessage(error: unknown): string;
75
+ export { readErrorMessage } from '../../instance-error-message.cjs';
76
76
  export declare function formatFileSize(sizeBytes: number): string;
77
77
  export declare function readShortHash(hash: string): string;
78
78
  export declare function readInstanceStateLabel(state: string): string;
@@ -147,4 +147,3 @@ export declare function readNodeRuntimeState(node: WorkflowNode, tasks: readonly
147
147
  statusLabel: string;
148
148
  tone: RuntimeTone;
149
149
  }>;
150
- export {};
@@ -72,7 +72,7 @@ export declare function readNumberField(record: Readonly<Record<string, unknown>
72
72
  export declare function isPresentText(value: string | null): value is string;
73
73
  export declare function isRecord(value: unknown): value is Readonly<Record<string, unknown>>;
74
74
  export declare function isPendingTask(task: TaskRecord): boolean;
75
- export declare function readErrorMessage(error: unknown): string;
75
+ export { readErrorMessage } from '../../instance-error-message.js';
76
76
  export declare function formatFileSize(sizeBytes: number): string;
77
77
  export declare function readShortHash(hash: string): string;
78
78
  export declare function readInstanceStateLabel(state: string): string;
@@ -147,4 +147,3 @@ export declare function readNodeRuntimeState(node: WorkflowNode, tasks: readonly
147
147
  statusLabel: string;
148
148
  tone: RuntimeTone;
149
149
  }>;
150
- export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The message a case page shows for a failed request: a stable server code
3
+ * translated into words, otherwise the server's own message.
4
+ */
5
+ export declare function readErrorMessage(error: unknown): string;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * The message a case page shows for a failed request: a stable server code
3
+ * translated into words, otherwise the server's own message.
4
+ */
5
+ export declare function readErrorMessage(error: unknown): string;
@@ -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/approver-filled-form-B4zPg9kz.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-ChmM_4Yc.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(),y=_?.memberId??null,b=e??null,[x,S]=(0,s.useState)(null),[C,w]=(0,s.useState)({}),[T,E]=(0,s.useState)([]),[D,O]=(0,s.useState)(null),[k,A]=(0,s.useState)({}),[j,M]=(0,s.useState)(!0),[N,P]=(0,s.useState)(!1),[F,I]=(0,s.useState)({}),L=(0,s.useMemo)(()=>x?t.n(x.formVersion.schema,x.templateVersion.workflowDefinition):null,[x]),R=(0,s.useCallback)((e,t)=>{I(n=>{let r=n[e];return r?.hasValue===t.hasValue&&r.status===t.status?n:{...n,[e]:{hasValue:t.hasValue,status:t.status}}})},[]);(0,s.useEffect)(()=>{b?U(b):H()},[b]);let z=(0,s.useMemo)(()=>T.map(e=>({...e,key:e.id,updatedAt:n.t(e.updatedAt),versionLabel:`v${e.version}`})),[T]),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(){M(!0),O(null),S(null),I({});try{E(await(0,u.listLaunchableTemplates)())}catch(e){O(v(e))}finally{M(!1)}}async function U(e){M(!0),O(null),E([]),I({});try{S(await(0,u.readLaunchContext)(e))}catch(e){O(v(e))}finally{M(!1)}}async function W(){if(!x||!L||!y)return;P(!0),O(null),A({});let e=o.s(Object.values(F));if(e){O(e),P(!1);return}let n=t.r((0,p.buildFormRendererValues)(L.fields,C),x.templateVersion.workflowDefinition);try{let e=await(0,p.validateFormRendererValuesInWorker)({schema:L,uiSchema:x.formVersion.uiSchema,values:n});if(!e.valid){A(e.errors),O(`請先修正表單中標示的欄位。`),e.firstInvalidFieldKey&&(0,p.focusFormRendererField)(e.firstInvalidFieldKey);return}let t=await(0,u.submitApprovalInstance)({formData:n,initiatorMemberId:y,templateId:x.template.id,title:(0,u.readFormDataCaseTitle)({fallbackTitle:x.template.name,formData:n,schema:L,uiSchema:x.formVersion.uiSchema})});h.push(g.caseDetail(t))}catch(e){O(v(e))}finally{P(!1)}}async function G(e,t){if(!y)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:x?`${x.template.name} · 表單 v${x.formVersion.version}`:`選擇可發起的已發布模板後填寫表單內容。`,title:`發起簽核`,children:x?(0,l.jsx)(c.Button,{disabled:j||N,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:[D?(0,l.jsx)(c.Typography,{color:`text-error`,variant:`body`,children:D}):null,j?(0,l.jsx)(c.Typography,{color:`text-neutral`,variant:`body`,children:`載入中...`}):null,x&&L?(0,l.jsx)(o.t,{dataSourceContext:{kind:`runtime`,templateId:x.template.id},errors:k,maxWidth:480,onChange:e=>{w(e),A({})},onDataSourceStateChange:R,onUploadAttachment:G,schema:L,singleColumn:!0,uiSchema:x.formVersion.uiSchema,value:C}):null,!b&&!j?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:`載入中...`})})})]})}function v(e){return(0,p.readFormDataSourceErrorMessage)(e)||(e instanceof Error?e.message:`發生未知錯誤`)}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-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-DwfFbaip.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.status===t.status?n:{...n,[e]:{hasValue:t.hasValue,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;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Suspense","useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","readApplicantFormSchema","useCallback","formatDateTime","listLaunchableTemplates","readLaunchContext","readFormDataSourceSubmissionBlockMessage","readApplicantSubmission","buildFormRendererValues","validateFormRendererValuesInWorker","submitApprovalInstance","readFormDataCaseTitle","uploadAttachment","_Fragment","PageHeader","ContentHeader","Button","CheckedIcon","SectionGroup","Section","Typography","FormRenderer","Table","readFormDataSourceErrorMessage","require_rolldown_runtime","require_approver_filled_form","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","applicantSchema","handleDataSourceStateChange","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","requestError","readErrorMessage","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 readFormDataSourceErrorMessage,\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';\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<string, Pick<FormDataSourceFieldState, 'hasValue' | 'status'>>\n >\n >({});\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' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\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 // 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 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\nfunction readErrorMessage(error: unknown): string {\n // DataSource failures arrive as stable codes so the backend never leaks\n // upstream transport detail; translate them instead of showing the raw code.\n const dataSourceMessage = readFormDataSourceErrorMessage(error);\n\n if (dataSourceMessage) {\n return dataSourceMessage;\n }\n\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"A,6vBAqDA,IAAM2C,EAAoC,CACxC,QAAS,OACT,IAAK,EACP,EAwBA,SAAgBC,EACd,EAA8B,CAAC,EACjB,CACd,OACE,EAAAN,EAAA,IAAA,CAACtC,EAAAA,SAAD,CAAU,UAAU,EAAAsC,EAAA,IAAA,CAACO,EAAD,CAA6B,CAAA,EAC/C,UAAA,EAAAP,EAAA,IAAA,CAACQ,EAAD,CAA4B,WAAYC,EAAM,YAAc,IAAA,EAAY,CAAA,CAChE,CAAA,CAEd,CAEA,SAASD,EAA2B,CAClC,WAAYE,GAGG,CACf,IAAMC,EAAShD,EAAAA,EAAiB,EAC1BiD,EAAShD,EAAAA,EAAa,EACtB,CAAE,UAAWC,EAAAA,EAAQ,EACrBgD,EAAkBC,GAAQ,UAAY,KACtCC,EAAaL,GAAkB,KAC/B,CAACM,EAASC,IAAA,EAAcnD,EAAAA,SAAAA,CAA+B,IAAI,EAC3D,CAACoD,EAAYC,IAAA,EAAiBrD,EAAAA,SAAAA,CAA6B,CAAC,CAAC,EAC7D,CAACsD,EAAWC,IAAA,EAAgBvD,EAAAA,SAAAA,CAEhC,CAAC,CAAC,EACE,CAACwD,EAAOC,IAAA,EAAYzD,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAAC0D,EAAYC,IAAA,EAAiB3D,EAAAA,SAAAA,CAElC,CAAC,CAAC,EACE,CAAC4D,EAASC,IAAA,EAAc7D,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAAC8D,EAAYC,IAAA,EAAiB/D,EAAAA,SAAAA,CAAS,EAAK,EAC5C,CAACgE,EAAkBC,IAAA,EAAuBjE,EAAAA,SAAAA,CAI9C,CAAC,CAAC,EAIEkE,GAAA,EAAkBjE,EAAAA,QAAAA,KAEpBiD,EACIhD,EAAAA,EACEgD,EAAQ,YAAY,OACpBA,EAAQ,gBAAgB,kBAC1B,EACA,KACN,CAACA,CAAO,CACV,EAEMiB,GAAA,EAA8BhE,EAAAA,YAAAA,EAEhC,EACA,IAIS,CACT8D,EAAqB,GAAkB,CACrC,IAAMG,EAAeC,EAAcC,GASnC,OANEF,GAAc,WAAaG,EAAM,UACjCH,EAAa,SAAWG,EAAM,OAEvBF,EAGF,CACL,GAAGA,GACFC,GAAW,CACV,SAAUC,EAAM,SAChB,OAAQA,EAAM,MAChB,CACF,CACF,CAAC,CACH,EACA,CAAC,CACH,GAEA,EAAAvC,EAAA,UAAA,KAAsB,CACfiB,EAMLuB,EAAoBvB,CAAU,EAL5BwB,EAAsB,CAM1B,EAAG,CAACxB,CAAU,CAAC,EAEf,IAAMyB,GAAA,EAAOzE,EAAAA,QAAAA,KAETqD,EAAU,IAAK,IAAc,CAC3B,GAAGqB,EACH,IAAKA,EAAS,GACd,UAAWvE,EAAAA,EAAeuE,EAAS,SAAS,EAC5C,aAAc,IAAIA,EAAS,SAC7B,EAAE,EACJ,CAACrB,CAAS,CACZ,EACMsB,GAAA,EAAU3E,EAAAA,QAAAA,KAC8B,CAC1C,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,OAAQ,MAAO,GAAI,EAC5D,CACE,UAAW,eACX,IAAK,eACL,MAAO,OACP,MAAO,GACT,EACA,CACE,UAAW,YACX,IAAK,YACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACM4E,GAAA,EAAe5E,EAAAA,QAAAA,MACyB,CAC1C,OACE,GAC8D,CAC9D,CACE,KAAM,KACN,YACE4C,EAAO,KAAKC,EAAO,QAAQgC,EAAO,EAAE,CAAC,EACvC,QAAS,cACX,CACF,EACA,QAAS,iBACT,MAAO,EACT,GACA,CAACjC,CAAM,CACT,EAEA,eAAe4B,GAAkC,CAC/CZ,EAAW,EAAI,EACfJ,EAAS,IAAI,EACbN,EAAW,IAAI,EACfc,EAAoB,CAAC,CAAC,EAEtB,GAAI,CACFV,EAAa,MAAA,EAAMlD,EAAAA,wBAAAA,CAAwB,CAAC,CAC9C,OAAS0E,EAAuB,CAC9BtB,EAASuB,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRlB,EAAW,EAAK,CAClB,CACF,CAEA,eAAeW,EAAe,EAAuC,CACnEX,EAAW,EAAI,EACfJ,EAAS,IAAI,EACbF,EAAa,CAAC,CAAC,EACfU,EAAoB,CAAC,CAAC,EAEtB,GAAI,CACFd,EAAW,MAAA,EAAM7C,EAAAA,kBAAAA,CAAkB2E,CAAc,CAAC,CACpD,OAASF,EAAuB,CAC9BtB,EAASuB,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRlB,EAAW,EAAK,CAClB,CACF,CAEA,eAAeqB,GAA8B,CAC3C,GAAI,CAAChC,GAAW,CAACgB,GAAmB,CAACnB,EACnC,OAGFgB,EAAc,EAAI,EAClBN,EAAS,IAAI,EACbE,EAAc,CAAC,CAAC,EAEhB,IAAMwB,EAAyB5E,EAAAA,EAC7B,OAAO,OAAOyD,CAAgB,CAChC,EAEA,GAAImB,EAAwB,CAC1B1B,EAAS0B,CAAsB,EAC/BpB,EAAc,EAAK,EAEnB,MACF,CAOA,IAAMqB,EAAkB5E,EAAAA,GAAAA,EACtBC,EAAAA,wBAAAA,CAAwByD,EAAgB,OAAQd,CAAU,EAC1DF,EAAQ,gBAAgB,kBAC1B,EAGA,GAAI,CAGF,IAAMmC,EAAa,MAAA,EAAM3E,EAAAA,mCAAAA,CAAmC,CAC1D,OAAQwD,EACR,SAAUhB,EAAQ,YAAY,SAC9B,OAAQkC,CACV,CAAC,EAED,GAAI,CAACC,EAAW,MAAO,CACrB1B,EAAc0B,EAAW,MAAM,EAC/B5B,EAAS,eAAe,EAEpB4B,EAAW,uBACb,EAAA/C,EAAA,uBAAA,CAAuB+C,EAAW,oBAAoB,EAGxD,MACF,CAEA,IAAMC,EAAa,MAAA,EAAM3E,EAAAA,uBAAAA,CAAuB,CAC9C,SAAUyE,EACV,kBAAmBrC,EACnB,WAAYG,EAAQ,SAAS,GAC7B,OAAA,EAAOtC,EAAAA,sBAAAA,CAAsB,CAC3B,cAAesC,EAAQ,SAAS,KAChC,SAAUkC,EACV,OAAQlB,EACR,SAAUhB,EAAQ,YAAY,QAChC,CAAC,CACH,CAAC,EAEDL,EAAO,KAAKC,EAAO,WAAWwC,CAAU,CAAC,CAC3C,OAASP,EAAuB,CAC9BtB,EAASuB,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRhB,EAAc,EAAK,CACrB,CACF,CAEA,eAAewB,EACb,EACA,EACkC,CAClC,GAAI,CAACxC,EACH,MAAU,MAAM,aAAa,EAQ/B,MAAO,CAAE,IAAI,MAAA,EALYlC,EAAAA,iBAAAA,CAAiB,CACxC,OACA,cAAe,QAAQ2E,EAAM,UAC/B,CAAC,EAAA,CAEuB,EAAG,CAC7B,CAEA,OACE,EAAAtD,EAAA,KAAA,CAAApB,EAAAA,SAAA,CAAA,SAAA,EACI,EAAAoB,EAAA,IAAA,CAACnB,EAAAA,WAAD,CAAA,UACE,EAAAmB,EAAA,IAAA,CAAClB,EAAAA,QAAD,CACE,YACEkC,EACI,GAAGA,EAAQ,SAAS,KAAK,SAASA,EAAQ,YAAY,UACtD,sBAEN,MAAM,OAEL,SAAAA,GACC,EAAAhB,EAAA,IAAA,CAACjB,EAAAA,OAAD,CACE,SAAU2C,GAAWE,EACrB,KAAM5C,EAAAA,YACN,SAAS,UACT,QAASgE,EACT,QAAQ,eACT,SAAA,IAEO,CAAA,EACN,IACS,CAAA,CACL,CAAA,GAEZ,EAAAhD,EAAA,IAAA,CAACf,EAAAA,aAAD,CAAA,UACE,EAAAe,EAAA,IAAA,CAACd,EAAAA,QAAD,CAAA,UACE,EAAAc,EAAA,KAAA,CAAC,MAAD,CAAK,MAAOK,EAAZ,SAAA,CACGiB,GACC,EAAAtB,EAAA,IAAA,CAACb,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAAmC,CACS,CAAA,EACV,KAEHI,GACC,EAAA1B,EAAA,IAAA,CAACb,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OAAO,SAAA,QAEpC,CAAA,EACV,KAEH6B,GAAWgB,GACV,EAAAhC,EAAA,IAAA,CAACZ,EAAAA,EAAD,CACE,kBAAmB,CACjB,KAAM,UACN,WAAY4B,EAAQ,SAAS,EAC/B,EACA,OAAQQ,EACR,SAAU,IACV,SAAW,GAAiB,CAC1BL,EAAcoC,CAAM,EACpB9B,EAAc,CAAC,CAAC,CAClB,EACA,wBAAyBQ,EACzB,mBAAoBoB,EACpB,OAAQrB,EACR,aAAA,GACA,SAAUhB,EAAQ,YAAY,SAC9B,MAAOE,CACR,CAAA,EACC,KAEH,CAACH,GAAc,CAACW,EACfc,EAAK,OAAS,GACZ,EAAAxC,EAAA,IAAA,CAACX,EAAAA,MAAD,CACE,QAASsD,EACA,UACT,WAAYH,EACZ,UAAA,EACD,CAAA,GAED,EAAAxC,EAAA,IAAA,CAACb,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OAAO,SAAA,gBAEpC,CAAA,EAEZ,IACD,CACE,CAAA,CAAA,CAAA,CACG,CAAA,CACd,CAAA,CAAA,CAER,CAEA,SAASoB,GAA2C,CAClD,OACE,EAAAP,EAAA,KAAA,CAAApB,EAAAA,SAAA,CAAA,SAAA,EACI,EAAAoB,EAAA,IAAA,CAACnB,EAAAA,WAAD,CAAA,UACE,EAAAmB,EAAA,IAAA,CAAClB,EAAAA,QAAD,CACE,YAAY,sBACZ,MAAM,MACP,CAAA,CACS,CAAA,GAEZ,EAAAkB,EAAA,IAAA,CAACf,EAAAA,aAAD,CAAA,UACE,EAAAe,EAAA,IAAA,CAACd,EAAAA,QAAD,CAAA,UACE,EAAAc,EAAA,IAAA,CAACb,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OAAO,SAAA,QAEpC,CAAA,CACL,CAAA,CACG,CAAA,CACd,CAAA,CAAA,CAER,CAEA,SAAS2D,EAAiB,EAAwB,CAShD,OANM,EAAoBxD,EAAAA,+BAAAA,CAA+BgC,CAErD,IAIGA,aAAiB,MAAQA,EAAM,QAAU,SAClD,C"}
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<string, Pick<FormDataSourceFieldState, 'hasValue' | 'status'>>\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' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\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,31 +1,31 @@
1
1
  "use client";
2
- import { n as e, r as t } from "../../../chunks/approver-filled-form-Bgazhbvd.js";
3
- import { t as n } from "../../../chunks/format-date-time-B0LdmWg4.js";
4
- import { n as r } from "../../../chunks/auth-provider-C2b-5mGt.js";
5
- import { r as i } from "../../../chunks/router-adapter-CkxCyzf5.js";
6
- import { r as a } from "../../../chunks/routes-config-BcNaWJWJ.js";
7
- import { s as o, t as s } from "../../../chunks/FormRendererView-CTLlG13b.js";
8
- import { Suspense as c, useCallback as ee, useEffect as l, useMemo as u, useState as d } from "react";
9
- import { Button as f, PageHeader as p, Section as m, SectionGroup as h, Table as te, Typography as g } from "@mezzanine-ui/react";
10
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
11
- import { listLaunchableTemplates as b, readFormDataCaseTitle as x, readLaunchContext as S, submitApprovalInstance as C, uploadAttachment as w } from "@rytass/bpm-core-client/workflow";
12
- import T from "@mezzanine-ui/react/ContentHeader";
13
- import { CheckedIcon as E } from "@mezzanine-ui/icons";
14
- import { buildFormRendererValues as D, focusFormRendererField as O, readFormDataSourceErrorMessage as k, validateFormRendererValuesInWorker as ne } from "@rytass/bpm-core-client/form";
2
+ import { i as e, r as t, t as n } from "../../../chunks/instance-error-message-q6gy5evy.js";
3
+ import { t as r } from "../../../chunks/format-date-time-B0LdmWg4.js";
4
+ import { n as i } from "../../../chunks/auth-provider-C2b-5mGt.js";
5
+ import { r as a } from "../../../chunks/router-adapter-CkxCyzf5.js";
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-DHfVgbo6.js";
8
+ import { Suspense as u, useCallback as d, useEffect as f, useMemo as p, useState as m } from "react";
9
+ import { Button as ee, PageHeader as h, Section as g, SectionGroup as _, Table as v, Typography as y } from "@mezzanine-ui/react";
10
+ import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
11
+ import { listLaunchableTemplates as C, readFormDataCaseTitle as w, readLaunchContext as T, submitApprovalInstance as E, uploadAttachment as D } from "@rytass/bpm-core-client/workflow";
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";
15
15
  // src/views/instances/new/InstanceNewView.tsx
16
- var re = {
16
+ var ie = {
17
17
  display: "grid",
18
18
  gap: 16
19
19
  };
20
20
  function A(e = {}) {
21
- return /* @__PURE__ */ v(c, {
22
- fallback: /* @__PURE__ */ v(M, {}),
23
- children: /* @__PURE__ */ v(j, { templateId: e.templateId ?? void 0 })
21
+ return /* @__PURE__ */ x(u, {
22
+ fallback: /* @__PURE__ */ x(M, {}),
23
+ children: /* @__PURE__ */ x(j, { templateId: e.templateId ?? void 0 })
24
24
  });
25
25
  }
26
- function j({ templateId: c }) {
27
- let k = i(), A = a(), { member: j } = r(), M = j?.memberId ?? null, P = c ?? null, [F, I] = d(null), [L, R] = d({}), [z, B] = d([]), [V, H] = d(null), [U, W] = d({}), [G, K] = d(!0), [q, J] = d(!1), [Y, X] = d({}), Z = u(() => F ? e(F.formVersion.schema, F.templateVersion.workflowDefinition) : null, [F]), ie = ee((e, t) => {
28
- X((n) => {
26
+ function j({ templateId: u }) {
27
+ let A = a(), j = o(), { member: M } = i(), N = M?.memberId ?? null, P = u ?? null, [F, I] = m(null), [L, R] = m({}), [z, B] = m([]), [V, H] = m(null), [U, W] = m({}), [G, K] = m(!0), [q, J] = m(!1), [ae, Y] = m({}), X = c(), Z = p(() => F ? t(F.formVersion.schema, F.templateVersion.workflowDefinition) : null, [F]), oe = d((e, t) => {
28
+ Y((n) => {
29
29
  let r = n[e];
30
30
  return r?.hasValue === t.hasValue && r.status === t.status ? n : {
31
31
  ...n,
@@ -36,15 +36,15 @@ function j({ templateId: c }) {
36
36
  };
37
37
  });
38
38
  }, []);
39
- l(() => {
40
- P ? se(P) : $();
39
+ f(() => {
40
+ P ? $(P) : le();
41
41
  }, [P]);
42
- let Q = u(() => z.map((e) => ({
42
+ let Q = p(() => z.map((e) => ({
43
43
  ...e,
44
44
  key: e.id,
45
- updatedAt: n(e.updatedAt),
45
+ updatedAt: r(e.updatedAt),
46
46
  versionLabel: `v${e.version}`
47
- })), [z]), ae = u(() => [
47
+ })), [z]), se = p(() => [
48
48
  {
49
49
  dataIndex: "name",
50
50
  key: "name",
@@ -63,104 +63,108 @@ function j({ templateId: c }) {
63
63
  title: "更新時間",
64
64
  width: 220
65
65
  }
66
- ], []), oe = u(() => ({
66
+ ], []), ce = p(() => ({
67
67
  render: (e) => [{
68
68
  name: "發起",
69
- onClick: () => k.push(A.caseNew(e.id)),
69
+ onClick: () => A.push(j.caseNew(e.id)),
70
70
  variant: "base-primary"
71
71
  }],
72
72
  variant: "base-secondary",
73
73
  width: 88
74
- }), [k]);
75
- async function $() {
76
- K(!0), H(null), I(null), X({});
74
+ }), [A]);
75
+ async function le() {
76
+ K(!0), H(null), I(null), Y({});
77
77
  try {
78
- B(await b());
78
+ B(await C());
79
79
  } catch (e) {
80
- H(N(e));
80
+ H(n(e));
81
81
  } finally {
82
82
  K(!1);
83
83
  }
84
84
  }
85
- async function se(e) {
86
- K(!0), H(null), B([]), X({});
85
+ async function $(e) {
86
+ K(!0), H(null), B([]), Y({});
87
87
  try {
88
- I(await S(e));
88
+ I(await T(e));
89
89
  } catch (e) {
90
- H(N(e));
90
+ H(n(e));
91
91
  } finally {
92
92
  K(!1);
93
93
  }
94
94
  }
95
- async function ce() {
96
- if (!F || !Z || !M) return;
95
+ async function ue() {
96
+ if (!F || !Z || !N) return;
97
97
  J(!0), H(null), W({});
98
- let e = o(Object.values(Y));
99
- if (e) {
100
- H(e), J(!1);
98
+ let t = s(Object.values(ae));
99
+ if (t) {
100
+ H(t), J(!1);
101
101
  return;
102
102
  }
103
- let n = t(D(Z.fields, L), F.templateVersion.workflowDefinition);
103
+ if (X.blockMessage) {
104
+ H(X.blockMessage), J(!1);
105
+ return;
106
+ }
107
+ let r = e(te(Z.fields, L), F.templateVersion.workflowDefinition);
104
108
  try {
105
- let e = await ne({
109
+ let e = await re({
106
110
  schema: Z,
107
111
  uiSchema: F.formVersion.uiSchema,
108
- values: n
112
+ values: r
109
113
  });
110
114
  if (!e.valid) {
111
- W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && O(e.firstInvalidFieldKey);
115
+ W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && ne(e.firstInvalidFieldKey);
112
116
  return;
113
117
  }
114
- let t = await C({
115
- formData: n,
116
- initiatorMemberId: M,
118
+ let t = await E({
119
+ formData: r,
120
+ initiatorMemberId: N,
117
121
  templateId: F.template.id,
118
- title: x({
122
+ title: w({
119
123
  fallbackTitle: F.template.name,
120
- formData: n,
124
+ formData: r,
121
125
  schema: Z,
122
126
  uiSchema: F.formVersion.uiSchema
123
127
  })
124
128
  });
125
- k.push(A.caseDetail(t));
129
+ A.push(j.caseDetail(t));
126
130
  } catch (e) {
127
- H(N(e));
131
+ H(n(e));
128
132
  } finally {
129
133
  J(!1);
130
134
  }
131
135
  }
132
- async function le(e, t) {
133
- if (!M) throw Error("尚未登入,無法上傳附件");
134
- return { id: (await w({
136
+ async function de(e, t) {
137
+ if (!N) throw Error("尚未登入,無法上傳附件");
138
+ return { id: (await D({
135
139
  file: t,
136
140
  formFieldPath: `form.${e.fieldKey}`
137
141
  })).id };
138
142
  }
139
- return /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v(p, { children: /* @__PURE__ */ v(T, {
143
+ return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(O, {
140
144
  description: F ? `${F.template.name} · 表單 v${F.formVersion.version}` : "選擇可發起的已發布模板後填寫表單內容。",
141
145
  title: "發起簽核",
142
- children: F ? /* @__PURE__ */ v(f, {
146
+ children: F ? /* @__PURE__ */ x(ee, {
143
147
  disabled: G || q,
144
- icon: E,
148
+ icon: k,
145
149
  iconType: "leading",
146
- onClick: ce,
150
+ onClick: ue,
147
151
  variant: "base-primary",
148
152
  children: "送出"
149
153
  }) : null
150
- }) }), /* @__PURE__ */ v(h, { children: /* @__PURE__ */ v(m, { children: /* @__PURE__ */ y("div", {
151
- style: re,
154
+ }) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ x(g, { children: /* @__PURE__ */ S("div", {
155
+ style: ie,
152
156
  children: [
153
- V ? /* @__PURE__ */ v(g, {
157
+ V ? /* @__PURE__ */ x(y, {
154
158
  color: "text-error",
155
159
  variant: "body",
156
160
  children: V
157
161
  }) : null,
158
- G ? /* @__PURE__ */ v(g, {
162
+ G ? /* @__PURE__ */ x(y, {
159
163
  color: "text-neutral",
160
164
  variant: "body",
161
165
  children: "載入中..."
162
166
  }) : null,
163
- F && Z ? /* @__PURE__ */ v(s, {
167
+ F && Z ? /* @__PURE__ */ x(l, {
164
168
  dataSourceContext: {
165
169
  kind: "runtime",
166
170
  templateId: F.template.id
@@ -170,19 +174,20 @@ function j({ templateId: c }) {
170
174
  onChange: (e) => {
171
175
  R(e), W({});
172
176
  },
173
- onDataSourceStateChange: ie,
174
- onUploadAttachment: le,
177
+ onDataSourceStateChange: oe,
178
+ onFileUploadStateChange: X.onFileUploadStateChange,
179
+ onUploadAttachment: de,
175
180
  schema: Z,
176
181
  singleColumn: !0,
177
182
  uiSchema: F.formVersion.uiSchema,
178
183
  value: L
179
184
  }) : null,
180
- !P && !G ? Q.length > 0 ? /* @__PURE__ */ v(te, {
181
- actions: oe,
182
- columns: ae,
185
+ !P && !G ? Q.length > 0 ? /* @__PURE__ */ x(v, {
186
+ actions: ce,
187
+ columns: se,
183
188
  dataSource: Q,
184
189
  fullWidth: !0
185
- }) : /* @__PURE__ */ v(g, {
190
+ }) : /* @__PURE__ */ x(y, {
186
191
  color: "text-neutral",
187
192
  variant: "body",
188
193
  children: "目前沒有可發起的已發布模板。"
@@ -191,18 +196,15 @@ function j({ templateId: c }) {
191
196
  }) }) })] });
192
197
  }
193
198
  function M() {
194
- return /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v(p, { children: /* @__PURE__ */ v(T, {
199
+ return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(O, {
195
200
  description: "選擇可發起的已發布模板後填寫表單內容。",
196
201
  title: "發起簽核"
197
- }) }), /* @__PURE__ */ v(h, { children: /* @__PURE__ */ v(m, { children: /* @__PURE__ */ v(g, {
202
+ }) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ x(g, { children: /* @__PURE__ */ x(y, {
198
203
  color: "text-neutral",
199
204
  variant: "body",
200
205
  children: "載入中..."
201
206
  }) }) })] });
202
207
  }
203
- function N(e) {
204
- return k(e) || (e instanceof Error ? e.message : "發生未知錯誤");
205
- }
206
208
  export { A as InstanceNewView };
207
209
 
208
210
  //# sourceMappingURL=index.js.map