@rytass/bpm-core-react 0.18.1 → 0.20.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 +52 -0
- package/dist/chunks/{FormBuilderView-vQfVc08Z.js → FormBuilderView-CFRiw04B.js} +563 -475
- package/dist/chunks/FormBuilderView-CFRiw04B.js.map +1 -0
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +3 -0
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +1 -0
- package/dist/chunks/FormRendererView-GfbVWEGa.js +1321 -0
- package/dist/chunks/FormRendererView-GfbVWEGa.js.map +1 -0
- package/dist/chunks/FormRendererView-lYSaR8CQ.cjs +6 -0
- package/dist/chunks/FormRendererView-lYSaR8CQ.cjs.map +1 -0
- package/dist/chunks/{compose-DtfX8DQ9.cjs → compose-Bb5bUVFd.cjs} +2 -2
- package/dist/chunks/{compose-DtfX8DQ9.cjs.map → compose-Bb5bUVFd.cjs.map} +1 -1
- package/dist/chunks/{compose-D9ipJpF_.js → compose-egQlRjuZ.js} +5 -4
- package/dist/chunks/{compose-D9ipJpF_.js.map → compose-egQlRjuZ.js.map} +1 -1
- package/dist/chunks/{delegations-BfhCDz5e.js → delegations-9-yvWWws.js} +3 -2
- package/dist/chunks/delegations-9-yvWWws.js.map +1 -0
- package/dist/chunks/delegations-CVmtpkRn.cjs +2 -0
- package/dist/chunks/delegations-CVmtpkRn.cjs.map +1 -0
- package/dist/chunks/delegations-CrfjsH94.cjs +2 -0
- package/dist/chunks/delegations-CrfjsH94.cjs.map +1 -0
- package/dist/chunks/{delegations-DBh5TT6G.js → delegations-CxnNvTCc.js} +3 -2
- package/dist/chunks/delegations-CxnNvTCc.js.map +1 -0
- package/dist/chunks/designer-CX9bhYJS.cjs +69 -0
- package/dist/chunks/designer-CX9bhYJS.cjs.map +1 -0
- package/dist/chunks/{designer-ubnZbP-A.js → designer-CZDlQ9Nf.js} +2341 -1584
- package/dist/chunks/designer-CZDlQ9Nf.js.map +1 -0
- package/dist/chunks/{detail-C6XKZjlF.js → detail-ByZV1XaI.js} +853 -840
- package/dist/chunks/detail-ByZV1XaI.js.map +1 -0
- package/dist/chunks/detail-ChseSF55.cjs +5 -0
- package/dist/chunks/detail-ChseSF55.cjs.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/chunks/workflow-chat-prompt-B4wCFKPB.js +25 -0
- package/dist/chunks/workflow-chat-prompt-B4wCFKPB.js.map +1 -0
- package/dist/chunks/workflow-chat-prompt-B803qVdt.cjs +27 -0
- package/dist/chunks/workflow-chat-prompt-B803qVdt.cjs.map +1 -0
- package/dist/next/workflow-chat-route.cjs +8 -19
- package/dist/next/workflow-chat-route.cjs.map +1 -1
- package/dist/next/workflow-chat-route.d.cts +92 -4
- package/dist/next/workflow-chat-route.d.ts +92 -4
- package/dist/next/workflow-chat-route.js +127 -19
- package/dist/next/workflow-chat-route.js.map +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- 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/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +1 -1
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/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 +25 -2
- package/dist/views/forms/renderer/FormRendererView.d.ts +25 -2
- 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-data-source-field.d.cts +9 -1
- package/dist/views/forms/renderer/form-data-source-field.d.ts +9 -1
- 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 +20 -3
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +20 -3
- 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 +79 -76
- 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/designer-version-labels.d.cts +7 -0
- package/dist/views/templates/designer/designer-version-labels.d.ts +7 -0
- package/dist/views/templates/designer/expression/DialectUpgradeModal.d.cts +25 -0
- package/dist/views/templates/designer/expression/DialectUpgradeModal.d.ts +25 -0
- package/dist/views/templates/designer/expression/ExpressionField.d.cts +79 -0
- package/dist/views/templates/designer/expression/ExpressionField.d.ts +79 -0
- package/dist/views/templates/designer/expression/use-workflow-expression-references.d.cts +22 -0
- package/dist/views/templates/designer/expression/use-workflow-expression-references.d.ts +22 -0
- package/dist/views/templates/designer/expression/workflow-expression-edits.d.cts +58 -0
- package/dist/views/templates/designer/expression/workflow-expression-edits.d.ts +58 -0
- package/dist/views/templates/designer/expression/workflow-expression-tools.d.cts +14 -0
- package/dist/views/templates/designer/expression/workflow-expression-tools.d.ts +14 -0
- package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.cts +7 -1
- package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.ts +7 -1
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/dist/views/templates/designer/notify-webhook-designer.d.cts +8 -0
- package/dist/views/templates/designer/notify-webhook-designer.d.ts +8 -0
- package/dist/views/templates/designer/use-workflow-designer-controller.d.cts +8 -2
- package/dist/views/templates/designer/use-workflow-designer-controller.d.ts +8 -2
- package/dist/views/templates/designer/workflow-chat-prompt.d.cts +18 -0
- package/dist/views/templates/designer/workflow-chat-prompt.d.ts +18 -0
- package/package.json +3 -3
- package/dist/chunks/FormBuilderView-CHaAQL5v.cjs +0 -3
- package/dist/chunks/FormBuilderView-CHaAQL5v.cjs.map +0 -1
- package/dist/chunks/FormBuilderView-vQfVc08Z.js.map +0 -1
- package/dist/chunks/FormRendererView-CTLlG13b.js +0 -1106
- 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/delegations-BfhCDz5e.js.map +0 -1
- package/dist/chunks/delegations-BmFGcuhA.cjs +0 -2
- package/dist/chunks/delegations-BmFGcuhA.cjs.map +0 -1
- package/dist/chunks/delegations-CcS0SHbf.cjs +0 -2
- package/dist/chunks/delegations-CcS0SHbf.cjs.map +0 -1
- package/dist/chunks/delegations-DBh5TT6G.js.map +0 -1
- package/dist/chunks/designer-Df79YzUn.cjs +0 -65
- package/dist/chunks/designer-Df79YzUn.cjs.map +0 -1
- package/dist/chunks/designer-ubnZbP-A.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
|
@@ -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<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
|
|
@@ -1,50 +1,51 @@
|
|
|
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-GfbVWEGa.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
|
-
return r?.hasValue === t.hasValue && r.status === t.status ? n : {
|
|
30
|
+
return r?.hasValue === t.hasValue && r.selectionExpired === (t.selectionExpired === !0) && r.status === t.status ? n : {
|
|
31
31
|
...n,
|
|
32
32
|
[e]: {
|
|
33
33
|
hasValue: t.hasValue,
|
|
34
|
+
selectionExpired: t.selectionExpired === !0,
|
|
34
35
|
status: t.status
|
|
35
36
|
}
|
|
36
37
|
};
|
|
37
38
|
});
|
|
38
39
|
}, []);
|
|
39
|
-
|
|
40
|
-
P ?
|
|
40
|
+
f(() => {
|
|
41
|
+
P ? $(P) : le();
|
|
41
42
|
}, [P]);
|
|
42
|
-
let Q =
|
|
43
|
+
let Q = p(() => z.map((e) => ({
|
|
43
44
|
...e,
|
|
44
45
|
key: e.id,
|
|
45
|
-
updatedAt:
|
|
46
|
+
updatedAt: r(e.updatedAt),
|
|
46
47
|
versionLabel: `v${e.version}`
|
|
47
|
-
})), [z]),
|
|
48
|
+
})), [z]), se = p(() => [
|
|
48
49
|
{
|
|
49
50
|
dataIndex: "name",
|
|
50
51
|
key: "name",
|
|
@@ -63,104 +64,108 @@ function j({ templateId: c }) {
|
|
|
63
64
|
title: "更新時間",
|
|
64
65
|
width: 220
|
|
65
66
|
}
|
|
66
|
-
], []),
|
|
67
|
+
], []), ce = p(() => ({
|
|
67
68
|
render: (e) => [{
|
|
68
69
|
name: "發起",
|
|
69
|
-
onClick: () =>
|
|
70
|
+
onClick: () => A.push(j.caseNew(e.id)),
|
|
70
71
|
variant: "base-primary"
|
|
71
72
|
}],
|
|
72
73
|
variant: "base-secondary",
|
|
73
74
|
width: 88
|
|
74
|
-
}), [
|
|
75
|
-
async function
|
|
76
|
-
K(!0), H(null), I(null),
|
|
75
|
+
}), [A]);
|
|
76
|
+
async function le() {
|
|
77
|
+
K(!0), H(null), I(null), Y({});
|
|
77
78
|
try {
|
|
78
|
-
B(await
|
|
79
|
+
B(await C());
|
|
79
80
|
} catch (e) {
|
|
80
|
-
H(
|
|
81
|
+
H(n(e));
|
|
81
82
|
} finally {
|
|
82
83
|
K(!1);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
|
-
async function
|
|
86
|
-
K(!0), H(null), B([]),
|
|
86
|
+
async function $(e) {
|
|
87
|
+
K(!0), H(null), B([]), Y({});
|
|
87
88
|
try {
|
|
88
|
-
I(await
|
|
89
|
+
I(await T(e));
|
|
89
90
|
} catch (e) {
|
|
90
|
-
H(
|
|
91
|
+
H(n(e));
|
|
91
92
|
} finally {
|
|
92
93
|
K(!1);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
|
-
async function
|
|
96
|
-
if (!F || !Z || !
|
|
96
|
+
async function ue() {
|
|
97
|
+
if (!F || !Z || !N) return;
|
|
97
98
|
J(!0), H(null), W({});
|
|
98
|
-
let
|
|
99
|
-
if (
|
|
100
|
-
H(
|
|
99
|
+
let t = s(Object.values(ae));
|
|
100
|
+
if (t) {
|
|
101
|
+
H(t), J(!1);
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
+
if (X.blockMessage) {
|
|
105
|
+
H(X.blockMessage), J(!1);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
let r = e(te(Z.fields, L), F.templateVersion.workflowDefinition);
|
|
104
109
|
try {
|
|
105
|
-
let e = await
|
|
110
|
+
let e = await re({
|
|
106
111
|
schema: Z,
|
|
107
112
|
uiSchema: F.formVersion.uiSchema,
|
|
108
|
-
values:
|
|
113
|
+
values: r
|
|
109
114
|
});
|
|
110
115
|
if (!e.valid) {
|
|
111
|
-
W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey &&
|
|
116
|
+
W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && ne(e.firstInvalidFieldKey);
|
|
112
117
|
return;
|
|
113
118
|
}
|
|
114
|
-
let t = await
|
|
115
|
-
formData:
|
|
116
|
-
initiatorMemberId:
|
|
119
|
+
let t = await E({
|
|
120
|
+
formData: r,
|
|
121
|
+
initiatorMemberId: N,
|
|
117
122
|
templateId: F.template.id,
|
|
118
|
-
title:
|
|
123
|
+
title: w({
|
|
119
124
|
fallbackTitle: F.template.name,
|
|
120
|
-
formData:
|
|
125
|
+
formData: r,
|
|
121
126
|
schema: Z,
|
|
122
127
|
uiSchema: F.formVersion.uiSchema
|
|
123
128
|
})
|
|
124
129
|
});
|
|
125
|
-
|
|
130
|
+
A.push(j.caseDetail(t));
|
|
126
131
|
} catch (e) {
|
|
127
|
-
H(
|
|
132
|
+
H(n(e));
|
|
128
133
|
} finally {
|
|
129
134
|
J(!1);
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
|
-
async function
|
|
133
|
-
if (!
|
|
134
|
-
return { id: (await
|
|
137
|
+
async function de(e, t) {
|
|
138
|
+
if (!N) throw Error("尚未登入,無法上傳附件");
|
|
139
|
+
return { id: (await D({
|
|
135
140
|
file: t,
|
|
136
141
|
formFieldPath: `form.${e.fieldKey}`
|
|
137
142
|
})).id };
|
|
138
143
|
}
|
|
139
|
-
return /* @__PURE__ */
|
|
144
|
+
return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(O, {
|
|
140
145
|
description: F ? `${F.template.name} · 表單 v${F.formVersion.version}` : "選擇可發起的已發布模板後填寫表單內容。",
|
|
141
146
|
title: "發起簽核",
|
|
142
|
-
children: F ? /* @__PURE__ */
|
|
147
|
+
children: F ? /* @__PURE__ */ x(ee, {
|
|
143
148
|
disabled: G || q,
|
|
144
|
-
icon:
|
|
149
|
+
icon: k,
|
|
145
150
|
iconType: "leading",
|
|
146
|
-
onClick:
|
|
151
|
+
onClick: ue,
|
|
147
152
|
variant: "base-primary",
|
|
148
153
|
children: "送出"
|
|
149
154
|
}) : null
|
|
150
|
-
}) }), /* @__PURE__ */
|
|
151
|
-
style:
|
|
155
|
+
}) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ x(g, { children: /* @__PURE__ */ S("div", {
|
|
156
|
+
style: ie,
|
|
152
157
|
children: [
|
|
153
|
-
V ? /* @__PURE__ */
|
|
158
|
+
V ? /* @__PURE__ */ x(y, {
|
|
154
159
|
color: "text-error",
|
|
155
160
|
variant: "body",
|
|
156
161
|
children: V
|
|
157
162
|
}) : null,
|
|
158
|
-
G ? /* @__PURE__ */
|
|
163
|
+
G ? /* @__PURE__ */ x(y, {
|
|
159
164
|
color: "text-neutral",
|
|
160
165
|
variant: "body",
|
|
161
166
|
children: "載入中..."
|
|
162
167
|
}) : null,
|
|
163
|
-
F && Z ? /* @__PURE__ */
|
|
168
|
+
F && Z ? /* @__PURE__ */ x(l, {
|
|
164
169
|
dataSourceContext: {
|
|
165
170
|
kind: "runtime",
|
|
166
171
|
templateId: F.template.id
|
|
@@ -170,19 +175,20 @@ function j({ templateId: c }) {
|
|
|
170
175
|
onChange: (e) => {
|
|
171
176
|
R(e), W({});
|
|
172
177
|
},
|
|
173
|
-
onDataSourceStateChange:
|
|
174
|
-
|
|
178
|
+
onDataSourceStateChange: oe,
|
|
179
|
+
onFileUploadStateChange: X.onFileUploadStateChange,
|
|
180
|
+
onUploadAttachment: de,
|
|
175
181
|
schema: Z,
|
|
176
182
|
singleColumn: !0,
|
|
177
183
|
uiSchema: F.formVersion.uiSchema,
|
|
178
184
|
value: L
|
|
179
185
|
}) : null,
|
|
180
|
-
!P && !G ? Q.length > 0 ? /* @__PURE__ */ v
|
|
181
|
-
actions:
|
|
182
|
-
columns:
|
|
186
|
+
!P && !G ? Q.length > 0 ? /* @__PURE__ */ x(v, {
|
|
187
|
+
actions: ce,
|
|
188
|
+
columns: se,
|
|
183
189
|
dataSource: Q,
|
|
184
190
|
fullWidth: !0
|
|
185
|
-
}) : /* @__PURE__ */
|
|
191
|
+
}) : /* @__PURE__ */ x(y, {
|
|
186
192
|
color: "text-neutral",
|
|
187
193
|
variant: "body",
|
|
188
194
|
children: "目前沒有可發起的已發布模板。"
|
|
@@ -191,18 +197,15 @@ function j({ templateId: c }) {
|
|
|
191
197
|
}) }) })] });
|
|
192
198
|
}
|
|
193
199
|
function M() {
|
|
194
|
-
return /* @__PURE__ */
|
|
200
|
+
return /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(h, { children: /* @__PURE__ */ x(O, {
|
|
195
201
|
description: "選擇可發起的已發布模板後填寫表單內容。",
|
|
196
202
|
title: "發起簽核"
|
|
197
|
-
}) }), /* @__PURE__ */
|
|
203
|
+
}) }), /* @__PURE__ */ x(_, { children: /* @__PURE__ */ x(g, { children: /* @__PURE__ */ x(y, {
|
|
198
204
|
color: "text-neutral",
|
|
199
205
|
variant: "body",
|
|
200
206
|
children: "載入中..."
|
|
201
207
|
}) }) })] });
|
|
202
208
|
}
|
|
203
|
-
function N(e) {
|
|
204
|
-
return k(e) || (e instanceof Error ? e.message : "發生未知錯誤");
|
|
205
|
-
}
|
|
206
209
|
export { A as InstanceNewView };
|
|
207
210
|
|
|
208
211
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["_Fragment","readApplicantFormSchema","readApplicantSubmission","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readErrorMessage","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table","readFormDataSourceErrorMessage"],"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.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-Bb5bUVFd.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-
|
|
1
|
+
export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-egQlRjuZ.js";
|
|
@@ -8,5 +8,12 @@ export declare function readTemplateVersionDescription(input: {
|
|
|
8
8
|
hasPublishedVersion: boolean;
|
|
9
9
|
publishedVersion: number | null;
|
|
10
10
|
}): string;
|
|
11
|
+
/**
|
|
12
|
+
* The designer header's description line: the version line plus the
|
|
13
|
+
* definition's expression dialect. `ContentHeader` drops any child that is not
|
|
14
|
+
* a button, filter or back link, so a dialect `Tag` there never rendered; its
|
|
15
|
+
* `description` string is the slot it does show.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readTemplateHeaderDescription(versionDescription: string, expressionDialect: string): string;
|
|
11
18
|
/** The bound form's version, labelled so it is not mistaken for the template's. */
|
|
12
19
|
export declare function readFormVersionLabel(formName: string, version: number): string;
|
|
@@ -8,5 +8,12 @@ export declare function readTemplateVersionDescription(input: {
|
|
|
8
8
|
hasPublishedVersion: boolean;
|
|
9
9
|
publishedVersion: number | null;
|
|
10
10
|
}): string;
|
|
11
|
+
/**
|
|
12
|
+
* The designer header's description line: the version line plus the
|
|
13
|
+
* definition's expression dialect. `ContentHeader` drops any child that is not
|
|
14
|
+
* a button, filter or back link, so a dialect `Tag` there never rendered; its
|
|
15
|
+
* `description` string is the slot it does show.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readTemplateHeaderDescription(versionDescription: string, expressionDialect: string): string;
|
|
11
18
|
/** The bound form's version, labelled so it is not mistaken for the template's. */
|
|
12
19
|
export declare function readFormVersionLabel(formName: string, version: number): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { WorkflowDialectUpgradePreviewRecord, WorkflowExpressionsDraft } from '@rytass/bpm-core-client/template';
|
|
3
|
+
export interface DialectUpgradeModalProps {
|
|
4
|
+
/** The draft to check: the designer's current state, saved or not. */
|
|
5
|
+
readonly draft: WorkflowExpressionsDraft;
|
|
6
|
+
readonly onCancel: () => void;
|
|
7
|
+
/** The user confirmed; the host switches the draft to cel-v2. */
|
|
8
|
+
readonly onConfirm: () => void;
|
|
9
|
+
readonly open: boolean;
|
|
10
|
+
/** Injectable for tests and Storybook. */
|
|
11
|
+
readonly preview?: (draft: WorkflowExpressionsDraft) => Promise<WorkflowDialectUpgradePreviewRecord>;
|
|
12
|
+
}
|
|
13
|
+
/** `ok:<json>` / `err:<code>` as the designer reads it. */
|
|
14
|
+
export declare function readDialectOutcomeText(outcome: string): string;
|
|
15
|
+
/** Whether the check lets the user upgrade on it. */
|
|
16
|
+
export declare function canConfirmDialectUpgrade(result: WorkflowDialectUpgradePreviewRecord | null): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The whole-draft dialect upgrade (Phase 23 P4, docs/24 §1): before a draft
|
|
19
|
+
* moves from cel-legacy to cel-v2 the backend runs every expression under
|
|
20
|
+
* both engines on sample data and lists where the answers differ, e.g.
|
|
21
|
+
* `7 / 2` is 3.5 on legacy and an integer division on cel-v2. Nothing is
|
|
22
|
+
* changed here; confirming hands the decision back to the designer, which
|
|
23
|
+
* sets the dialect on the draft and saves it the usual way.
|
|
24
|
+
*/
|
|
25
|
+
export declare function DialectUpgradeModal({ draft, onCancel, onConfirm, open, preview, }: DialectUpgradeModalProps): ReactElement;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { WorkflowDialectUpgradePreviewRecord, WorkflowExpressionsDraft } from '@rytass/bpm-core-client/template';
|
|
3
|
+
export interface DialectUpgradeModalProps {
|
|
4
|
+
/** The draft to check: the designer's current state, saved or not. */
|
|
5
|
+
readonly draft: WorkflowExpressionsDraft;
|
|
6
|
+
readonly onCancel: () => void;
|
|
7
|
+
/** The user confirmed; the host switches the draft to cel-v2. */
|
|
8
|
+
readonly onConfirm: () => void;
|
|
9
|
+
readonly open: boolean;
|
|
10
|
+
/** Injectable for tests and Storybook. */
|
|
11
|
+
readonly preview?: (draft: WorkflowExpressionsDraft) => Promise<WorkflowDialectUpgradePreviewRecord>;
|
|
12
|
+
}
|
|
13
|
+
/** `ok:<json>` / `err:<code>` as the designer reads it. */
|
|
14
|
+
export declare function readDialectOutcomeText(outcome: string): string;
|
|
15
|
+
/** Whether the check lets the user upgrade on it. */
|
|
16
|
+
export declare function canConfirmDialectUpgrade(result: WorkflowDialectUpgradePreviewRecord | null): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The whole-draft dialect upgrade (Phase 23 P4, docs/24 §1): before a draft
|
|
19
|
+
* moves from cel-legacy to cel-v2 the backend runs every expression under
|
|
20
|
+
* both engines on sample data and lists where the answers differ, e.g.
|
|
21
|
+
* `7 / 2` is 3.5 on legacy and an integer division on cel-v2. Nothing is
|
|
22
|
+
* changed here; confirming hands the decision back to the designer, which
|
|
23
|
+
* sets the dialect on the draft and saves it the usual way.
|
|
24
|
+
*/
|
|
25
|
+
export declare function DialectUpgradeModal({ draft, onCancel, onConfirm, open, preview, }: DialectUpgradeModalProps): ReactElement;
|