@rytass/bpm-core-react 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +1 -0
  3. package/dist/chunks/FormBuilderView-Bg9ftYz-.cjs +4 -0
  4. package/dist/chunks/FormBuilderView-Bg9ftYz-.cjs.map +1 -0
  5. package/dist/chunks/{FormBuilderView-DbfbLZCI.js → FormBuilderView-CBvdcg_t.js} +675 -614
  6. package/dist/chunks/FormBuilderView-CBvdcg_t.js.map +1 -0
  7. package/dist/chunks/FormRendererView-D-p6GDQB.cjs +6 -0
  8. package/dist/chunks/FormRendererView-D-p6GDQB.cjs.map +1 -0
  9. package/dist/chunks/FormRendererView-DHXmekC3.js +1319 -0
  10. package/dist/chunks/FormRendererView-DHXmekC3.js.map +1 -0
  11. package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs → approval-instance-list-page-BqkG9jiR.cjs} +2 -2
  12. package/dist/chunks/{approval-instance-list-page-Cv5I1YPX.cjs.map → approval-instance-list-page-BqkG9jiR.cjs.map} +1 -1
  13. package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js → approval-instance-list-page-CsSpIN4C.js} +2 -2
  14. package/dist/chunks/{approval-instance-list-page-BI5fIXc-.js.map → approval-instance-list-page-CsSpIN4C.js.map} +1 -1
  15. package/dist/chunks/compose-B43jtdyL.cjs +2 -0
  16. package/dist/chunks/compose-B43jtdyL.cjs.map +1 -0
  17. package/dist/chunks/{compose-U1zs3Yof.js → compose-C7yS6bJm.js} +162 -148
  18. package/dist/chunks/compose-C7yS6bJm.js.map +1 -0
  19. package/dist/chunks/{dashboard-page-BoqNhjT_.js → dashboard-page-DBJCsPya.js} +2 -2
  20. package/dist/chunks/{dashboard-page-BoqNhjT_.js.map → dashboard-page-DBJCsPya.js.map} +1 -1
  21. package/dist/chunks/{dashboard-page-D7YJ3udk.cjs → dashboard-page-lqlLELKs.cjs} +2 -2
  22. package/dist/chunks/{dashboard-page-D7YJ3udk.cjs.map → dashboard-page-lqlLELKs.cjs.map} +1 -1
  23. package/dist/chunks/{designer-DPG7R_WP.js → designer-B9Ut4xze.js} +1786 -1463
  24. package/dist/chunks/designer-B9Ut4xze.js.map +1 -0
  25. package/dist/chunks/designer-eXw7R9ug.cjs +69 -0
  26. package/dist/chunks/designer-eXw7R9ug.cjs.map +1 -0
  27. package/dist/chunks/{detail-CHZDNNM6.js → detail-BB_uYaoM.js} +904 -896
  28. package/dist/chunks/detail-BB_uYaoM.js.map +1 -0
  29. package/dist/chunks/detail-DN8pEzUJ.cjs +5 -0
  30. package/dist/chunks/detail-DN8pEzUJ.cjs.map +1 -0
  31. package/dist/chunks/instance-error-message-BKt07-Bo.js +270 -0
  32. package/dist/chunks/instance-error-message-BKt07-Bo.js.map +1 -0
  33. package/dist/chunks/instance-error-message-BL_X7Af8.cjs +2 -0
  34. package/dist/chunks/instance-error-message-BL_X7Af8.cjs.map +1 -0
  35. package/dist/chunks/member-profile-resolution-CJlgVdTR.js +44 -0
  36. package/dist/chunks/member-profile-resolution-CJlgVdTR.js.map +1 -0
  37. package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs +2 -0
  38. package/dist/chunks/member-profile-resolution-DiH-P-Vh.cjs.map +1 -0
  39. package/dist/chunks/{providers-CQWekD7_.js → providers-D35lBOTd.js} +2 -2
  40. package/dist/chunks/{providers-CQWekD7_.js.map → providers-D35lBOTd.js.map} +1 -1
  41. package/dist/chunks/{providers-VUOh6i0i.cjs → providers-Dz4Wqxr6.cjs} +2 -2
  42. package/dist/chunks/{providers-VUOh6i0i.cjs.map → providers-Dz4Wqxr6.cjs.map} +1 -1
  43. package/dist/chunks/{routes-config-C1j_vFKo.cjs → routes-config-BWjZDAU3.cjs} +2 -2
  44. package/dist/chunks/{routes-config-C1j_vFKo.cjs.map → routes-config-BWjZDAU3.cjs.map} +1 -1
  45. package/dist/chunks/{routes-config-BcNaWJWJ.js → routes-config-DjEOE9eP.js} +3 -2
  46. package/dist/chunks/{routes-config-BcNaWJWJ.js.map → routes-config-DjEOE9eP.js.map} +1 -1
  47. package/dist/chunks/users-C_Dtw_sR.cjs +2 -0
  48. package/dist/chunks/users-C_Dtw_sR.cjs.map +1 -0
  49. package/dist/chunks/users-wgM3TqU3.js +513 -0
  50. package/dist/chunks/users-wgM3TqU3.js.map +1 -0
  51. package/dist/index.cjs +1 -1
  52. package/dist/index.js +4 -4
  53. package/dist/lib/routes-config.d.cts +2 -0
  54. package/dist/lib/routes-config.d.ts +2 -0
  55. package/dist/next/index.cjs +1 -1
  56. package/dist/next/index.js +2 -2
  57. package/dist/pages/admin/stuck-instances/index.cjs +2 -0
  58. package/dist/pages/admin/stuck-instances/index.cjs.map +1 -0
  59. package/dist/pages/admin/stuck-instances/index.d.cts +4 -0
  60. package/dist/pages/admin/stuck-instances/index.d.ts +4 -0
  61. package/dist/pages/admin/stuck-instances/index.js +13 -0
  62. package/dist/pages/admin/stuck-instances/index.js.map +1 -0
  63. package/dist/pages/admin/users/index.cjs +1 -1
  64. package/dist/pages/admin/users/index.js +1 -1
  65. package/dist/pages/instances/detail/index.cjs +1 -1
  66. package/dist/pages/instances/detail/index.js +1 -1
  67. package/dist/pages/templates/compose/index.cjs +1 -1
  68. package/dist/pages/templates/compose/index.js +1 -1
  69. package/dist/pages/templates/designer/index.cjs +1 -1
  70. package/dist/pages/templates/designer/index.js +1 -1
  71. package/dist/views/admin/index.cjs +1 -1
  72. package/dist/views/admin/index.d.cts +1 -0
  73. package/dist/views/admin/index.d.ts +1 -0
  74. package/dist/views/admin/index.js +3 -2
  75. package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.cts +10 -0
  76. package/dist/views/admin/stuck-instances/AdminStuckInstancesView.d.ts +10 -0
  77. package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.cts +14 -0
  78. package/dist/views/admin/stuck-instances/StuckInstanceCancelModal.d.ts +14 -0
  79. package/dist/views/admin/stuck-instances/index.cjs +2 -0
  80. package/dist/views/admin/stuck-instances/index.cjs.map +1 -0
  81. package/dist/views/admin/stuck-instances/index.d.cts +2 -0
  82. package/dist/views/admin/stuck-instances/index.d.ts +2 -0
  83. package/dist/views/admin/stuck-instances/index.js +237 -0
  84. package/dist/views/admin/stuck-instances/index.js.map +1 -0
  85. package/dist/views/admin/users/index.cjs +1 -1
  86. package/dist/views/admin/users/index.js +1 -1
  87. package/dist/views/cc/index.cjs +1 -1
  88. package/dist/views/cc/index.js +1 -1
  89. package/dist/views/dashboard/index.cjs +1 -1
  90. package/dist/views/dashboard/index.js +1 -1
  91. package/dist/views/forms/builder/index.cjs +1 -1
  92. package/dist/views/forms/builder/index.js +1 -1
  93. package/dist/views/forms/renderer/FormRendererView.d.cts +26 -1
  94. package/dist/views/forms/renderer/FormRendererView.d.ts +26 -1
  95. package/dist/views/forms/renderer/index.cjs +1 -1
  96. package/dist/views/forms/renderer/index.js +1 -1
  97. package/dist/views/inbox/index.cjs +1 -1
  98. package/dist/views/inbox/index.js +1 -1
  99. package/dist/views/instances/approver-filled-form.d.cts +56 -20
  100. package/dist/views/instances/approver-filled-form.d.ts +56 -20
  101. package/dist/views/instances/detail/index.cjs +1 -1
  102. package/dist/views/instances/detail/index.js +1 -1
  103. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +7 -0
  104. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +7 -0
  105. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +1 -1
  106. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +1 -1
  107. package/dist/views/instances/new/index.cjs +1 -1
  108. package/dist/views/instances/new/index.js +5 -5
  109. package/dist/views/instances/new/index.js.map +1 -1
  110. package/dist/views/search/index.cjs +1 -1
  111. package/dist/views/search/index.js +1 -1
  112. package/dist/views/sent/index.cjs +1 -1
  113. package/dist/views/sent/index.js +1 -1
  114. package/dist/views/templates/compose/index.cjs +1 -1
  115. package/dist/views/templates/compose/index.js +1 -1
  116. package/dist/views/templates/compose/steps/ComposeReviewStep.d.cts +3 -1
  117. package/dist/views/templates/compose/steps/ComposeReviewStep.d.ts +3 -1
  118. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.cts +4 -1
  119. package/dist/views/templates/compose/steps/ComposeWorkflowStep.d.ts +4 -1
  120. package/dist/views/templates/compose/use-template-compose-wizard.d.cts +3 -1
  121. package/dist/views/templates/compose/use-template-compose-wizard.d.ts +3 -1
  122. package/dist/views/templates/designer/TemplateDesignerView.d.cts +10 -1
  123. package/dist/views/templates/designer/TemplateDesignerView.d.ts +10 -1
  124. package/dist/views/templates/designer/approver-resolver-model.d.cts +31 -0
  125. package/dist/views/templates/designer/approver-resolver-model.d.ts +31 -0
  126. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.cts +3 -1
  127. package/dist/views/templates/designer/field-access-matrix/FieldAccessMatrixDrawer.d.ts +3 -1
  128. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.cts +3 -2
  129. package/dist/views/templates/designer/field-access-matrix/field-access-copy.d.ts +3 -2
  130. package/dist/views/templates/designer/index.cjs +1 -1
  131. package/dist/views/templates/designer/index.js +1 -1
  132. package/dist/views/templates/designer/launch-mode.d.cts +19 -0
  133. package/dist/views/templates/designer/launch-mode.d.ts +19 -0
  134. package/dist/views/templates/designer/node-actor-resolver-options.d.cts +30 -3
  135. package/dist/views/templates/designer/node-actor-resolver-options.d.ts +30 -3
  136. package/dist/views/templates/designer/publish-default-value-check.d.cts +36 -0
  137. package/dist/views/templates/designer/publish-default-value-check.d.ts +36 -0
  138. package/dist/views/templates/index.cjs +1 -1
  139. package/dist/views/templates/index.js +1 -1
  140. package/dist/views/templates/versions/index.cjs +1 -1
  141. package/dist/views/templates/versions/index.js +1 -1
  142. package/package.json +23 -3
  143. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs +0 -4
  144. package/dist/chunks/FormBuilderView-Bok4Y59D.cjs.map +0 -1
  145. package/dist/chunks/FormBuilderView-DbfbLZCI.js.map +0 -1
  146. package/dist/chunks/FormRendererView-CAyPXhPq.js +0 -1351
  147. package/dist/chunks/FormRendererView-CAyPXhPq.js.map +0 -1
  148. package/dist/chunks/FormRendererView-iLlHFIUR.cjs +0 -6
  149. package/dist/chunks/FormRendererView-iLlHFIUR.cjs.map +0 -1
  150. package/dist/chunks/compose-DP1N4twA.cjs +0 -2
  151. package/dist/chunks/compose-DP1N4twA.cjs.map +0 -1
  152. package/dist/chunks/compose-U1zs3Yof.js.map +0 -1
  153. package/dist/chunks/designer-CWL-dCQ_.cjs +0 -69
  154. package/dist/chunks/designer-CWL-dCQ_.cjs.map +0 -1
  155. package/dist/chunks/designer-DPG7R_WP.js.map +0 -1
  156. package/dist/chunks/detail-BUfsSal0.cjs +0 -5
  157. package/dist/chunks/detail-BUfsSal0.cjs.map +0 -1
  158. package/dist/chunks/detail-CHZDNNM6.js.map +0 -1
  159. package/dist/chunks/instance-error-message-BEM4O_Kj.js +0 -208
  160. package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +0 -1
  161. package/dist/chunks/instance-error-message-BpCLCOjp.cjs +0 -2
  162. package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +0 -1
  163. package/dist/chunks/users-BBtiZ9QQ.js +0 -486
  164. package/dist/chunks/users-BBtiZ9QQ.js.map +0 -1
  165. package/dist/chunks/users-EqSzDhuj.cjs +0 -2
  166. package/dist/chunks/users-EqSzDhuj.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","useFileUploadFieldStates","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","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Cv5I1YPX.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-BqkG9jiR.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BI5fIXc-.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-CsSpIN4C.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/search/SearchView.tsx
5
5
  function n() {
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Cv5I1YPX.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-BqkG9jiR.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BI5fIXc-.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-CsSpIN4C.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/sent/SentView.tsx
5
5
  function n() {
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-DP1N4twA.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-B43jtdyL.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-U1zs3Yof.js";
1
+ export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-C7yS6bJm.js";
@@ -1,5 +1,6 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema, FormUiSchema } from '@rytass/bpm-core-shared/form';
3
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
3
4
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
5
  export interface ComposeReviewStepProps {
5
6
  readonly name: string;
@@ -7,6 +8,7 @@ export interface ComposeReviewStepProps {
7
8
  readonly formUiSchema: FormUiSchema;
8
9
  readonly workflowDefinition: WorkflowDefinition | null;
9
10
  readonly initiatorPolicyCel: string | null;
11
+ readonly launchMode: ApprovalTemplateLaunchMode;
10
12
  readonly publishError: string | null;
11
13
  }
12
- export declare function ComposeReviewStep({ formSchema, formUiSchema, initiatorPolicyCel, name, publishError, workflowDefinition, }: ComposeReviewStepProps): ReactElement;
14
+ export declare function ComposeReviewStep({ formSchema, formUiSchema, initiatorPolicyCel, launchMode, name, publishError, workflowDefinition, }: ComposeReviewStepProps): ReactElement;
@@ -1,5 +1,6 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema, FormUiSchema } from '@rytass/bpm-core-shared/form';
3
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
3
4
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
5
  export interface ComposeReviewStepProps {
5
6
  readonly name: string;
@@ -7,6 +8,7 @@ export interface ComposeReviewStepProps {
7
8
  readonly formUiSchema: FormUiSchema;
8
9
  readonly workflowDefinition: WorkflowDefinition | null;
9
10
  readonly initiatorPolicyCel: string | null;
11
+ readonly launchMode: ApprovalTemplateLaunchMode;
10
12
  readonly publishError: string | null;
11
13
  }
12
- export declare function ComposeReviewStep({ formSchema, formUiSchema, initiatorPolicyCel, name, publishError, workflowDefinition, }: ComposeReviewStepProps): ReactElement;
14
+ export declare function ComposeReviewStep({ formSchema, formUiSchema, initiatorPolicyCel, launchMode, name, publishError, workflowDefinition, }: ComposeReviewStepProps): ReactElement;
@@ -1,12 +1,15 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
4
5
  export interface ComposeWorkflowStepProps {
5
6
  readonly formSchema: FormDefinitionSchema;
6
7
  readonly workflowDefinition: WorkflowDefinition | null;
7
8
  readonly initiatorPolicyCel: string | null;
8
9
  readonly onWorkflowChange: (definition: WorkflowDefinition) => void;
9
10
  readonly onInitiatorPolicyChange: (cel: string | null) => void;
11
+ readonly launchMode: ApprovalTemplateLaunchMode;
12
+ readonly onLaunchModeChange: (launchMode: ApprovalTemplateLaunchMode) => void;
10
13
  /**
11
14
  * Show the AI assistant button inside the embedded designer's side panel.
12
15
  * Follows the same opt-in contract as the standalone designer page; default
@@ -19,4 +22,4 @@ export interface ComposeWorkflowStepProps {
19
22
  */
20
23
  readonly aiAssistantAvailable?: boolean;
21
24
  }
22
- export declare function ComposeWorkflowStep({ aiAssistantAvailable, formSchema, initiatorPolicyCel, onInitiatorPolicyChange, onWorkflowChange, showAiAssistant, workflowDefinition, }: ComposeWorkflowStepProps): ReactElement;
25
+ export declare function ComposeWorkflowStep({ aiAssistantAvailable, formSchema, initiatorPolicyCel, launchMode, onInitiatorPolicyChange, onLaunchModeChange, onWorkflowChange, showAiAssistant, workflowDefinition, }: ComposeWorkflowStepProps): ReactElement;
@@ -1,12 +1,15 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
4
5
  export interface ComposeWorkflowStepProps {
5
6
  readonly formSchema: FormDefinitionSchema;
6
7
  readonly workflowDefinition: WorkflowDefinition | null;
7
8
  readonly initiatorPolicyCel: string | null;
8
9
  readonly onWorkflowChange: (definition: WorkflowDefinition) => void;
9
10
  readonly onInitiatorPolicyChange: (cel: string | null) => void;
11
+ readonly launchMode: ApprovalTemplateLaunchMode;
12
+ readonly onLaunchModeChange: (launchMode: ApprovalTemplateLaunchMode) => void;
10
13
  /**
11
14
  * Show the AI assistant button inside the embedded designer's side panel.
12
15
  * Follows the same opt-in contract as the standalone designer page; default
@@ -19,4 +22,4 @@ export interface ComposeWorkflowStepProps {
19
22
  */
20
23
  readonly aiAssistantAvailable?: boolean;
21
24
  }
22
- export declare function ComposeWorkflowStep({ aiAssistantAvailable, formSchema, initiatorPolicyCel, onInitiatorPolicyChange, onWorkflowChange, showAiAssistant, workflowDefinition, }: ComposeWorkflowStepProps): ReactElement;
25
+ export declare function ComposeWorkflowStep({ aiAssistantAvailable, formSchema, initiatorPolicyCel, launchMode, onInitiatorPolicyChange, onLaunchModeChange, onWorkflowChange, showAiAssistant, workflowDefinition, }: ComposeWorkflowStepProps): ReactElement;
@@ -1,6 +1,6 @@
1
1
  import { FormDefinitionSchema, FormUiSchema } from '@rytass/bpm-core-shared/form';
2
2
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
3
- import { ComposeApprovalTemplateWithFormResult } from '@rytass/bpm-core-client/template';
3
+ import { ApprovalTemplateLaunchMode, ComposeApprovalTemplateWithFormResult } from '@rytass/bpm-core-client/template';
4
4
  export type ComposeWizardStep = 0 | 1 | 2;
5
5
  export type ComposePublishPhase = 'error' | 'idle' | 'submitting' | 'success';
6
6
  export declare const EMPTY_COMPOSE_FORM_SCHEMA: FormDefinitionSchema;
@@ -18,6 +18,7 @@ export interface TemplateComposeWizard {
18
18
  readonly formUiSchema: FormUiSchema;
19
19
  readonly workflowDefinition: WorkflowDefinition | null;
20
20
  readonly initiatorPolicyCel: string | null;
21
+ readonly launchMode: ApprovalTemplateLaunchMode;
21
22
  readonly publishPhase: ComposePublishPhase;
22
23
  readonly publishError: string | null;
23
24
  readonly canLeaveBasics: boolean;
@@ -32,6 +33,7 @@ export interface TemplateComposeWizard {
32
33
  }) => void;
33
34
  readonly setWorkflowDefinition: (definition: WorkflowDefinition) => void;
34
35
  readonly setInitiatorPolicyCel: (cel: string | null) => void;
36
+ readonly setLaunchMode: (launchMode: ApprovalTemplateLaunchMode) => void;
35
37
  readonly publish: () => Promise<ComposeApprovalTemplateWithFormResult | null>;
36
38
  }
37
39
  /**
@@ -1,6 +1,6 @@
1
1
  import { FormDefinitionSchema, FormUiSchema } from '@rytass/bpm-core-shared/form';
2
2
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
3
- import { ComposeApprovalTemplateWithFormResult } from '@rytass/bpm-core-client/template';
3
+ import { ApprovalTemplateLaunchMode, ComposeApprovalTemplateWithFormResult } from '@rytass/bpm-core-client/template';
4
4
  export type ComposeWizardStep = 0 | 1 | 2;
5
5
  export type ComposePublishPhase = 'error' | 'idle' | 'submitting' | 'success';
6
6
  export declare const EMPTY_COMPOSE_FORM_SCHEMA: FormDefinitionSchema;
@@ -18,6 +18,7 @@ export interface TemplateComposeWizard {
18
18
  readonly formUiSchema: FormUiSchema;
19
19
  readonly workflowDefinition: WorkflowDefinition | null;
20
20
  readonly initiatorPolicyCel: string | null;
21
+ readonly launchMode: ApprovalTemplateLaunchMode;
21
22
  readonly publishPhase: ComposePublishPhase;
22
23
  readonly publishError: string | null;
23
24
  readonly canLeaveBasics: boolean;
@@ -32,6 +33,7 @@ export interface TemplateComposeWizard {
32
33
  }) => void;
33
34
  readonly setWorkflowDefinition: (definition: WorkflowDefinition) => void;
34
35
  readonly setInitiatorPolicyCel: (cel: string | null) => void;
36
+ readonly setLaunchMode: (launchMode: ApprovalTemplateLaunchMode) => void;
35
37
  readonly publish: () => Promise<ComposeApprovalTemplateWithFormResult | null>;
36
38
  }
37
39
  /**
@@ -1,6 +1,7 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
4
5
  export interface TemplateDesignerViewProps {
5
6
  /**
6
7
  * Template id to load. Required in non-embedded mode; unused in embedded mode.
@@ -35,6 +36,14 @@ export interface TemplateDesignerViewProps {
35
36
  * Falls back to `null` (no policy) when omitted.
36
37
  */
37
38
  readonly initialInitiatorPolicyCel?: string | null;
39
+ /**
40
+ * In embedded mode: the initial 發起方式. Falls back to `OPEN` when omitted.
41
+ */
42
+ readonly initialLaunchMode?: ApprovalTemplateLaunchMode;
43
+ /**
44
+ * In embedded mode: called whenever the 發起方式 changes.
45
+ */
46
+ readonly onLaunchModeChange?: (launchMode: ApprovalTemplateLaunchMode) => void;
38
47
  /**
39
48
  * In embedded mode: called whenever the workflow definition changes so the
40
49
  * host can persist the current canvas state.
@@ -62,4 +71,4 @@ export interface TemplateDesignerViewProps {
62
71
  */
63
72
  readonly aiAssistantAvailable?: boolean;
64
73
  }
65
- export declare function TemplateDesignerView({ aiAssistantAvailable, embedded, formSchemaOverride, initialInitiatorPolicyCel, initialWorkflowDefinition, onInitiatorPolicyChange, onWorkflowChange, showAiAssistant, showDryRun, templateId, }: TemplateDesignerViewProps): ReactElement;
74
+ export declare function TemplateDesignerView({ aiAssistantAvailable, embedded, formSchemaOverride, initialInitiatorPolicyCel, initialLaunchMode, initialWorkflowDefinition, onInitiatorPolicyChange, onLaunchModeChange, onWorkflowChange, showAiAssistant, showDryRun, templateId, }: TemplateDesignerViewProps): ReactElement;
@@ -1,6 +1,7 @@
1
1
  import { ReactElement } from 'react';
2
2
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
3
3
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
4
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
4
5
  export interface TemplateDesignerViewProps {
5
6
  /**
6
7
  * Template id to load. Required in non-embedded mode; unused in embedded mode.
@@ -35,6 +36,14 @@ export interface TemplateDesignerViewProps {
35
36
  * Falls back to `null` (no policy) when omitted.
36
37
  */
37
38
  readonly initialInitiatorPolicyCel?: string | null;
39
+ /**
40
+ * In embedded mode: the initial 發起方式. Falls back to `OPEN` when omitted.
41
+ */
42
+ readonly initialLaunchMode?: ApprovalTemplateLaunchMode;
43
+ /**
44
+ * In embedded mode: called whenever the 發起方式 changes.
45
+ */
46
+ readonly onLaunchModeChange?: (launchMode: ApprovalTemplateLaunchMode) => void;
38
47
  /**
39
48
  * In embedded mode: called whenever the workflow definition changes so the
40
49
  * host can persist the current canvas state.
@@ -62,4 +71,4 @@ export interface TemplateDesignerViewProps {
62
71
  */
63
72
  readonly aiAssistantAvailable?: boolean;
64
73
  }
65
- export declare function TemplateDesignerView({ aiAssistantAvailable, embedded, formSchemaOverride, initialInitiatorPolicyCel, initialWorkflowDefinition, onInitiatorPolicyChange, onWorkflowChange, showAiAssistant, showDryRun, templateId, }: TemplateDesignerViewProps): ReactElement;
74
+ export declare function TemplateDesignerView({ aiAssistantAvailable, embedded, formSchemaOverride, initialInitiatorPolicyCel, initialLaunchMode, initialWorkflowDefinition, onInitiatorPolicyChange, onLaunchModeChange, onWorkflowChange, showAiAssistant, showDryRun, templateId, }: TemplateDesignerViewProps): ReactElement;
@@ -233,6 +233,22 @@ export declare const START_POSITION_LEVEL_ABOVE_MIN_HINT = "\u8D77\u59CB\u8077\u
233
233
  * No `startFrom` is the initiator.
234
234
  */
235
235
  export declare function readOrgManagerChainStartMode(resolver: OrgManagerChainResolver): OrgManagerChainStartMode | null;
236
+ /**
237
+ * `true` when 接續前面某一段主管鏈 cannot be picked because the stage already
238
+ * has 起點本人已達簽到職等時略過 ticked: the two exclude each other (the publish
239
+ * check refuses both together). A stage that already continues is not blocked:
240
+ * its own option is the selected one.
241
+ */
242
+ export declare function isOrgManagerChainContinuationPickDisabled(resolver: OrgManagerChainResolver): boolean;
243
+ /**
244
+ * `true` when the 起點本人已達簽到職等時略過 box cannot be ticked because the
245
+ * stage continues an earlier chain. A stage that stores anything but "no
246
+ * flag" next to the continuation stays unblocked, so the author can still
247
+ * write the flag back to a valid value: `true` (both set) and a stored value
248
+ * that is not a boolean (`'yes'`, which the box shows unticked while the shape
249
+ * check keeps refusing it) would otherwise be impossible to clear.
250
+ */
251
+ export declare function isOrgManagerChainSkipToggleDisabled(resolver: OrgManagerChainResolver): boolean;
236
252
  export type OrgManagerChainStartChoice = Readonly<{
237
253
  /** Hint under the select: what the chosen start means. */
238
254
  hint: string;
@@ -273,6 +289,21 @@ export declare function withOrgManagerChainStartFormPath(resolver: OrgManagerCha
273
289
  * comes back as the same object.
274
290
  */
275
291
  export declare function withOrgManagerChainStartNodeIds(resolver: OrgManagerChainResolver, nodeIds: readonly string[]): OrgManagerChainResolver;
292
+ /** The stage a `CHAIN_CONTINUATION` start continues, else `null`. */
293
+ export declare function readOrgManagerChainContinuationNodeId(resolver: OrgManagerChainResolver): string | null;
294
+ /**
295
+ * The resolver with the stage a `CHAIN_CONTINUATION` start continues set. Any
296
+ * other start comes back as the same object.
297
+ */
298
+ export declare function withOrgManagerChainContinuationNodeId(resolver: OrgManagerChainResolver, nodeId: string): OrgManagerChainResolver;
299
+ /** Whether 起點本人已達簽到職等時略過此關 is ticked. */
300
+ export declare function readOrgManagerChainSkipWhenStartReached(resolver: OrgManagerChainResolver): boolean;
301
+ /**
302
+ * The resolver after 起點本人已達簽到職等時略過此關 is ticked or unticked: ticked
303
+ * writes `skipWhenStartReached: true`, unticked removes the key (never a
304
+ * stored `false`, which reads the same but would show up as a change).
305
+ */
306
+ export declare function withOrgManagerChainSkipWhenStartReached(resolver: OrgManagerChainResolver, skip: boolean): OrgManagerChainResolver;
276
307
  /**
277
308
  * The resolver after 簽到職等 is set to `minPositionLevel`: `startFrom`,
278
309
  * `startPositionLevel` and `fallback` stay as they were.
@@ -233,6 +233,22 @@ export declare const START_POSITION_LEVEL_ABOVE_MIN_HINT = "\u8D77\u59CB\u8077\u
233
233
  * No `startFrom` is the initiator.
234
234
  */
235
235
  export declare function readOrgManagerChainStartMode(resolver: OrgManagerChainResolver): OrgManagerChainStartMode | null;
236
+ /**
237
+ * `true` when 接續前面某一段主管鏈 cannot be picked because the stage already
238
+ * has 起點本人已達簽到職等時略過 ticked: the two exclude each other (the publish
239
+ * check refuses both together). A stage that already continues is not blocked:
240
+ * its own option is the selected one.
241
+ */
242
+ export declare function isOrgManagerChainContinuationPickDisabled(resolver: OrgManagerChainResolver): boolean;
243
+ /**
244
+ * `true` when the 起點本人已達簽到職等時略過 box cannot be ticked because the
245
+ * stage continues an earlier chain. A stage that stores anything but "no
246
+ * flag" next to the continuation stays unblocked, so the author can still
247
+ * write the flag back to a valid value: `true` (both set) and a stored value
248
+ * that is not a boolean (`'yes'`, which the box shows unticked while the shape
249
+ * check keeps refusing it) would otherwise be impossible to clear.
250
+ */
251
+ export declare function isOrgManagerChainSkipToggleDisabled(resolver: OrgManagerChainResolver): boolean;
236
252
  export type OrgManagerChainStartChoice = Readonly<{
237
253
  /** Hint under the select: what the chosen start means. */
238
254
  hint: string;
@@ -273,6 +289,21 @@ export declare function withOrgManagerChainStartFormPath(resolver: OrgManagerCha
273
289
  * comes back as the same object.
274
290
  */
275
291
  export declare function withOrgManagerChainStartNodeIds(resolver: OrgManagerChainResolver, nodeIds: readonly string[]): OrgManagerChainResolver;
292
+ /** The stage a `CHAIN_CONTINUATION` start continues, else `null`. */
293
+ export declare function readOrgManagerChainContinuationNodeId(resolver: OrgManagerChainResolver): string | null;
294
+ /**
295
+ * The resolver with the stage a `CHAIN_CONTINUATION` start continues set. Any
296
+ * other start comes back as the same object.
297
+ */
298
+ export declare function withOrgManagerChainContinuationNodeId(resolver: OrgManagerChainResolver, nodeId: string): OrgManagerChainResolver;
299
+ /** Whether 起點本人已達簽到職等時略過此關 is ticked. */
300
+ export declare function readOrgManagerChainSkipWhenStartReached(resolver: OrgManagerChainResolver): boolean;
301
+ /**
302
+ * The resolver after 起點本人已達簽到職等時略過此關 is ticked or unticked: ticked
303
+ * writes `skipWhenStartReached: true`, unticked removes the key (never a
304
+ * stored `false`, which reads the same but would show up as a change).
305
+ */
306
+ export declare function withOrgManagerChainSkipWhenStartReached(resolver: OrgManagerChainResolver, skip: boolean): OrgManagerChainResolver;
276
307
  /**
277
308
  * The resolver after 簽到職等 is set to `minPositionLevel`: `startFrom`,
278
309
  * `startPositionLevel` and `fallback` stay as they were.
@@ -1,5 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
- import { FieldAccessChoice, FieldAccessMatrixEntry } from '@rytass/bpm-core-shared';
2
+ import { FieldAccessChoice, FieldAccessFill, FieldAccessMatrixEntry } from '@rytass/bpm-core-shared';
3
3
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
4
4
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
5
5
  import { BPMLanguage } from '../../../../lib/language-provider.cjs';
@@ -23,6 +23,8 @@ export interface FieldAccessMatrixDrawerProps {
23
23
  }
24
24
  /** Sets one cell of the draft; `DEFAULT` removes its entry. */
25
25
  export declare function updateFieldAccessDraft(entries: readonly FieldAccessMatrixEntry[], nodeId: string, fieldKey: string, choice: FieldAccessChoice): readonly FieldAccessMatrixEntry[];
26
+ /** Sets one table column's fill in column mode; `NONE` takes that column out. */
27
+ export declare function updateFieldAccessColumnDraft(entries: readonly FieldAccessMatrixEntry[], nodeId: string, fieldKey: string, columnKey: string, fill: FieldAccessFill): readonly FieldAccessMatrixEntry[];
26
28
  /**
27
29
  * The cells edited in the drawer (`draft` against `initial`), laid onto the
28
30
  * entries the flow holds now. An undo or an assistant edit made while the
@@ -1,5 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
- import { FieldAccessChoice, FieldAccessMatrixEntry } from '@rytass/bpm-core-shared';
2
+ import { FieldAccessChoice, FieldAccessFill, FieldAccessMatrixEntry } from '@rytass/bpm-core-shared';
3
3
  import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
4
4
  import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
5
5
  import { BPMLanguage } from '../../../../lib/language-provider.js';
@@ -23,6 +23,8 @@ export interface FieldAccessMatrixDrawerProps {
23
23
  }
24
24
  /** Sets one cell of the draft; `DEFAULT` removes its entry. */
25
25
  export declare function updateFieldAccessDraft(entries: readonly FieldAccessMatrixEntry[], nodeId: string, fieldKey: string, choice: FieldAccessChoice): readonly FieldAccessMatrixEntry[];
26
+ /** Sets one table column's fill in column mode; `NONE` takes that column out. */
27
+ export declare function updateFieldAccessColumnDraft(entries: readonly FieldAccessMatrixEntry[], nodeId: string, fieldKey: string, columnKey: string, fill: FieldAccessFill): readonly FieldAccessMatrixEntry[];
26
28
  /**
27
29
  * The cells edited in the drawer (`draft` against `initial`), laid onto the
28
30
  * entries the flow holds now. An undo or an assistant edit made while the
@@ -1,6 +1,8 @@
1
- import { FieldAccessChoice, FieldAccessEffective, FieldAccessIssue, FieldAccessIssueCode, FieldAccessMatrixColumn } from '@rytass/bpm-core-shared';
1
+ import { FieldAccessChoice, FieldAccessEffective, FieldAccessFill, FieldAccessIssue, FieldAccessIssueCode, FieldAccessMatrixColumn } from '@rytass/bpm-core-shared';
2
2
  import { UserTaskNode } from '@rytass/bpm-core-shared/workflow';
3
3
  export declare const FIELD_ACCESS_CHOICE_LABELS: Readonly<Record<FieldAccessChoice, string>>;
4
+ /** The per-column fill choices under a table row in column mode. */
5
+ export declare const FIELD_ACCESS_COLUMN_FILL_LABELS: Readonly<Record<FieldAccessFill, string>>;
4
6
  export declare const FIELD_ACCESS_EFFECTIVE_LABELS: Readonly<Record<FieldAccessEffective, string>>;
5
7
  /**
6
8
  * Why the form will not let an approver fill a field in, short enough for the
@@ -8,7 +10,6 @@ export declare const FIELD_ACCESS_EFFECTIVE_LABELS: Readonly<Record<FieldAccessE
8
10
  * actually set to be filled in.
9
11
  */
10
12
  export declare const FIELD_ACCESS_FILL_BLOCKER_LABELS: Readonly<Partial<Record<FieldAccessIssueCode, string>>>;
11
- export declare const FIELD_ACCESS_BOOLEAN_REQUIRED_NOTE = "\u958B\u95DC\u6B04\u4F4D\u53EA\u80FD\u9078\u586B\u88DC\u586B\uFF1A\u958B\u95DC\u95DC\u8457\u4E5F\u662F\u7B54\u6848\uFF0C\u4E0D\u80FD\u8981\u6C42\u5FC5\u586B\u3002";
12
13
  export declare const FIELD_ACCESS_HIDE_NOTE = "\u300C\u96B1\u85CF\u300D\u53EA\u5F71\u97FF\u9019\u4E00\u95DC\u7684\u756B\u9762\uFF0C\u4E0D\u662F\u6B0A\u9650\uFF1A\u8CC7\u6599\u67E5\u8A62\u4ECD\u62FF\u5F97\u5230\u503C\uFF0C\u4E0D\u80FD\u7528\u4F86\u4FDD\u5BC6\u3002";
13
14
  export declare function readFieldAccessStageLabel(column: Pick<FieldAccessMatrixColumn, 'stage'>): string;
14
15
  export interface FieldAccessNodeCounts {
@@ -1,6 +1,8 @@
1
- import { FieldAccessChoice, FieldAccessEffective, FieldAccessIssue, FieldAccessIssueCode, FieldAccessMatrixColumn } from '@rytass/bpm-core-shared';
1
+ import { FieldAccessChoice, FieldAccessEffective, FieldAccessFill, FieldAccessIssue, FieldAccessIssueCode, FieldAccessMatrixColumn } from '@rytass/bpm-core-shared';
2
2
  import { UserTaskNode } from '@rytass/bpm-core-shared/workflow';
3
3
  export declare const FIELD_ACCESS_CHOICE_LABELS: Readonly<Record<FieldAccessChoice, string>>;
4
+ /** The per-column fill choices under a table row in column mode. */
5
+ export declare const FIELD_ACCESS_COLUMN_FILL_LABELS: Readonly<Record<FieldAccessFill, string>>;
4
6
  export declare const FIELD_ACCESS_EFFECTIVE_LABELS: Readonly<Record<FieldAccessEffective, string>>;
5
7
  /**
6
8
  * Why the form will not let an approver fill a field in, short enough for the
@@ -8,7 +10,6 @@ export declare const FIELD_ACCESS_EFFECTIVE_LABELS: Readonly<Record<FieldAccessE
8
10
  * actually set to be filled in.
9
11
  */
10
12
  export declare const FIELD_ACCESS_FILL_BLOCKER_LABELS: Readonly<Partial<Record<FieldAccessIssueCode, string>>>;
11
- export declare const FIELD_ACCESS_BOOLEAN_REQUIRED_NOTE = "\u958B\u95DC\u6B04\u4F4D\u53EA\u80FD\u9078\u586B\u88DC\u586B\uFF1A\u958B\u95DC\u95DC\u8457\u4E5F\u662F\u7B54\u6848\uFF0C\u4E0D\u80FD\u8981\u6C42\u5FC5\u586B\u3002";
12
13
  export declare const FIELD_ACCESS_HIDE_NOTE = "\u300C\u96B1\u85CF\u300D\u53EA\u5F71\u97FF\u9019\u4E00\u95DC\u7684\u756B\u9762\uFF0C\u4E0D\u662F\u6B0A\u9650\uFF1A\u8CC7\u6599\u67E5\u8A62\u4ECD\u62FF\u5F97\u5230\u503C\uFF0C\u4E0D\u80FD\u7528\u4F86\u4FDD\u5BC6\u3002";
13
14
  export declare function readFieldAccessStageLabel(column: Pick<FieldAccessMatrixColumn, 'stage'>): string;
14
15
  export interface FieldAccessNodeCounts {
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/designer-CWL-dCQ_.cjs");exports.TemplateDesignerView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/designer-eXw7R9ug.cjs");exports.TemplateDesignerView=e.t;
@@ -1 +1 @@
1
- export { t as TemplateDesignerView } from "../../../chunks/designer-DPG7R_WP.js";
1
+ export { t as TemplateDesignerView } from "../../../chunks/designer-B9Ut4xze.js";
@@ -0,0 +1,19 @@
1
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
2
+ /** 發起方式 option shown in the designer and the compose wizard. */
3
+ export interface LaunchModeOption {
4
+ readonly id: ApprovalTemplateLaunchMode;
5
+ readonly name: string;
6
+ readonly description: string;
7
+ }
8
+ export declare const LAUNCH_MODE_OPTIONS: readonly LaunchModeOption[];
9
+ /** A template with no stored mode, or an unknown value, behaves as OPEN. */
10
+ export declare const DEFAULT_LAUNCH_MODE: ApprovalTemplateLaunchMode;
11
+ export declare function readLaunchMode(value: string | null | undefined): ApprovalTemplateLaunchMode;
12
+ export declare function readLaunchModeOption(mode: ApprovalTemplateLaunchMode): LaunchModeOption;
13
+ /**
14
+ * Draft-save input fragment. `launchMode` is always sent so the server stores
15
+ * the mode the user sees; an omitted field would keep whatever is stored.
16
+ */
17
+ export declare function buildDraftLaunchModeInput(launchMode: ApprovalTemplateLaunchMode): {
18
+ readonly launchMode: ApprovalTemplateLaunchMode;
19
+ };
@@ -0,0 +1,19 @@
1
+ import { ApprovalTemplateLaunchMode } from '@rytass/bpm-core-client/template';
2
+ /** 發起方式 option shown in the designer and the compose wizard. */
3
+ export interface LaunchModeOption {
4
+ readonly id: ApprovalTemplateLaunchMode;
5
+ readonly name: string;
6
+ readonly description: string;
7
+ }
8
+ export declare const LAUNCH_MODE_OPTIONS: readonly LaunchModeOption[];
9
+ /** A template with no stored mode, or an unknown value, behaves as OPEN. */
10
+ export declare const DEFAULT_LAUNCH_MODE: ApprovalTemplateLaunchMode;
11
+ export declare function readLaunchMode(value: string | null | undefined): ApprovalTemplateLaunchMode;
12
+ export declare function readLaunchModeOption(mode: ApprovalTemplateLaunchMode): LaunchModeOption;
13
+ /**
14
+ * Draft-save input fragment. `launchMode` is always sent so the server stores
15
+ * the mode the user sees; an omitted field would keep whatever is stored.
16
+ */
17
+ export declare function buildDraftLaunchModeInput(launchMode: ApprovalTemplateLaunchMode): {
18
+ readonly launchMode: ApprovalTemplateLaunchMode;
19
+ };
@@ -13,7 +13,7 @@ export type NodeActorStageChoice = Readonly<{
13
13
  problems: readonly string[];
14
14
  selected: readonly NodeActorOption[];
15
15
  }>;
16
- export declare const NO_UPSTREAM_USER_TASK_HINT = "\u9019\u500B\u7BC0\u9EDE\u524D\u9762\u6C92\u6709\u53EF\u4EE5\u9078\u7684\u7C3D\u6838\u95DC\u5361\uFF0C\u8ACB\u5148\u5728\u5B83\u524D\u9762\u52A0\u5165\u7C3D\u6838\u7BC0\u9EDE\uFF08\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\uFF0C\u4E5F\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF09";
16
+ export declare const NO_UPSTREAM_USER_TASK_HINT = "\u9019\u500B\u7BC0\u9EDE\u524D\u9762\u6C92\u6709\u53EF\u4EE5\u9078\u7684\u7C3D\u6838\u95DC\u5361\uFF0C\u8ACB\u5148\u5728\u5B83\u524D\u9762\u52A0\u5165\u7C3D\u6838\u7BC0\u9EDE\uFF08\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\u3001\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF0C\u4E3B\u7BA1\u93C8\u4E5F\u6C92\u8A2D\u7565\u904E\uFF09";
17
17
  /** The 關卡 picker's hint while the selection has no problem to report. */
18
18
  export declare const NODE_ACTOR_STAGE_HINT = "\u7C3D\u6838\u4EBA\u53D6\u81EA\u4F60\u9078\u7684\u524D\u9762\u95DC\u5361\u5BE6\u969B\u7C3D\u6838\u7684\u4EBA\uFF1B\u53EF\u8907\u9078\uFF0C\u6574\u7D44\u8981\u6DB5\u84CB\u6BCF\u689D\u8DEF\u5F91\u3002\u8907\u9078\u591A\u500B\u95DC\u5361\u6642\uFF0C\u53D6\u6700\u8FD1\u5BE6\u969B\u8D70\u5230\u7684\u90A3\u4E00\u95DC\u7684\u7C3D\u6838\u4EBA\uFF0C\u4E0D\u662F\u5168\u90E8\u95DC\u5361\u7684\u7C3D\u6838\u4EBA\u3002";
19
19
  /**
@@ -57,9 +57,9 @@ export declare function readOrgManagerChainStageChoice(definition: WorkflowDefin
57
57
  */
58
58
  export declare function readNodeActorGraphIssues(definition: WorkflowDefinition): readonly string[];
59
59
  /** The hint under the 不可與前面關卡同一人 picker while it has no problem to report. */
60
- export declare const EXCLUDE_NODE_ACTORS_STAGE_HINT = "\u6B64\u95DC\u7684\u7C3D\u6838\u4EBA\u4E0D\u6703\u662F\u4F60\u9078\u7684\u524D\u9762\u95DC\u5361\u5BE6\u969B\u7C3D\u6838\u7684\u4EBA\uFF08\u542B\u5176\u4EE3\u7406\u4EBA\uFF09\uFF0C\u4E5F\u4E0D\u80FD\u88AB\u8F49\u7C3D\u6216\u52A0\u7C3D\u5230\u6B64\u95DC\uFF1B\u53EF\u8907\u9078\uFF0C\u6BCF\u500B\u95DC\u5361\u90FD\u6703\u6392\u9664\u3002\u53EA\u80FD\u9078\u6BCF\u689D\u8DEF\u5F91\u90FD\u6703\u7D93\u904E\u3001\u800C\u4E14\u4E00\u5B9A\u6709\u4EBA\u5BE6\u969B\u7C3D\u6838\u7684\u95DC\u5361\uFF08\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\u3001\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF09\uFF1B\u689D\u4EF6\u5F0F\u7684\u95DC\u5361\u3001\u5E73\u884C\u5206\u652F\u4E0A\u7684\u95DC\u5361\u90FD\u4E0D\u652F\u63F4\uFF0C\u689D\u4EF6\u5F0F\u7684\u8ACB\u6539\u7528\u5206\u6D41\u628A\u5169\u95DC\u653E\u5728\u540C\u4E00\u689D\u8DEF\u7DDA\u4E0A\uFF0C\u5E73\u884C\u5206\u652F\u4E0A\u7684\u8ACB\u6539\u6210\u5148\u5F8C\u4E32\u63A5\u3002";
60
+ export declare const EXCLUDE_NODE_ACTORS_STAGE_HINT = "\u6B64\u95DC\u7684\u7C3D\u6838\u4EBA\u4E0D\u6703\u662F\u4F60\u9078\u7684\u524D\u9762\u95DC\u5361\u5BE6\u969B\u7C3D\u6838\u7684\u4EBA\uFF08\u542B\u5176\u4EE3\u7406\u4EBA\uFF09\uFF0C\u4E5F\u4E0D\u80FD\u88AB\u8F49\u7C3D\u6216\u52A0\u7C3D\u5230\u6B64\u95DC\uFF1B\u53EF\u8907\u9078\uFF0C\u6BCF\u500B\u95DC\u5361\u90FD\u6703\u6392\u9664\u3002\u53EA\u80FD\u9078\u6BCF\u689D\u8DEF\u5F91\u90FD\u6703\u7D93\u904E\u3001\u800C\u4E14\u4E00\u5B9A\u6709\u4EBA\u5BE6\u969B\u7C3D\u6838\u7684\u95DC\u5361\uFF08\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\u3001\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF0C\u4E3B\u7BA1\u93C8\u4E5F\u6C92\u8A2D\u7565\u904E\uFF09\uFF1B\u689D\u4EF6\u5F0F\u7684\u95DC\u5361\u3001\u5E73\u884C\u5206\u652F\u4E0A\u7684\u95DC\u5361\u90FD\u4E0D\u652F\u63F4\uFF0C\u689D\u4EF6\u5F0F\u7684\u8ACB\u6539\u7528\u5206\u6D41\u628A\u5169\u95DC\u653E\u5728\u540C\u4E00\u689D\u8DEF\u7DDA\u4E0A\uFF0C\u5E73\u884C\u5206\u652F\u4E0A\u7684\u8ACB\u6539\u6210\u5148\u5F8C\u4E32\u63A5\u3002";
61
61
  /** Shown when no earlier stage can be picked. */
62
- export declare const NO_EXCLUDABLE_STAGE_HINT = "\u9019\u500B\u7BC0\u9EDE\u524D\u9762\u6C92\u6709\u53EF\u4EE5\u9078\u7684\u7C3D\u6838\u95DC\u5361\uFF0C\u8ACB\u5148\u5728\u5B83\u524D\u9762\u52A0\u5165\u7C3D\u6838\u7BC0\u9EDE\uFF08\u6BCF\u689D\u8DEF\u5F91\u90FD\u6703\u7D93\u904E\u3001\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\uFF0C\u4E5F\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF09";
62
+ export declare const NO_EXCLUDABLE_STAGE_HINT = "\u9019\u500B\u7BC0\u9EDE\u524D\u9762\u6C92\u6709\u53EF\u4EE5\u9078\u7684\u7C3D\u6838\u95DC\u5361\uFF0C\u8ACB\u5148\u5728\u5B83\u524D\u9762\u52A0\u5165\u7C3D\u6838\u7BC0\u9EDE\uFF08\u6BCF\u689D\u8DEF\u5F91\u90FD\u6703\u7D93\u904E\u3001\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\u3001\u6C92\u8A2D\u903E\u6642\u81EA\u52D5\u6838\u51C6\uFF0C\u4E3B\u7BA1\u93C8\u4E5F\u6C92\u8A2D\u7565\u904E\uFF09";
63
63
  /**
64
64
  * The 不可與前面關卡同一人 picker: the user tasks that pass the publish
65
65
  * check on their own (`readExcludeNodeActorsIssues` with just that stage
@@ -79,3 +79,30 @@ export declare function readExcludeNodeActorStageChoice(definition: WorkflowDefi
79
79
  * which blocks saving.
80
80
  */
81
81
  export declare function readExcludeNodeActorsGraphIssues(definition: WorkflowDefinition): readonly string[];
82
+ export type ChainContinuationSourceChoice = Readonly<{
83
+ /** The upstream manager chains that can be continued, plus a stale stored choice. */
84
+ options: readonly NodeActorOption[];
85
+ /** Live problems of the stored choice (the publish check's own lines). */
86
+ problems: readonly string[];
87
+ selected: NodeActorOption | null;
88
+ }>;
89
+ /** Shown when no upstream manager chain can be continued. */
90
+ export declare const NO_CONTINUABLE_CHAIN_HINT = "\u9019\u500B\u7BC0\u9EDE\u524D\u9762\u6C92\u6709\u53EF\u4EE5\u63A5\u7E8C\u7684\u4E3B\u7BA1\u93C8\u95DC\u5361\uFF1B\u9700\u8981\u662F\u6BCF\u689D\u8DEF\u5F91\u90FD\u6703\u7D93\u904E\u3001\u8D77\u9EDE\u70BA\u7533\u8ACB\u4EBA\u6216\u524D\u9762\u95DC\u5361\u7C3D\u6838\u8005\u3001\u672C\u8EAB\u4E0D\u662F\u63A5\u7E8C\u578B\u3001\u6C92\u6709\u9032\u5165\u689D\u4EF6\u3001\u4E5F\u6C92\u8A2D\u8DF3\u904E\u6B64\u95DC\u7684\u300C\u6CBF\u4E3B\u7BA1\u93C8\u7C3D\u6838\u300D\u95DC\u5361\u3002";
91
+ /**
92
+ * The 接續哪一關 picker of a manager chain that continues an earlier one: the
93
+ * manager-chain stages for which `readChainContinuationSourceIssues` has
94
+ * nothing to say when `nodeId` continues them (at an unreachably high level, so
95
+ * the level rule never decides). Judged by the shared check itself, not by
96
+ * matching strings, so the list cannot drift from the publish lint. A stage with
97
+ * 起點本人已達簽到職等時略過 is still offered: the engine reads its skip record.
98
+ * A stored stage that does not qualify stays in the list, marked, and the
99
+ * `problems` say why, so the stored choice is never dropped silently.
100
+ */
101
+ export declare function readChainContinuationSourceChoice(definition: WorkflowDefinition, nodeId: string, selectedId: string | null): ChainContinuationSourceChoice;
102
+ /**
103
+ * The graph problems of every manager chain that continues an earlier one,
104
+ * naming the node: the checks the backend publish lint runs
105
+ * (`readChainContinuationSourceIssues`), for the designer to show before
106
+ * publish. A missing stage id is left to `readOrgManagerChainIssue`.
107
+ */
108
+ export declare function readChainContinuationGraphIssues(definition: WorkflowDefinition): readonly string[];