@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.
- package/CHANGELOG.md +20 -0
- package/dist/chunks/{FormBuilderView-vQfVc08Z.js → FormBuilderView-Djlm3y4S.js} +2 -2
- package/dist/chunks/{FormBuilderView-vQfVc08Z.js.map → FormBuilderView-Djlm3y4S.js.map} +1 -1
- package/dist/chunks/{FormBuilderView-CHaAQL5v.cjs → FormBuilderView-G6uRSywl.cjs} +2 -2
- package/dist/chunks/{FormBuilderView-CHaAQL5v.cjs.map → FormBuilderView-G6uRSywl.cjs.map} +1 -1
- package/dist/chunks/{FormRendererView-CTLlG13b.js → FormRendererView-DHfVgbo6.js} +391 -265
- package/dist/chunks/FormRendererView-DHfVgbo6.js.map +1 -0
- package/dist/chunks/FormRendererView-DwfFbaip.cjs +6 -0
- package/dist/chunks/FormRendererView-DwfFbaip.cjs.map +1 -0
- package/dist/chunks/{compose-D9ipJpF_.js → compose-D6zBIc2Z.js} +4 -4
- package/dist/chunks/{compose-D9ipJpF_.js.map → compose-D6zBIc2Z.js.map} +1 -1
- package/dist/chunks/{compose-DtfX8DQ9.cjs → compose-NH6dsFXD.cjs} +2 -2
- package/dist/chunks/{compose-DtfX8DQ9.cjs.map → compose-NH6dsFXD.cjs.map} +1 -1
- package/dist/chunks/{designer-Df79YzUn.cjs → designer-Be9UI9Tg.cjs} +2 -2
- package/dist/chunks/{designer-Df79YzUn.cjs.map → designer-Be9UI9Tg.cjs.map} +1 -1
- package/dist/chunks/{designer-ubnZbP-A.js → designer-uhC_7m2i.js} +3 -3
- package/dist/chunks/{designer-ubnZbP-A.js.map → designer-uhC_7m2i.js.map} +1 -1
- package/dist/chunks/detail-6uw5dmTi.cjs +5 -0
- package/dist/chunks/detail-6uw5dmTi.cjs.map +1 -0
- package/dist/chunks/{detail-C6XKZjlF.js → detail-_GeKqNC-.js} +851 -839
- package/dist/chunks/detail-_GeKqNC-.js.map +1 -0
- package/dist/chunks/{approver-filled-form-B4zPg9kz.cjs → instance-error-message-DTARGbGo.cjs} +2 -2
- package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +1 -0
- package/dist/chunks/{approver-filled-form-Bgazhbvd.js → instance-error-message-q6gy5evy.js} +44 -36
- package/dist/chunks/instance-error-message-q6gy5evy.js.map +1 -0
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/FormRendererView.d.cts +24 -1
- package/dist/views/forms/renderer/FormRendererView.d.ts +24 -1
- package/dist/views/forms/renderer/file-upload-field.d.cts +84 -0
- package/dist/views/forms/renderer/file-upload-field.d.ts +84 -0
- package/dist/views/forms/renderer/form-value-readers.d.cts +7 -0
- package/dist/views/forms/renderer/form-value-readers.d.ts +7 -0
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.d.cts +1 -0
- package/dist/views/forms/renderer/index.d.ts +1 -0
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +19 -2
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +19 -2
- package/dist/views/instances/detail/sections/shared.d.cts +1 -2
- package/dist/views/instances/detail/sections/shared.d.ts +1 -2
- package/dist/views/instances/instance-error-message.d.cts +5 -0
- package/dist/views/instances/instance-error-message.d.ts +5 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +77 -75
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunks/FormRendererView-CTLlG13b.js.map +0 -1
- package/dist/chunks/FormRendererView-ChmM_4Yc.cjs +0 -4
- package/dist/chunks/FormRendererView-ChmM_4Yc.cjs.map +0 -1
- package/dist/chunks/approver-filled-form-B4zPg9kz.cjs.map +0 -1
- package/dist/chunks/approver-filled-form-Bgazhbvd.js.map +0 -1
- package/dist/chunks/detail-BBC9kqXd.cjs +0 -5
- package/dist/chunks/detail-BBC9kqXd.cjs.map +0 -1
- 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-
|
|
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 +1 @@
|
|
|
1
|
-
export { t as FormRenderer, t as FormRendererView,
|
|
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-
|
|
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-
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
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
|
|
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 {};
|
|
@@ -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/
|
|
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":"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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","_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 {
|
|
3
|
-
import { t as
|
|
4
|
-
import { n as
|
|
5
|
-
import { r as
|
|
6
|
-
import { r as
|
|
7
|
-
import { s as
|
|
8
|
-
import { Suspense as
|
|
9
|
-
import { Button as
|
|
10
|
-
import { Fragment as
|
|
11
|
-
import { listLaunchableTemplates as
|
|
12
|
-
import
|
|
13
|
-
import { CheckedIcon as
|
|
14
|
-
import { buildFormRendererValues as
|
|
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
|
|
16
|
+
var ie = {
|
|
17
17
|
display: "grid",
|
|
18
18
|
gap: 16
|
|
19
19
|
};
|
|
20
20
|
function A(e = {}) {
|
|
21
|
-
return /* @__PURE__ */
|
|
22
|
-
fallback: /* @__PURE__ */
|
|
23
|
-
children: /* @__PURE__ */
|
|
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:
|
|
27
|
-
let
|
|
28
|
-
|
|
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
|
-
|
|
40
|
-
P ?
|
|
39
|
+
f(() => {
|
|
40
|
+
P ? $(P) : le();
|
|
41
41
|
}, [P]);
|
|
42
|
-
let Q =
|
|
42
|
+
let Q = p(() => z.map((e) => ({
|
|
43
43
|
...e,
|
|
44
44
|
key: e.id,
|
|
45
|
-
updatedAt:
|
|
45
|
+
updatedAt: r(e.updatedAt),
|
|
46
46
|
versionLabel: `v${e.version}`
|
|
47
|
-
})), [z]),
|
|
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
|
-
], []),
|
|
66
|
+
], []), ce = p(() => ({
|
|
67
67
|
render: (e) => [{
|
|
68
68
|
name: "發起",
|
|
69
|
-
onClick: () =>
|
|
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
|
-
}), [
|
|
75
|
-
async function
|
|
76
|
-
K(!0), H(null), I(null),
|
|
74
|
+
}), [A]);
|
|
75
|
+
async function le() {
|
|
76
|
+
K(!0), H(null), I(null), Y({});
|
|
77
77
|
try {
|
|
78
|
-
B(await
|
|
78
|
+
B(await C());
|
|
79
79
|
} catch (e) {
|
|
80
|
-
H(
|
|
80
|
+
H(n(e));
|
|
81
81
|
} finally {
|
|
82
82
|
K(!1);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
async function
|
|
86
|
-
K(!0), H(null), B([]),
|
|
85
|
+
async function $(e) {
|
|
86
|
+
K(!0), H(null), B([]), Y({});
|
|
87
87
|
try {
|
|
88
|
-
I(await
|
|
88
|
+
I(await T(e));
|
|
89
89
|
} catch (e) {
|
|
90
|
-
H(
|
|
90
|
+
H(n(e));
|
|
91
91
|
} finally {
|
|
92
92
|
K(!1);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
async function
|
|
96
|
-
if (!F || !Z || !
|
|
95
|
+
async function ue() {
|
|
96
|
+
if (!F || !Z || !N) return;
|
|
97
97
|
J(!0), H(null), W({});
|
|
98
|
-
let
|
|
99
|
-
if (
|
|
100
|
-
H(
|
|
98
|
+
let t = s(Object.values(ae));
|
|
99
|
+
if (t) {
|
|
100
|
+
H(t), J(!1);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
|
-
|
|
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
|
|
109
|
+
let e = await re({
|
|
106
110
|
schema: Z,
|
|
107
111
|
uiSchema: F.formVersion.uiSchema,
|
|
108
|
-
values:
|
|
112
|
+
values: r
|
|
109
113
|
});
|
|
110
114
|
if (!e.valid) {
|
|
111
|
-
W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey &&
|
|
115
|
+
W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && ne(e.firstInvalidFieldKey);
|
|
112
116
|
return;
|
|
113
117
|
}
|
|
114
|
-
let t = await
|
|
115
|
-
formData:
|
|
116
|
-
initiatorMemberId:
|
|
118
|
+
let t = await E({
|
|
119
|
+
formData: r,
|
|
120
|
+
initiatorMemberId: N,
|
|
117
121
|
templateId: F.template.id,
|
|
118
|
-
title:
|
|
122
|
+
title: w({
|
|
119
123
|
fallbackTitle: F.template.name,
|
|
120
|
-
formData:
|
|
124
|
+
formData: r,
|
|
121
125
|
schema: Z,
|
|
122
126
|
uiSchema: F.formVersion.uiSchema
|
|
123
127
|
})
|
|
124
128
|
});
|
|
125
|
-
|
|
129
|
+
A.push(j.caseDetail(t));
|
|
126
130
|
} catch (e) {
|
|
127
|
-
H(
|
|
131
|
+
H(n(e));
|
|
128
132
|
} finally {
|
|
129
133
|
J(!1);
|
|
130
134
|
}
|
|
131
135
|
}
|
|
132
|
-
async function
|
|
133
|
-
if (!
|
|
134
|
-
return { id: (await
|
|
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__ */
|
|
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__ */
|
|
146
|
+
children: F ? /* @__PURE__ */ x(ee, {
|
|
143
147
|
disabled: G || q,
|
|
144
|
-
icon:
|
|
148
|
+
icon: k,
|
|
145
149
|
iconType: "leading",
|
|
146
|
-
onClick:
|
|
150
|
+
onClick: ue,
|
|
147
151
|
variant: "base-primary",
|
|
148
152
|
children: "送出"
|
|
149
153
|
}) : null
|
|
150
|
-
}) }), /* @__PURE__ */
|
|
151
|
-
style:
|
|
154
|
+
}) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ x(g, { children: /* @__PURE__ */ S("div", {
|
|
155
|
+
style: ie,
|
|
152
156
|
children: [
|
|
153
|
-
V ? /* @__PURE__ */
|
|
157
|
+
V ? /* @__PURE__ */ x(y, {
|
|
154
158
|
color: "text-error",
|
|
155
159
|
variant: "body",
|
|
156
160
|
children: V
|
|
157
161
|
}) : null,
|
|
158
|
-
G ? /* @__PURE__ */
|
|
162
|
+
G ? /* @__PURE__ */ x(y, {
|
|
159
163
|
color: "text-neutral",
|
|
160
164
|
variant: "body",
|
|
161
165
|
children: "載入中..."
|
|
162
166
|
}) : null,
|
|
163
|
-
F && Z ? /* @__PURE__ */
|
|
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:
|
|
174
|
-
|
|
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
|
|
181
|
-
actions:
|
|
182
|
-
columns:
|
|
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__ */
|
|
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__ */
|
|
199
|
+
return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(O, {
|
|
195
200
|
description: "選擇可發起的已發布模板後填寫表單內容。",
|
|
196
201
|
title: "發起簽核"
|
|
197
|
-
}) }), /* @__PURE__ */
|
|
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
|