@rytass/bpm-core-react 0.20.1 → 0.21.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 (127) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/README.md +1 -1
  3. package/dist/approval-instance-list-page.css +1 -1
  4. package/dist/chunks/FormBuilderView-DjPGrOJ2.cjs +4 -0
  5. package/dist/chunks/FormBuilderView-DjPGrOJ2.cjs.map +1 -0
  6. package/dist/chunks/{FormBuilderView-CFRiw04B.js → FormBuilderView-WtC2iW5f.js} +667 -584
  7. package/dist/chunks/FormBuilderView-WtC2iW5f.js.map +1 -0
  8. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs → FormRendererView-B-xycC9S.cjs} +3 -3
  9. package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs.map → FormRendererView-B-xycC9S.cjs.map} +1 -1
  10. package/dist/chunks/{FormRendererView-GfbVWEGa.js → FormRendererView-BcQKUi1A.js} +238 -238
  11. package/dist/chunks/{FormRendererView-GfbVWEGa.js.map → FormRendererView-BcQKUi1A.js.map} +1 -1
  12. package/dist/chunks/approval-instance-list-page-Bth7Raya.js +724 -0
  13. package/dist/chunks/approval-instance-list-page-Bth7Raya.js.map +1 -0
  14. package/dist/chunks/approval-instance-list-page-Dcvo6TrT.cjs +2 -0
  15. package/dist/chunks/approval-instance-list-page-Dcvo6TrT.cjs.map +1 -0
  16. package/dist/chunks/{categories-DQUtVEiV.cjs → categories-CyyqG6wG.cjs} +2 -2
  17. package/dist/chunks/{categories-DQUtVEiV.cjs.map → categories-CyyqG6wG.cjs.map} +1 -1
  18. package/dist/chunks/{categories-BAdxjNSA.js → categories-f7E-RJEc.js} +9 -9
  19. package/dist/chunks/{categories-BAdxjNSA.js.map → categories-f7E-RJEc.js.map} +1 -1
  20. package/dist/chunks/{compose-Bb5bUVFd.cjs → compose-BKUTsB2W.cjs} +2 -2
  21. package/dist/chunks/{compose-Bb5bUVFd.cjs.map → compose-BKUTsB2W.cjs.map} +1 -1
  22. package/dist/chunks/{compose-egQlRjuZ.js → compose-DZvIspW3.js} +4 -4
  23. package/dist/chunks/{compose-egQlRjuZ.js.map → compose-DZvIspW3.js.map} +1 -1
  24. package/dist/chunks/{delegations-CVmtpkRn.cjs → delegations-ClRCwD1I.cjs} +2 -2
  25. package/dist/chunks/{delegations-CVmtpkRn.cjs.map → delegations-ClRCwD1I.cjs.map} +1 -1
  26. package/dist/chunks/{delegations-9-yvWWws.js → delegations-CqND-Qtz.js} +5 -5
  27. package/dist/chunks/{delegations-9-yvWWws.js.map → delegations-CqND-Qtz.js.map} +1 -1
  28. package/dist/chunks/{delegations-CrfjsH94.cjs → delegations-D43VDSz1.cjs} +2 -2
  29. package/dist/chunks/{delegations-CrfjsH94.cjs.map → delegations-D43VDSz1.cjs.map} +1 -1
  30. package/dist/chunks/{delegations-CxnNvTCc.js → delegations-zisffLwk.js} +5 -5
  31. package/dist/chunks/{delegations-CxnNvTCc.js.map → delegations-zisffLwk.js.map} +1 -1
  32. package/dist/chunks/{designer-CZDlQ9Nf.js → designer-CWubIE69.js} +1425 -1412
  33. package/dist/chunks/designer-CWubIE69.js.map +1 -0
  34. package/dist/chunks/designer-C_m8DmMl.cjs +69 -0
  35. package/dist/chunks/designer-C_m8DmMl.cjs.map +1 -0
  36. package/dist/chunks/{detail-ByZV1XaI.js → detail-Bv90gvy0.js} +578 -577
  37. package/dist/chunks/detail-Bv90gvy0.js.map +1 -0
  38. package/dist/chunks/detail-DNzqesdI.cjs +5 -0
  39. package/dist/chunks/detail-DNzqesdI.cjs.map +1 -0
  40. package/dist/chunks/instance-error-message-BW464LRQ.cjs +2 -0
  41. package/dist/chunks/instance-error-message-BW464LRQ.cjs.map +1 -0
  42. package/dist/chunks/instance-error-message-CAP1vJhX.js +204 -0
  43. package/dist/chunks/instance-error-message-CAP1vJhX.js.map +1 -0
  44. package/dist/components/approval-instance-field-filter-controls.d.cts +12 -0
  45. package/dist/components/approval-instance-field-filter-controls.d.ts +12 -0
  46. package/dist/components/approval-instance-field-filters.d.cts +86 -0
  47. package/dist/components/approval-instance-field-filters.d.ts +86 -0
  48. package/dist/components/approval-instance-list-page.d.cts +4 -0
  49. package/dist/components/approval-instance-list-page.d.ts +4 -0
  50. package/dist/index.cjs +1 -1
  51. package/dist/index.js +1 -1
  52. package/dist/next/workflow-chat-route.cjs +2 -2
  53. package/dist/next/workflow-chat-route.cjs.map +1 -1
  54. package/dist/next/workflow-chat-route.js +13 -13
  55. package/dist/pages/admin/delegations/index.cjs +1 -1
  56. package/dist/pages/admin/delegations/index.js +1 -1
  57. package/dist/pages/delegations/index.cjs +1 -1
  58. package/dist/pages/delegations/index.js +1 -1
  59. package/dist/pages/instances/detail/index.cjs +1 -1
  60. package/dist/pages/instances/detail/index.js +1 -1
  61. package/dist/pages/templates/categories/index.cjs +1 -1
  62. package/dist/pages/templates/categories/index.js +1 -1
  63. package/dist/pages/templates/compose/index.cjs +1 -1
  64. package/dist/pages/templates/compose/index.js +1 -1
  65. package/dist/pages/templates/designer/index.cjs +1 -1
  66. package/dist/pages/templates/designer/index.js +1 -1
  67. package/dist/views/admin/delegations/index.cjs +1 -1
  68. package/dist/views/admin/delegations/index.js +1 -1
  69. package/dist/views/admin/index.cjs +1 -1
  70. package/dist/views/admin/index.js +1 -1
  71. package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
  72. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  73. package/dist/views/admin/webhook-endpoints/index.js +60 -60
  74. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  75. package/dist/views/cc/index.cjs +1 -1
  76. package/dist/views/cc/index.js +1 -1
  77. package/dist/views/delegations/index.cjs +1 -1
  78. package/dist/views/delegations/index.js +1 -1
  79. package/dist/views/forms/builder/FormBuilderView.d.cts +8 -1
  80. package/dist/views/forms/builder/FormBuilderView.d.ts +8 -1
  81. package/dist/views/forms/builder/index.cjs +1 -1
  82. package/dist/views/forms/builder/index.js +1 -1
  83. package/dist/views/forms/renderer/index.cjs +1 -1
  84. package/dist/views/forms/renderer/index.js +1 -1
  85. package/dist/views/instances/approver-filled-form.d.cts +8 -5
  86. package/dist/views/instances/approver-filled-form.d.ts +8 -5
  87. package/dist/views/instances/detail/index.cjs +1 -1
  88. package/dist/views/instances/detail/index.js +1 -1
  89. package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +2 -1
  90. package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +2 -1
  91. package/dist/views/instances/new/index.cjs +1 -1
  92. package/dist/views/instances/new/index.cjs.map +1 -1
  93. package/dist/views/instances/new/index.js +8 -8
  94. package/dist/views/instances/new/index.js.map +1 -1
  95. package/dist/views/search/index.cjs +1 -1
  96. package/dist/views/search/index.js +1 -1
  97. package/dist/views/sent/index.cjs +1 -1
  98. package/dist/views/sent/index.js +1 -1
  99. package/dist/views/templates/categories/index.cjs +1 -1
  100. package/dist/views/templates/categories/index.js +1 -1
  101. package/dist/views/templates/compose/index.cjs +1 -1
  102. package/dist/views/templates/compose/index.js +1 -1
  103. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.cts +2 -0
  104. package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.ts +2 -0
  105. package/dist/views/templates/designer/index.cjs +1 -1
  106. package/dist/views/templates/designer/index.js +1 -1
  107. package/dist/views/templates/index.cjs +1 -1
  108. package/dist/views/templates/index.cjs.map +1 -1
  109. package/dist/views/templates/index.js +7 -7
  110. package/package.json +3 -3
  111. package/dist/chunks/FormBuilderView-CFRiw04B.js.map +0 -1
  112. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +0 -3
  113. package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +0 -1
  114. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js +0 -279
  115. package/dist/chunks/approval-instance-list-page-BnI4t5mD.js.map +0 -1
  116. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs +0 -2
  117. package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs.map +0 -1
  118. package/dist/chunks/designer-CX9bhYJS.cjs +0 -69
  119. package/dist/chunks/designer-CX9bhYJS.cjs.map +0 -1
  120. package/dist/chunks/designer-CZDlQ9Nf.js.map +0 -1
  121. package/dist/chunks/detail-ByZV1XaI.js.map +0 -1
  122. package/dist/chunks/detail-ChseSF55.cjs +0 -5
  123. package/dist/chunks/detail-ChseSF55.cjs.map +0 -1
  124. package/dist/chunks/instance-error-message-DTARGbGo.cjs +0 -2
  125. package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +0 -1
  126. package/dist/chunks/instance-error-message-q6gy5evy.js +0 -120
  127. package/dist/chunks/instance-error-message-q6gy5evy.js.map +0 -1
@@ -1,17 +1,17 @@
1
1
  "use client";
2
- import { i as e, r as t, t as n } from "../../../chunks/instance-error-message-q6gy5evy.js";
2
+ import { i as e, r as t, t as n } from "../../../chunks/instance-error-message-CAP1vJhX.js";
3
3
  import { t as r } from "../../../chunks/format-date-time-B0LdmWg4.js";
4
4
  import { n as i } from "../../../chunks/auth-provider-C2b-5mGt.js";
5
5
  import { r as a } from "../../../chunks/router-adapter-CkxCyzf5.js";
6
6
  import { r as o } from "../../../chunks/routes-config-BcNaWJWJ.js";
7
- import { l as s, o as c, t as l } from "../../../chunks/FormRendererView-GfbVWEGa.js";
7
+ import { l as s, o as c, t as l } from "../../../chunks/FormRendererView-BcQKUi1A.js";
8
8
  import { Suspense as u, useCallback as d, useEffect as f, useMemo as p, useState as m } from "react";
9
9
  import { Button as ee, PageHeader as h, Section as g, SectionGroup as _, Table as v, Typography as y } from "@mezzanine-ui/react";
10
10
  import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
11
11
  import { listLaunchableTemplates as C, readFormDataCaseTitle as w, readLaunchContext as T, submitApprovalInstance as E, uploadAttachment as D } from "@rytass/bpm-core-client/workflow";
12
12
  import O from "@mezzanine-ui/react/ContentHeader";
13
- import { CheckedIcon as k } from "@mezzanine-ui/icons";
14
- import { buildFormRendererValues as te, focusFormRendererField as ne, validateFormRendererValuesInWorker as re } from "@rytass/bpm-core-client/form";
13
+ import { buildFormRendererValues as k, focusFormRendererField as te, validateFormRendererValuesInWorker as ne } from "@rytass/bpm-core-client/form";
14
+ import { CheckedIcon as re } from "@mezzanine-ui/icons";
15
15
  // src/views/instances/new/InstanceNewView.tsx
16
16
  var ie = {
17
17
  display: "grid",
@@ -105,15 +105,15 @@ function j({ templateId: u }) {
105
105
  H(X.blockMessage), J(!1);
106
106
  return;
107
107
  }
108
- let r = e(te(Z.fields, L), F.templateVersion.workflowDefinition);
108
+ let r = e(k(Z.fields, L), F.templateVersion.workflowDefinition);
109
109
  try {
110
- let e = await re({
110
+ let e = await ne({
111
111
  schema: Z,
112
112
  uiSchema: F.formVersion.uiSchema,
113
113
  values: r
114
114
  });
115
115
  if (!e.valid) {
116
- W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && ne(e.firstInvalidFieldKey);
116
+ W(e.errors), H("請先修正表單中標示的欄位。"), e.firstInvalidFieldKey && te(e.firstInvalidFieldKey);
117
117
  return;
118
118
  }
119
119
  let t = await E({
@@ -146,7 +146,7 @@ function j({ templateId: u }) {
146
146
  title: "發起簽核",
147
147
  children: F ? /* @__PURE__ */ x(ee, {
148
148
  disabled: G || q,
149
- icon: k,
149
+ icon: re,
150
150
  iconType: "leading",
151
151
  onClick: ue,
152
152
  variant: "base-primary",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","readApplicantSubmission","readApplicantFormSchema","readErrorMessage","formatDateTime","useAuth","useRouterAdapter","useBPMRoutes","readFormDataSourceSubmissionBlockMessage","useFileUploadFieldStates","FormRenderer","Fragment$1","ContentHeader","FORM_SECTION_STYLE","InstanceNewView","Suspense","NewApprovalInstanceLoading","NewApprovalInstanceContent","props","templateIdProp","router","routes","currentMemberId","member","templateId","context","setContext","useState","formValues","setFormValues","templates","setTemplates","error","setError","formErrors","setFormErrors","loading","setLoading","submitting","setSubmitting","dataSourceStates","setDataSourceStates","fileUploads","applicantSchema","useMemo","handleDataSourceStateChange","useCallback","currentState","currentStates","fieldKey","state","refreshContext","refreshTemplates","rows","template","columns","tableActions","record","listLaunchableTemplates","requestError","readLaunchContext","nextTemplateId","handleSubmit","dataSourceBlockMessage","submittedValues","buildFormRendererValues","validation","validateFormRendererValuesInWorker","focusFormRendererField","instanceId","submitApprovalInstance","readFormDataCaseTitle","handleUploadAttachment","uploadAttachment","field","PageHeader","Button","CheckedIcon","SectionGroup","Section","Typography","values","Table"],"sources":["../../../../src/views/instances/new/InstanceNewView.tsx"],"sourcesContent":["'use client';\n\nimport {\n CSSProperties,\n ReactElement,\n Suspense,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { CheckedIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldDefinition } from '@rytass/bpm-core-shared/form';\nimport {\n buildFormRendererValues,\n focusFormRendererField,\n FormRendererValues,\n validateFormRendererValuesInWorker,\n} from '@rytass/bpm-core-client/form';\nimport {\n LaunchContext,\n LaunchableTemplateRecord,\n listLaunchableTemplates,\n readFormDataCaseTitle,\n readLaunchContext,\n submitApprovalInstance,\n uploadAttachment,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n readApplicantFormSchema,\n readApplicantSubmission,\n} from '../approver-filled-form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { useAuth } from '../../../lib/auth-provider';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { useBPMRoutes } from '../../../lib/routes-config';\nimport { FormRenderer } from '../../forms/renderer/FormRendererView';\nimport {\n readFormDataSourceSubmissionBlockMessage,\n type FormDataSourceFieldState,\n} from '../../forms/renderer/form-data-source-field';\nimport { useFileUploadFieldStates } from '../../forms/renderer/file-upload-field';\nimport { readErrorMessage } from '../instance-error-message';\n\nconst FORM_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\ntype LaunchableTemplateRow = Readonly<\n Record<string, unknown> &\n LaunchableTemplateRecord & {\n key: string;\n versionLabel: string;\n }\n>;\n\nexport interface InstanceNewViewProps {\n /**\n * Optional template id pre-selected by the host. The Server Component\n * page should read `?templateId=` from its `searchParams` and pass the\n * value through this prop.\n */\n readonly templateId?: string | null;\n}\n\n/**\n * Framework-agnostic view for the BPM \"發起簽核\" launch page. Mechanical port\n * of `apps/client/src/app/instances/new/page.tsx` — picks a launchable\n * template and submits the launch form.\n */\nexport function InstanceNewView(\n props: InstanceNewViewProps = {},\n): ReactElement {\n return (\n <Suspense fallback={<NewApprovalInstanceLoading />}>\n <NewApprovalInstanceContent templateId={props.templateId ?? undefined} />\n </Suspense>\n );\n}\n\nfunction NewApprovalInstanceContent({\n templateId: templateIdProp,\n}: {\n readonly templateId?: string;\n}): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const templateId = templateIdProp ?? null;\n const [context, setContext] = useState<LaunchContext | null>(null);\n const [formValues, setFormValues] = useState<FormRendererValues>({});\n const [templates, setTemplates] = useState<\n readonly LaunchableTemplateRecord[]\n >([]);\n const [error, setError] = useState<string | null>(null);\n const [formErrors, setFormErrors] = useState<\n Readonly<Record<string, string>>\n >({});\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [dataSourceStates, setDataSourceStates] = useState<\n Readonly<\n Record<\n string,\n Pick<FormDataSourceFieldState, 'hasValue' | 'selectionExpired' | 'status'>\n >\n >\n >({});\n const fileUploads = useFileUploadFieldStates();\n\n // The form the applicant sees: approver-filled fields are not theirs to fill\n // (the server drops them), so they are left out of everything below.\n const applicantSchema = useMemo(\n () =>\n context\n ? readApplicantFormSchema(\n context.formVersion.schema,\n context.templateVersion.workflowDefinition,\n )\n : null,\n [context],\n );\n\n const handleDataSourceStateChange = useCallback(\n (\n fieldKey: string,\n state: Pick<\n FormDataSourceFieldState,\n 'hasValue' | 'invalidValues' | 'selectionExpired' | 'status'\n >,\n ): void => {\n setDataSourceStates((currentStates) => {\n const currentState = currentStates[fieldKey];\n\n if (\n currentState?.hasValue === state.hasValue &&\n currentState.selectionExpired === (state.selectionExpired === true) &&\n currentState.status === state.status\n ) {\n return currentStates;\n }\n\n return {\n ...currentStates,\n [fieldKey]: {\n hasValue: state.hasValue,\n selectionExpired: state.selectionExpired === true,\n status: state.status,\n },\n };\n });\n },\n [],\n );\n\n useEffect((): void => {\n if (!templateId) {\n void refreshTemplates();\n\n return;\n }\n\n void refreshContext(templateId);\n }, [templateId]);\n\n const rows = useMemo(\n (): LaunchableTemplateRow[] =>\n templates.map((template) => ({\n ...template,\n key: template.id,\n updatedAt: formatDateTime(template.updatedAt),\n versionLabel: `v${template.version}`,\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<LaunchableTemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 240 },\n {\n dataIndex: 'versionLabel',\n key: 'versionLabel',\n title: '發布版本',\n width: 120,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<LaunchableTemplateRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<LaunchableTemplateRow>['render']> => [\n {\n name: '發起',\n onClick: (): void =>\n router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n async function refreshTemplates(): Promise<void> {\n setLoading(true);\n setError(null);\n setContext(null);\n setDataSourceStates({});\n\n try {\n setTemplates(await listLaunchableTemplates());\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function refreshContext(nextTemplateId: string): Promise<void> {\n setLoading(true);\n setError(null);\n setTemplates([]);\n setDataSourceStates({});\n\n try {\n setContext(await readLaunchContext(nextTemplateId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function handleSubmit(): Promise<void> {\n if (!context || !applicantSchema || !currentMemberId) {\n return;\n }\n\n setSubmitting(true);\n setError(null);\n setFormErrors({});\n\n const dataSourceBlockMessage = readFormDataSourceSubmissionBlockMessage(\n Object.values(dataSourceStates),\n );\n\n if (dataSourceBlockMessage) {\n setError(dataSourceBlockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // A file still uploading, or one that failed, is listed in its field but\n // is not in the value; submitting now would leave it off the case.\n if (fileUploads.blockMessage) {\n setError(fileUploads.blockMessage);\n setSubmitting(false);\n\n return;\n }\n\n // What the renderer shows, not just what has been touched: a table seeds\n // its `minRows` rows and a field can carry a `defaultValue`, and neither\n // reaches this state until the filler edits something. Validating and\n // submitting the raw state would reject a table the user can plainly see\n // rows in — and submit a default the backend never receives.\n const submittedValues = readApplicantSubmission(\n buildFormRendererValues(applicantSchema.fields, formValues),\n context.templateVersion.workflowDefinition,\n );\n // Inside the `try`, so a validation that throws still clears `submitting`\n // and shows its error instead of leaving the button busy for good.\n try {\n // The format patterns run in a worker under the engine's time budget, so\n // a pattern that backtracks cannot freeze the page.\n const validation = await validateFormRendererValuesInWorker({\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n values: submittedValues,\n });\n\n if (!validation.valid) {\n setFormErrors(validation.errors);\n setError('請先修正表單中標示的欄位。');\n\n if (validation.firstInvalidFieldKey) {\n focusFormRendererField(validation.firstInvalidFieldKey);\n }\n\n return;\n }\n\n const instanceId = await submitApprovalInstance({\n formData: submittedValues,\n initiatorMemberId: currentMemberId,\n templateId: context.template.id,\n title: readFormDataCaseTitle({\n fallbackTitle: context.template.name,\n formData: submittedValues,\n schema: applicantSchema,\n uiSchema: context.formVersion.uiSchema,\n }),\n });\n\n router.push(routes.caseDetail(instanceId));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSubmitting(false);\n }\n }\n\n async function handleUploadAttachment(\n field: FormFieldDefinition,\n file: File,\n ): Promise<{ readonly id: string }> {\n if (!currentMemberId) {\n throw new Error('尚未登入,無法上傳附件');\n }\n\n const attachment = await uploadAttachment({\n file,\n formFieldPath: `form.${field.fieldKey}`,\n });\n\n return { id: attachment.id };\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={\n context\n ? `${context.template.name} · 表單 v${context.formVersion.version}`\n : '選擇可發起的已發布模板後填寫表單內容。'\n }\n title=\"發起簽核\"\n >\n {context ? (\n <Button\n disabled={loading || submitting}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={handleSubmit}\n variant=\"base-primary\"\n >\n 送出\n </Button>\n ) : null}\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={FORM_SECTION_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n\n {loading ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n ) : null}\n\n {context && applicantSchema ? (\n <FormRenderer\n dataSourceContext={{\n kind: 'runtime',\n templateId: context.template.id,\n }}\n errors={formErrors}\n maxWidth={480}\n onChange={(values): void => {\n setFormValues(values);\n setFormErrors({});\n }}\n onDataSourceStateChange={handleDataSourceStateChange}\n onFileUploadStateChange={fileUploads.onFileUploadStateChange}\n onUploadAttachment={handleUploadAttachment}\n schema={applicantSchema}\n singleColumn\n uiSchema={context.formVersion.uiSchema}\n value={formValues}\n />\n ) : null}\n\n {!templateId && !loading ? (\n rows.length > 0 ? (\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 目前沒有可發起的已發布模板。\n </Typography>\n )\n ) : null}\n </div>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction NewApprovalInstanceLoading(): ReactElement {\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"選擇可發起的已發布模板後填寫表單內容。\"\n title=\"發起簽核\"\n />\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <Typography color=\"text-neutral\" variant=\"body\">\n 載入中...\n </Typography>\n </Section>\n </SectionGroup>\n </>\n );\n}\n\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-fqvmkBlg.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Dcvo6TrT.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`以關鍵字與狀態查詢你有權限查看的簽核案件。`,emptyMessage:`沒有符合條件的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`案件搜尋`,view:`ALL`})}exports.SearchView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BnI4t5mD.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-Bth7Raya.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/search/SearchView.tsx
5
5
  function n() {
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-fqvmkBlg.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/approval-instance-list-page-Dcvo6TrT.cjs");let t=require("react/jsx-runtime");function n(){return(0,t.jsx)(e.t,{defaultState:null,description:`查看由你發起或代為送出的簽核案件與目前流程狀態。`,emptyMessage:`目前沒有由你發起或代為送出的簽核案件。`,searchPlaceholder:`關鍵字:搜尋案件、發起人、模板或狀態`,title:`我發起的`,view:`SENT`})}exports.SentView=n;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as e } from "../../chunks/approval-instance-list-page-BnI4t5mD.js";
2
+ import { t as e } from "../../chunks/approval-instance-list-page-Bth7Raya.js";
3
3
  import { jsx as t } from "react/jsx-runtime";
4
4
  // src/views/sent/SentView.tsx
5
5
  function n() {
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/categories-DQUtVEiV.cjs");exports.TemplateCategoriesView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/categories-CyyqG6wG.cjs");exports.TemplateCategoriesView=e.t;
@@ -1 +1 @@
1
- export { t as TemplateCategoriesView } from "../../../chunks/categories-BAdxjNSA.js";
1
+ export { t as TemplateCategoriesView } from "../../../chunks/categories-f7E-RJEc.js";
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-Bb5bUVFd.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/compose-BKUTsB2W.cjs");exports.EMPTY_COMPOSE_FORM_SCHEMA=e.n,exports.EMPTY_COMPOSE_FORM_UI_SCHEMA=e.r,exports.TemplateComposeWizardView=e.t,exports.useTemplateComposeWizard=e.i;
@@ -1 +1 @@
1
- export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-egQlRjuZ.js";
1
+ export { n as EMPTY_COMPOSE_FORM_SCHEMA, r as EMPTY_COMPOSE_FORM_UI_SCHEMA, t as TemplateComposeWizardView, i as useTemplateComposeWizard } from "../../../chunks/compose-DZvIspW3.js";
@@ -12,6 +12,8 @@ export interface NotifyWebhookTargetsEditorProps {
12
12
  readonly onChange: (targets: readonly NotifyWebhookTarget[]) => void;
13
13
  readonly targets: readonly NotifyWebhookTarget[];
14
14
  }
15
+ /** Shown in place of the editor when the catalog has no usable endpoint. */
16
+ export declare const NOTIFY_WEBHOOK_NO_ENDPOINTS_MESSAGE = "\u76EE\u524D\u6C92\u6709\u53EF\u7528\u7684 Webhook \u7AEF\u9EDE\uFF0C\u8ACB\u6D3D BPM \u7BA1\u7406\u8005\u6216\u7CFB\u7D71\u6574\u5408\u4EBA\u54E1\u65B0\u589E\u7AEF\u9EDE\u5F8C\u518D\u8A2D\u5B9A\u3002";
15
17
  /**
16
18
  * Edits a NOTIFY node's webhook targets (ADR 18 §3.3). Parameters come from
17
19
  * the endpoint catalog, so the author only picks an endpoint and binds each
@@ -12,6 +12,8 @@ export interface NotifyWebhookTargetsEditorProps {
12
12
  readonly onChange: (targets: readonly NotifyWebhookTarget[]) => void;
13
13
  readonly targets: readonly NotifyWebhookTarget[];
14
14
  }
15
+ /** Shown in place of the editor when the catalog has no usable endpoint. */
16
+ export declare const NOTIFY_WEBHOOK_NO_ENDPOINTS_MESSAGE = "\u76EE\u524D\u6C92\u6709\u53EF\u7528\u7684 Webhook \u7AEF\u9EDE\uFF0C\u8ACB\u6D3D BPM \u7BA1\u7406\u8005\u6216\u7CFB\u7D71\u6574\u5408\u4EBA\u54E1\u65B0\u589E\u7AEF\u9EDE\u5F8C\u518D\u8A2D\u5B9A\u3002";
15
17
  /**
16
18
  * Edits a NOTIFY node's webhook targets (ADR 18 §3.3). Parameters come from
17
19
  * the endpoint catalog, so the author only picks an endpoint and binds each
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/designer-CX9bhYJS.cjs");exports.TemplateDesignerView=e.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/designer-C_m8DmMl.cjs");exports.TemplateDesignerView=e.t;
@@ -1 +1 @@
1
- export { t as TemplateDesignerView } from "../../../chunks/designer-CZDlQ9Nf.js";
1
+ export { t as TemplateDesignerView } from "../../../chunks/designer-CWubIE69.js";
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/categories-DQUtVEiV.cjs"),n=require("../../chunks/format-date-time-D-cx5M8z.cjs"),r=require("../../chunks/router-adapter--gYs13E8.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("./versions/index.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/core/form"),d=require("@mezzanine-ui/react/ContentHeader");d=e.t(d,1);let f=require("@mezzanine-ui/icons"),p=require("@rytass/bpm-core-client/template");var m=[10,20,50],h=[{key:`ALL`,label:`全部`},{key:`PUBLISHED`,label:`已發布`},{key:`DRAFT`,label:`草稿`}],g=100;function _(){let e=r.r(),a=i.r(),[_,O]=(0,o.useState)([]),[k,A]=(0,o.useState)(C),[j,M]=(0,o.useState)([]),[N,P]=(0,o.useState)(new Set),[F,I]=(0,o.useState)(null),[L,R]=(0,o.useState)(!0),[z,B]=(0,o.useState)(1),[V,H]=(0,o.useState)(10),[U,W]=(0,o.useState)(``),[G,K]=(0,o.useState)(`ALL`),[q,J]=(0,o.useState)(0),[Y,X]=(0,o.useState)(null),Z=(0,o.useRef)(0),Q=(0,o.useCallback)(async()=>{let e=Z.current+1;Z.current=e,R(!0),I(null),P(new Set),(0,l.listLaunchableTemplates)().then(t=>{e===Z.current&&P(new Set(t.map(e=>e.id)))}).catch(()=>{e===Z.current&&P(new Set)});try{let[t,n]=await Promise.all([(0,p.listApprovalTemplatesPage)({categoryId:k.categoryId,page:z,pageSize:V,searchText:U,status:G===`ALL`?null:G}),(0,p.listApprovalTemplateCategoriesPage)({page:1,pageSize:g,searchText:``,status:`ACTIVE`})]);if(e!==Z.current)return;M([...n.categories.map(w)]),O(t.templates),J(t.totalCount)}catch(t){e===Z.current&&I(v(t))}finally{e===Z.current&&R(!1)}},[k,z,V,U,G]);(0,o.useEffect)(()=>{Q()},[Q]);let $=(0,o.useCallback)(async e=>{X(e.id),I(null);try{await(e.isActive?(0,p.deactivateApprovalTemplate)(e.id):(0,p.activateApprovalTemplate)(e.id)),await Q()}catch(e){I(v(e))}finally{X(null)}},[Q]),ee=(0,o.useMemo)(()=>_.map(e=>({...e,categoryLabel:D(e),key:e.id,status:e.currentVersionId?`PUBLISHED`:`DRAFT`,updatedAt:n.t(e.updatedAt)})),[_]),te=(0,o.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:220},{key:`status`,render:e=>(0,c.jsx)(b,{status:e.status}),title:`狀態`,width:120},{key:`isActive`,render:e=>(0,c.jsx)(x,{isActive:e.isActive}),title:`服務狀態`,width:120},{key:`category`,render:e=>(0,c.jsx)(S,{record:e}),title:`分類`,width:160},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),ne=(0,o.useMemo)(()=>({render:t=>[{disabled:e=>!N.has(e.id),name:`發起`,onClick:()=>e.push(a.caseNew(t.id)),variant:`base-primary`},{name:`設計`,onClick:()=>e.push(a.templateDesigner(t.id))},{name:`版本`,onClick:()=>e.push(a.templateVersions(t.id))},{disabled:e=>Y===e.id,name:t.isActive?`停用`:`啟用`,onClick:e=>{$(e)},variant:t.isActive?`destructive-secondary`:`base-secondary`}],variant:`base-secondary`,width:264}),[Y,N,e,$]);return(0,c.jsx)(c.Fragment,{children:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(d.default,{description:`建立流程模板、維護草稿與發布版本。`,title:`簽核模板`,children:(0,c.jsx)(s.Button,{icon:f.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.templateCompose()),variant:`base-primary`,children:`建立模板`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{filterArea:(0,c.jsx)(s.FilterArea,{className:t.n.templateFilterArea,size:`sub`,children:(0,c.jsxs)(s.FilterLine,{children:[(0,c.jsx)(s.Filter,{span:3,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:u.FormFieldLayout.VERTICAL,name:`templateSearchText`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>{W(e.target.value),B(1)},placeholder:`關鍵字:搜尋模板名稱、分類或描述`,size:`sub`,value:U,variant:`base`})})}),(0,c.jsx)(s.Filter,{span:2,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:u.FormFieldLayout.VERTICAL,name:`templateCategoryFilter`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{A(T(e,j)),B(1)},options:[C,...j],placeholder:`分類`,renderValue:e=>`分類:${E(e)}`,size:`sub`,value:k})})})]})}),tab:(0,c.jsx)(s.Tab,{activeKey:G,onChange:e=>{K(y(e)),B(1)},children:h.map(e=>(0,c.jsx)(s.TabItem,{children:e.label},e.key))}),children:[F?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:F}):null,(0,c.jsx)(s.Table,{actions:ne,columns:te,dataSource:ee,fullWidth:!0,loading:L,pagination:{current:z,onChange:e=>{B(e)},onChangePageSize:e=>{B(1),H(e)},pageSize:V,pageSizeLabel:`每頁筆數`,pageSizeOptions:m,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:q}})]})})]})})}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}function y(e){return e===`PUBLISHED`||e===`DRAFT`?e:`ALL`}function b({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-inactive`})}function x({isActive:e}){return e?(0,c.jsx)(s.Badge,{size:`sub`,text:`啟用中`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`已停用`,variant:`dot-inactive`})}function S({record:e}){return e.categoryDetail?.isActive===!1?(0,c.jsx)(s.Badge,{size:`sub`,text:`${e.categoryLabel}(停用)`,variant:`dot-inactive`}):(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.categoryLabel})}var C={categoryId:null,id:`ALL_CATEGORIES`,name:`全部分類`};function w(e){return{categoryId:e.id,id:e.id,name:e.name}}function T(e,t){if(!O(e))return C;let n=typeof e.id==`string`?e.id:null;return n===C.id?C:t.find(e=>e.id===n)??C}function E(e){return Array.isArray(e)||!O(e)?C.name:typeof e.name==`string`?e.name:C.name}function D(e){return e.categoryDetail?.name??e.category??`未分類`}function O(e){return typeof e==`object`&&!!e}exports.TemplateCategoriesView=t.t,exports.TemplateVersionsView=a.TemplateVersionsView,exports.TemplatesView=_;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/categories-CyyqG6wG.cjs"),n=require("../../chunks/format-date-time-D-cx5M8z.cjs"),r=require("../../chunks/router-adapter--gYs13E8.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("./versions/index.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/core/form"),d=require("@mezzanine-ui/react/ContentHeader");d=e.t(d,1);let f=require("@rytass/bpm-core-client/template"),p=require("@mezzanine-ui/icons");var m=[10,20,50],h=[{key:`ALL`,label:`全部`},{key:`PUBLISHED`,label:`已發布`},{key:`DRAFT`,label:`草稿`}],g=100;function _(){let e=r.r(),a=i.r(),[_,O]=(0,o.useState)([]),[k,A]=(0,o.useState)(C),[j,M]=(0,o.useState)([]),[N,P]=(0,o.useState)(new Set),[F,I]=(0,o.useState)(null),[L,R]=(0,o.useState)(!0),[z,B]=(0,o.useState)(1),[V,H]=(0,o.useState)(10),[U,W]=(0,o.useState)(``),[G,K]=(0,o.useState)(`ALL`),[q,J]=(0,o.useState)(0),[Y,X]=(0,o.useState)(null),Z=(0,o.useRef)(0),Q=(0,o.useCallback)(async()=>{let e=Z.current+1;Z.current=e,R(!0),I(null),P(new Set),(0,l.listLaunchableTemplates)().then(t=>{e===Z.current&&P(new Set(t.map(e=>e.id)))}).catch(()=>{e===Z.current&&P(new Set)});try{let[t,n]=await Promise.all([(0,f.listApprovalTemplatesPage)({categoryId:k.categoryId,page:z,pageSize:V,searchText:U,status:G===`ALL`?null:G}),(0,f.listApprovalTemplateCategoriesPage)({page:1,pageSize:g,searchText:``,status:`ACTIVE`})]);if(e!==Z.current)return;M([...n.categories.map(w)]),O(t.templates),J(t.totalCount)}catch(t){e===Z.current&&I(v(t))}finally{e===Z.current&&R(!1)}},[k,z,V,U,G]);(0,o.useEffect)(()=>{Q()},[Q]);let $=(0,o.useCallback)(async e=>{X(e.id),I(null);try{await(e.isActive?(0,f.deactivateApprovalTemplate)(e.id):(0,f.activateApprovalTemplate)(e.id)),await Q()}catch(e){I(v(e))}finally{X(null)}},[Q]),ee=(0,o.useMemo)(()=>_.map(e=>({...e,categoryLabel:D(e),key:e.id,status:e.currentVersionId?`PUBLISHED`:`DRAFT`,updatedAt:n.t(e.updatedAt)})),[_]),te=(0,o.useMemo)(()=>[{dataIndex:`name`,key:`name`,title:`模板名稱`,width:220},{key:`status`,render:e=>(0,c.jsx)(b,{status:e.status}),title:`狀態`,width:120},{key:`isActive`,render:e=>(0,c.jsx)(x,{isActive:e.isActive}),title:`服務狀態`,width:120},{key:`category`,render:e=>(0,c.jsx)(S,{record:e}),title:`分類`,width:160},{dataIndex:`updatedAt`,key:`updatedAt`,title:`更新時間`,width:220}],[]),ne=(0,o.useMemo)(()=>({render:t=>[{disabled:e=>!N.has(e.id),name:`發起`,onClick:()=>e.push(a.caseNew(t.id)),variant:`base-primary`},{name:`設計`,onClick:()=>e.push(a.templateDesigner(t.id))},{name:`版本`,onClick:()=>e.push(a.templateVersions(t.id))},{disabled:e=>Y===e.id,name:t.isActive?`停用`:`啟用`,onClick:e=>{$(e)},variant:t.isActive?`destructive-secondary`:`base-secondary`}],variant:`base-secondary`,width:264}),[Y,N,e,$]);return(0,c.jsx)(c.Fragment,{children:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(d.default,{description:`建立流程模板、維護草稿與發布版本。`,title:`簽核模板`,children:(0,c.jsx)(s.Button,{icon:p.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.templateCompose()),variant:`base-primary`,children:`建立模板`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{filterArea:(0,c.jsx)(s.FilterArea,{className:t.n.templateFilterArea,size:`sub`,children:(0,c.jsxs)(s.FilterLine,{children:[(0,c.jsx)(s.Filter,{span:3,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:u.FormFieldLayout.VERTICAL,name:`templateSearchText`,children:(0,c.jsx)(s.Input,{fullWidth:!0,onChange:e=>{W(e.target.value),B(1)},placeholder:`關鍵字:搜尋模板名稱、分類或描述`,size:`sub`,value:U,variant:`base`})})}),(0,c.jsx)(s.Filter,{span:2,children:(0,c.jsx)(s.FormField,{fullWidth:!0,layout:u.FormFieldLayout.VERTICAL,name:`templateCategoryFilter`,children:(0,c.jsx)(s.Select,{clearable:!1,fullWidth:!0,onChange:e=>{A(T(e,j)),B(1)},options:[C,...j],placeholder:`分類`,renderValue:e=>`分類:${E(e)}`,size:`sub`,value:k})})})]})}),tab:(0,c.jsx)(s.Tab,{activeKey:G,onChange:e=>{K(y(e)),B(1)},children:h.map(e=>(0,c.jsx)(s.TabItem,{children:e.label},e.key))}),children:[F?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:F}):null,(0,c.jsx)(s.Table,{actions:ne,columns:te,dataSource:ee,fullWidth:!0,loading:L,pagination:{current:z,onChange:e=>{B(e)},onChangePageSize:e=>{B(1),H(e)},pageSize:V,pageSizeLabel:`每頁筆數`,pageSizeOptions:m,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:q}})]})})]})})}function v(e){return e instanceof Error?e.message:`發生未知錯誤`}function y(e){return e===`PUBLISHED`||e===`DRAFT`?e:`ALL`}function b({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-inactive`})}function x({isActive:e}){return e?(0,c.jsx)(s.Badge,{size:`sub`,text:`啟用中`,variant:`dot-success`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`已停用`,variant:`dot-inactive`})}function S({record:e}){return e.categoryDetail?.isActive===!1?(0,c.jsx)(s.Badge,{size:`sub`,text:`${e.categoryLabel}(停用)`,variant:`dot-inactive`}):(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.categoryLabel})}var C={categoryId:null,id:`ALL_CATEGORIES`,name:`全部分類`};function w(e){return{categoryId:e.id,id:e.id,name:e.name}}function T(e,t){if(!O(e))return C;let n=typeof e.id==`string`?e.id:null;return n===C.id?C:t.find(e=>e.id===n)??C}function E(e){return Array.isArray(e)||!O(e)?C.name:typeof e.name==`string`?e.name:C.name}function D(e){return e.categoryDetail?.name??e.category??`未分類`}function O(e){return typeof e==`object`&&!!e}exports.TemplateCategoriesView=t.t,exports.TemplateVersionsView=a.TemplateVersionsView,exports.TemplatesView=_;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useState","useRef","useCallback","listLaunchableTemplates","listApprovalTemplatesPage","listApprovalTemplateCategoriesPage","deactivateApprovalTemplate","activateApprovalTemplate","useMemo","formatDateTime","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Select","Tab","TabItem","Typography","Table","Badge","require_rolldown_runtime","require_categories","require_format_date_time","require_router_adapter","require_routes_config","require_views_templates_versions_index","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","TEMPLATE_PAGE_SIZE_OPTIONS","TEMPLATE_STATUS_TABS","TEMPLATE_CATEGORY_PAGE_SIZE","TemplatesView","router","routes","templates","setTemplates","categoryFilter","setCategoryFilter","UNCATEGORIZED_TEMPLATE_FILTER_OPTION","categoryOptions","setCategoryOptions","launchableTemplateIds","setLaunchableTemplateIds","error","setError","loading","setLoading","templatePage","setTemplatePage","templatePageSize","setTemplatePageSize","templateSearchText","setTemplateSearchText","templateStatus","setTemplateStatus","templateTotalCount","setTemplateTotalCount","activationPendingTemplateId","setActivationPendingTemplateId","refreshRequestIdRef","refreshTemplates","requestId","nextLaunchableTemplates","template","templatePageResult","activeCategoryPageResult","readCategoryOption","requestError","readErrorMessage","toggleTemplateActivation","rows","readTemplateCategoryLabel","columns","TemplateStatusBadge","record","TemplateActivationBadge","TemplateCategoryLabel","tableActions","event","readCategoryFilterOption","option","readTemplateCategoryFilterLabel","value","readTemplateStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","status","isActive","category","isRecord","id","options"],"sources":["../../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n activateApprovalTemplate,\n deactivateApprovalTemplate,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n const [activationPendingTemplateId, setActivationPendingTemplateId] =\n useState<string | null>(null);\n const refreshRequestIdRef = useRef(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n setLaunchableTemplateIds(new Set());\n\n void listLaunchableTemplates()\n .then((nextLaunchableTemplates): void => {\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n })\n .catch((): void => {\n if (requestId === refreshRequestIdRef.current) {\n setLaunchableTemplateIds(new Set());\n }\n });\n\n try {\n const [templatePageResult, activeCategoryPageResult] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n } catch (requestError: unknown) {\n if (requestId === refreshRequestIdRef.current) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (requestId === refreshRequestIdRef.current) {\n setLoading(false);\n }\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const toggleTemplateActivation = useCallback(\n async (template: ApprovalTemplateRecord): Promise<void> => {\n setActivationPendingTemplateId(template.id);\n setError(null);\n\n try {\n await (template.isActive\n ? deactivateApprovalTemplate(template.id)\n : activateApprovalTemplate(template.id));\n await refreshTemplates();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setActivationPendingTemplateId(null);\n }\n },\n [refreshTemplates],\n );\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'isActive',\n render: (record: TemplateRow): ReactElement => (\n <TemplateActivationBadge isActive={record.isActive} />\n ),\n title: '服務狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void => router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n {\n disabled: (template): boolean =>\n activationPendingTemplateId === template.id,\n name: record.isActive ? '停用' : '啟用',\n onClick: (template): void => {\n void toggleTemplateActivation(template);\n },\n variant: record.isActive ? 'destructive-secondary' : 'base-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 264,\n }),\n [\n activationPendingTemplateId,\n launchableTemplateIds,\n router,\n toggleTemplateActivation,\n ],\n );\n\n return (\n <>\n <>\n <PageHeader>\n <ContentHeader\n description=\"建立流程模板、維護草稿與發布版本。\"\n title=\"簽核模板\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.templateCompose())}\n variant=\"base-primary\"\n >\n 建立模板\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateActivationBadge({\n isActive,\n}: {\n readonly isActive: boolean;\n}): ReactElement {\n if (isActive) {\n return <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"A,4rBAwCA,IAAM8C,EAA6B,CAAC,GAAI,GAAI,EAAE,EACxCC,EAGA,CACJ,CAAE,IAAK,MAAO,MAAO,IAAK,EAC1B,CAAE,IAAK,YAAa,MAAO,KAAM,EACjC,CAAE,IAAK,QAAS,MAAO,IAAK,CAC9B,EAEMC,EAA8B,IAmBpC,SAAgBC,GAA8B,CAC5C,IAAMC,EAASlD,EAAAA,EAAiB,EAC1BmD,EAASlD,EAAAA,EAAa,EACtB,CAACmD,EAAWC,IAAA,EAAgBnD,EAAAA,SAAAA,CAChC,CAAC,CACH,EACM,CAACoD,EAAgBC,IAAA,EAAqBrD,EAAAA,SAAAA,CAC1CsD,CACF,EACM,CAACC,EAAiBC,IAAA,EAAsBxD,EAAAA,SAAAA,CAE5C,CAAC,CAAC,EACE,CAACyD,EAAuBC,IAAA,EAA4B1D,EAAAA,SAAAA,CAExD,IAAI,GAAK,EACL,CAAC2D,EAAOC,IAAA,EAAY5D,EAAAA,SAAAA,CAAwB,IAAI,EAChD,CAAC6D,EAASC,IAAA,EAAc9D,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAAC+D,EAAcC,IAAA,EAAmBhE,EAAAA,SAAAA,CAAS,CAAC,EAC5C,CAACiE,EAAkBC,IAAA,EAAuBlE,EAAAA,SAAAA,CAAS,EAAE,EACrD,CAACmE,EAAoBC,IAAA,EAAyBpE,EAAAA,SAAAA,CAAS,EAAE,EACzD,CAACqE,EAAgBC,IAAA,EACrBtE,EAAAA,SAAAA,CAA+B,KAAK,EAChC,CAACuE,EAAoBC,IAAA,EAAyBxE,EAAAA,SAAAA,CAAS,CAAC,EACxD,CAACyE,EAA6BC,IAAA,EAClC1E,EAAAA,SAAAA,CAAwB,IAAI,EACxB2E,GAAA,EAAsB1E,EAAAA,OAAAA,CAAO,CAAC,EAE9B2E,GAAA,EAAmB1E,EAAAA,YAAAA,CAAY,SAA2B,CAC9D,IAAM2E,EAAYF,EAAoB,QAAU,EAChD,EAAoB,QAAUE,EAC9Bf,EAAW,EAAI,EACfF,EAAS,IAAI,EACbF,EAAyB,IAAI,GAAK,GAElC,EAAKvD,EAAAA,wBAAAA,CAAwB,CAAC,CAC3B,KAAM,GAAkC,CACnC0E,IAAcF,EAAoB,SAItCjB,EACE,IAAI,IAAIoB,EAAwB,IAAK,GAAaC,EAAS,EAAE,CAAC,CAChE,CACF,CAAC,CAAC,CACD,UAAkB,CACbF,IAAcF,EAAoB,SACpCjB,EAAyB,IAAI,GAAK,CAEtC,CAAC,EAEH,GAAI,CACF,GAAM,CAACsB,EAAoBC,GAA4B,MAAM,QAAQ,IAAI,EAAA,EACvE7E,EAAAA,0BAAAA,CAA0B,CACxB,WAAYgD,EAAe,WAC3B,KAAMW,EACN,SAAUE,EACV,WAAYE,EACZ,OAAQE,IAAmB,MAAQ,KAAOA,CAC5C,CAAC,GAAA,EACDhE,EAAAA,mCAAAA,CAAmC,CACjC,KAAM,EACN,SAAUyC,EACV,WAAY,GACZ,OAAQ,QACV,CAAC,CACH,CAAC,EAED,GAAI+B,IAAcF,EAAoB,QACpC,OAGFnB,EAAmB,CACjB,GAAGyB,EAAyB,WAAW,IAAIC,CAAkB,CAC/D,CAAC,EACD/B,EAAa6B,EAAmB,SAAS,EACzCR,EAAsBQ,EAAmB,UAAU,CACrD,OAASG,EAAuB,CAC1BN,IAAcF,EAAoB,SACpCf,EAASwB,EAAiBD,CAAY,CAAC,CAE3C,QAAU,CACJN,IAAcF,EAAoB,SACpCb,EAAW,EAAK,CAEpB,CACF,EAAG,CACDV,EACAW,EACAE,EACAE,EACAE,CACF,CAAC,GAED,EAAAjC,EAAA,UAAA,KAAsB,CACpBwC,EAAsB,CACxB,EAAG,CAACA,CAAgB,CAAC,EAErB,IAAMS,GAAA,EAA2BnF,EAAAA,YAAAA,CAC/B,KAAO,IAAoD,CACzDwE,EAA+BK,EAAS,EAAE,EAC1CnB,EAAS,IAAI,EAEb,GAAI,CACF,MAAOmB,EAAS,UAAA,EACZzE,EAAAA,2BAAAA,CAA2ByE,EAAS,EAAE,GAAA,EACtCxE,EAAAA,yBAAAA,CAAyBwE,EAAS,EAAE,GACxC,MAAMH,EAAiB,CACzB,OAASO,EAAuB,CAC9BvB,EAASwB,EAAiBD,CAAY,CAAC,CACzC,QAAU,CACRT,EAA+B,IAAI,CACrC,CACF,EACA,CAACE,CAAgB,CACnB,EAEMU,IAAA,EAAO9E,EAAAA,QAAAA,KAET0C,EAAU,IAAK,IAAc,CAC3B,GAAG6B,EACH,cAAeQ,EAA0BR,CAAQ,EACjD,IAAKA,EAAS,GACd,OAAQA,EAAS,iBAAmB,YAAc,QAClD,UAAWtE,EAAAA,EAAesE,EAAS,SAAS,CAC9C,EAAE,EACJ,CAAC7B,CAAS,CACZ,EACMsC,IAAA,EAAUhF,EAAAA,QAAAA,KACoB,CAChC,CAAE,UAAW,OAAQ,IAAK,OAAQ,MAAO,OAAQ,MAAO,GAAI,EAC5D,CACE,IAAK,SACL,OAAS,IACP,EAAA8B,EAAA,IAAA,CAACmD,EAAD,CAAqB,OAAQC,EAAO,MAAS,CAAA,EAE/C,MAAO,KACP,MAAO,GACT,EACA,CACE,IAAK,WACL,OAAS,IACP,EAAApD,EAAA,IAAA,CAACqD,EAAD,CAAyB,SAAUD,EAAO,QAAW,CAAA,EAEvD,MAAO,OACP,MAAO,GACT,EACA,CACE,IAAK,WACL,OAAS,IACP,EAAApD,EAAA,IAAA,CAACsD,EAAD,CAA+B,QAAS,CAAA,EAE1C,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,YACX,IAAK,YACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACMC,IAAA,EAAerF,EAAAA,QAAAA,MACe,CAChC,OAAS,GAA4D,CACnE,CACE,SAAW,GACT,CAACiD,EAAsB,IAAIsB,EAAS,EAAE,EACxC,KAAM,KACN,YAAqB/B,EAAO,KAAKC,EAAO,QAAQyC,EAAO,EAAE,CAAC,EAC1D,QAAS,cACX,EACA,CACE,KAAM,KACN,YAAqB1C,EAAO,KAAKC,EAAO,iBAAiByC,EAAO,EAAE,CAAC,CACrE,EACA,CACE,KAAM,KACN,YAAqB1C,EAAO,KAAKC,EAAO,iBAAiByC,EAAO,EAAE,CAAC,CACrE,EACA,CACE,SAAW,GACTjB,IAAgCM,EAAS,GAC3C,KAAMW,EAAO,SAAW,KAAO,KAC/B,QAAU,GAAmB,CAC3BL,EAA8BN,CAAQ,CACxC,EACA,QAASW,EAAO,SAAW,wBAA0B,gBACvD,CACF,EACA,QAAS,iBACT,MAAO,GACT,GACA,CACEjB,EACAhB,EACAT,EACAqC,CACF,CACF,EAEA,OACE,EAAA/C,EAAA,IAAA,CAAA5B,EAAAA,SAAA,CAAA,UACE,EAAA4B,EAAA,KAAA,CAAA5B,EAAAA,SAAA,CAAA,SAAA,EACE,EAAA4B,EAAA,IAAA,CAAC3B,EAAAA,WAAD,CAAA,UACE,EAAA2B,EAAA,IAAA,CAAC1B,EAAAA,QAAD,CACE,YAAY,oBACZ,MAAM,OAEN,UAAA,EAAA0B,EAAA,IAAA,CAACzB,EAAAA,OAAD,CACE,KAAMC,EAAAA,SACN,SAAS,UACT,YAAqBkC,EAAO,KAAKC,EAAO,gBAAgB,CAAC,EACzD,QAAQ,eACT,SAAA,MAEO,CAAA,CACK,CAAA,CACL,CAAA,GAEZ,EAAAX,EAAA,IAAA,CAACvB,EAAAA,aAAD,CAAA,UACE,EAAAuB,EAAA,KAAA,CAACtB,EAAAA,QAAD,CACE,YACE,EAAAsB,EAAA,IAAA,CAACrB,EAAAA,WAAD,CAAY,UAAWC,EAAAA,EAAO,mBAAoB,KAAK,MACrD,UAAA,EAAAoB,EAAA,KAAA,CAACnB,EAAAA,WAAD,CAAA,SAAA,EACE,EAAAmB,EAAA,IAAA,CAAClB,EAAAA,OAAD,CAAQ,KAAM,EACZ,UAAA,EAAAkB,EAAA,IAAA,CAACjB,EAAAA,UAAD,CACE,UAAA,GACA,OAAQC,EAAAA,gBAAgB,SACxB,KAAK,qBAEL,UAAA,EAAAgB,EAAA,IAAA,CAACf,EAAAA,MAAD,CACE,UAAA,GACA,SACE,GACS,CACT6C,EAAsB0B,EAAM,OAAO,KAAK,EACxC9B,EAAgB,CAAC,CACnB,EACA,YAAY,mBACZ,KAAK,MACL,MAAOG,EACP,QAAQ,MACT,CAAA,CACQ,CAAA,CACL,CAAA,GACR,EAAA7B,EAAA,IAAA,CAAClB,EAAAA,OAAD,CAAQ,KAAM,EACZ,UAAA,EAAAkB,EAAA,IAAA,CAACjB,EAAAA,UAAD,CACE,UAAA,GACA,OAAQC,EAAAA,gBAAgB,SACxB,KAAK,yBAEL,UAAA,EAAAgB,EAAA,IAAA,CAACd,EAAAA,OAAD,CACE,UAAW,GACX,UAAA,GACA,SAAW,GAAiB,CAC1B6B,EACE0C,EAAyBC,EAAQzC,CAAe,CAClD,EACAS,EAAgB,CAAC,CACnB,EACA,QAAS,CACPV,EACA,GAAGC,CACL,EACA,YAAY,KACZ,YAAc,GACZ,MAAM0C,EAAgCC,CAAK,IAE7C,KAAK,MACL,MAAO9C,CACR,CAAA,CACQ,CAAA,CACL,CAAA,CACE,CAAA,CAAA,CACF,CAAA,EAEd,KACE,EAAAd,EAAA,IAAA,CAACb,EAAAA,IAAD,CACE,UAAW4C,EACX,SAAW,GAAoB,CAC7BC,EAAkB6B,EAAyBC,CAAS,CAAC,EACrDpC,EAAgB,CAAC,CACnB,EAEC,SAAAnB,EAAqB,IAAK,IACzB,EAAAP,EAAA,IAAA,CAACZ,EAAAA,QAAD,CAAA,SAA8B2E,EAAU,KAAe,EAAzCA,EAAU,GAA+B,CACxD,CACE,CAAA,EAnET,SAAA,CAsEG1C,GACC,EAAArB,EAAA,IAAA,CAACX,EAAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,OACpC,SAAAgC,CACS,CAAA,EACV,MACJ,EAAArB,EAAA,IAAA,CAACV,EAAAA,MAAD,CACE,QAASiE,GACA,WACT,WAAYP,GACZ,UAAA,GACS,UACT,WAAY,CACV,QAASvB,EACT,SAAW,GAAe,CACxBC,EAAgBsC,CAAI,CACtB,EACA,iBAAmB,GAAmB,CACpCtC,EAAgB,CAAC,EACjBE,EAAoBqC,CAAQ,CAC9B,EACA,SAAUtC,EACV,cAAe,OACf,gBAAiBrB,EACjB,qBAAsB,EAAM,EAAI,IAC9B,MAAM4D,EAAK,GAAGC,EAAG,OAAOC,EAAM,IAChC,oBAAqB,GACrB,MAAOnC,CACT,CACD,CAAA,CACM,CACG,CAAA,CAAA,CAAA,CACd,CAAA,CAAA,CACF,CAAA,CAEN,CAEA,SAASa,EAAiB,EAAwB,CAChD,OAAOzB,aAAiB,MAAQA,EAAM,QAAU,QAClD,CAEA,SAASwC,EAAyB,EAAsC,CAKtE,OAJIC,IAAc,aAAeA,IAAc,QACtCA,EAGF,KACT,CAEA,SAASX,EAAoB,CAC3B,UAGe,CAKf,OAJIkB,IAAW,aACN,EAAArE,EAAA,IAAA,CAACT,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,aAAe,CAAA,GAGtD,EAAAS,EAAA,IAAA,CAACT,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,cAAgB,CAAA,CAC7D,CAEA,SAAS8D,EAAwB,CAC/B,YAGe,CAKf,OAJIiB,GACK,EAAAtE,EAAA,IAAA,CAACT,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,aAAe,CAAA,GAGtD,EAAAS,EAAA,IAAA,CAACT,EAAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,cAAgB,CAAA,CAC9D,CAEA,SAAS+D,EAAsB,CAC7B,UAGe,CAWf,OAVIF,EAAO,gBAAgB,WAAa,IAEpC,EAAApD,EAAA,IAAA,CAACT,EAAAA,MAAD,CACE,KAAK,MACL,KAAM,GAAG6D,EAAO,cAAc,MAC9B,QAAQ,cACT,CAAA,GAKH,EAAApD,EAAA,IAAA,CAACX,EAAAA,WAAD,CAAY,UAAU,OAAO,QAAQ,OAClC,SAAA+D,EAAO,aACE,CAAA,CAEhB,CAEA,IAAMpC,EAA+D,CACnE,WAAY,KACZ,GAAI,iBACJ,KAAM,MACR,EAEA,SAAS4B,EACP,EACwB,CACxB,MAAO,CACL,WAAY2B,EAAS,GACrB,GAAIA,EAAS,GACb,KAAMA,EAAS,IACjB,CACF,CAEA,SAASd,EACP,EACA,EACwB,CACxB,GAAI,CAACe,EAASZ,CAAK,EACjB,OAAO5C,EAGT,IAAMyD,EAAK,OAAOb,EAAM,IAAO,SAAWA,EAAM,GAAK,KAMrD,OAJIa,IAAOzD,EAAqC,GACvCA,EAIP0D,EAAQ,KAAM,GAAWhB,EAAO,KAAOe,CAAE,GACzCzD,CAEJ,CAEA,SAAS2C,EAAgC,EAAwB,CAS/D,OARI,MAAM,QAAQC,CAAK,GAInB,CAACY,EAASZ,CAAK,EACV5C,EAAqC,KAGvC,OAAO4C,EAAM,MAAS,SACzBA,EAAM,KACN5C,EAAqC,IAC3C,CAEA,SAASiC,EAA0B,EAA0C,CAC3E,OAAOR,EAAS,gBAAgB,MAAQA,EAAS,UAAY,KAC/D,CAEA,SAAS+B,EAAS,EAA4D,CAC5E,OAAO,OAAOZ,GAAU,YAAYA,CACtC,C"}
1
+ {"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useState","useRef","useCallback","listLaunchableTemplates","listApprovalTemplatesPage","listApprovalTemplateCategoriesPage","deactivateApprovalTemplate","activateApprovalTemplate","useMemo","formatDateTime","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Select","Tab","TabItem","Typography","Table","Badge","require_rolldown_runtime","require_categories","require_format_date_time","require_router_adapter","require_routes_config","require_views_templates_versions_index","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_rytass_bpm_core_client_template","_mezzanine_ui_icons","TEMPLATE_PAGE_SIZE_OPTIONS","TEMPLATE_STATUS_TABS","TEMPLATE_CATEGORY_PAGE_SIZE","TemplatesView","router","routes","templates","setTemplates","categoryFilter","setCategoryFilter","UNCATEGORIZED_TEMPLATE_FILTER_OPTION","categoryOptions","setCategoryOptions","launchableTemplateIds","setLaunchableTemplateIds","error","setError","loading","setLoading","templatePage","setTemplatePage","templatePageSize","setTemplatePageSize","templateSearchText","setTemplateSearchText","templateStatus","setTemplateStatus","templateTotalCount","setTemplateTotalCount","activationPendingTemplateId","setActivationPendingTemplateId","refreshRequestIdRef","refreshTemplates","requestId","nextLaunchableTemplates","template","templatePageResult","activeCategoryPageResult","readCategoryOption","requestError","readErrorMessage","toggleTemplateActivation","rows","readTemplateCategoryLabel","columns","TemplateStatusBadge","record","TemplateActivationBadge","TemplateCategoryLabel","tableActions","event","readCategoryFilterOption","option","readTemplateCategoryFilterLabel","value","readTemplateStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","status","isActive","category","isRecord","id","options"],"sources":["../../../src/views/templates/TemplatesView.tsx"],"sourcesContent":["'use client';\n\nimport type { ChangeEvent, Key, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Badge,\n Button,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport styles from './templates.module.scss';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\nimport {\n ApprovalTemplateListStatus,\n ApprovalTemplateRecord,\n ApprovalTemplateCategoryRecord,\n activateApprovalTemplate,\n deactivateApprovalTemplate,\n listApprovalTemplateCategoriesPage,\n listApprovalTemplatesPage,\n} from '@rytass/bpm-core-client/template';\nimport { listLaunchableTemplates } from '@rytass/bpm-core-client/workflow';\n\nconst TEMPLATE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst TEMPLATE_STATUS_TABS: readonly {\n readonly key: TemplateStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'PUBLISHED', label: '已發布' },\n { key: 'DRAFT', label: '草稿' },\n];\n\nconst TEMPLATE_CATEGORY_PAGE_SIZE = 100;\n\nexport interface TemplateCategoryOption {\n readonly categoryId: string | null;\n readonly id: string;\n readonly name: string;\n}\n\ntype TemplateStatusTabKey = 'ALL' | ApprovalTemplateListStatus;\n\ntype TemplateRow = Readonly<\n Record<string, unknown> &\n ApprovalTemplateRecord & {\n categoryLabel: string;\n key: string;\n status: ApprovalTemplateListStatus;\n }\n>;\n\nexport function TemplatesView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [templates, setTemplates] = useState<readonly ApprovalTemplateRecord[]>(\n [],\n );\n const [categoryFilter, setCategoryFilter] = useState<TemplateCategoryOption>(\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n );\n const [categoryOptions, setCategoryOptions] = useState<\n readonly TemplateCategoryOption[]\n >([]);\n const [launchableTemplateIds, setLaunchableTemplateIds] = useState<\n ReadonlySet<string>\n >(new Set());\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [templatePage, setTemplatePage] = useState(1);\n const [templatePageSize, setTemplatePageSize] = useState(10);\n const [templateSearchText, setTemplateSearchText] = useState('');\n const [templateStatus, setTemplateStatus] =\n useState<TemplateStatusTabKey>('ALL');\n const [templateTotalCount, setTemplateTotalCount] = useState(0);\n const [activationPendingTemplateId, setActivationPendingTemplateId] =\n useState<string | null>(null);\n const refreshRequestIdRef = useRef(0);\n\n const refreshTemplates = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n setLaunchableTemplateIds(new Set());\n\n void listLaunchableTemplates()\n .then((nextLaunchableTemplates): void => {\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setLaunchableTemplateIds(\n new Set(nextLaunchableTemplates.map((template) => template.id)),\n );\n })\n .catch((): void => {\n if (requestId === refreshRequestIdRef.current) {\n setLaunchableTemplateIds(new Set());\n }\n });\n\n try {\n const [templatePageResult, activeCategoryPageResult] = await Promise.all([\n listApprovalTemplatesPage({\n categoryId: categoryFilter.categoryId,\n page: templatePage,\n pageSize: templatePageSize,\n searchText: templateSearchText,\n status: templateStatus === 'ALL' ? null : templateStatus,\n }),\n listApprovalTemplateCategoriesPage({\n page: 1,\n pageSize: TEMPLATE_CATEGORY_PAGE_SIZE,\n searchText: '',\n status: 'ACTIVE',\n }),\n ]);\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setCategoryOptions([\n ...activeCategoryPageResult.categories.map(readCategoryOption),\n ]);\n setTemplates(templatePageResult.templates);\n setTemplateTotalCount(templatePageResult.totalCount);\n } catch (requestError: unknown) {\n if (requestId === refreshRequestIdRef.current) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (requestId === refreshRequestIdRef.current) {\n setLoading(false);\n }\n }\n }, [\n categoryFilter,\n templatePage,\n templatePageSize,\n templateSearchText,\n templateStatus,\n ]);\n\n useEffect((): void => {\n void refreshTemplates();\n }, [refreshTemplates]);\n\n const toggleTemplateActivation = useCallback(\n async (template: ApprovalTemplateRecord): Promise<void> => {\n setActivationPendingTemplateId(template.id);\n setError(null);\n\n try {\n await (template.isActive\n ? deactivateApprovalTemplate(template.id)\n : activateApprovalTemplate(template.id));\n await refreshTemplates();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setActivationPendingTemplateId(null);\n }\n },\n [refreshTemplates],\n );\n\n const rows = useMemo(\n (): TemplateRow[] =>\n templates.map((template) => ({\n ...template,\n categoryLabel: readTemplateCategoryLabel(template),\n key: template.id,\n status: template.currentVersionId ? 'PUBLISHED' : 'DRAFT',\n updatedAt: formatDateTime(template.updatedAt),\n })),\n [templates],\n );\n const columns = useMemo(\n (): TableColumn<TemplateRow>[] => [\n { dataIndex: 'name', key: 'name', title: '模板名稱', width: 220 },\n {\n key: 'status',\n render: (record: TemplateRow): ReactElement => (\n <TemplateStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'isActive',\n render: (record: TemplateRow): ReactElement => (\n <TemplateActivationBadge isActive={record.isActive} />\n ),\n title: '服務狀態',\n width: 120,\n },\n {\n key: 'category',\n render: (record: TemplateRow): ReactElement => (\n <TemplateCategoryLabel record={record} />\n ),\n title: '分類',\n width: 160,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '更新時間',\n width: 220,\n },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<TemplateRow> => ({\n render: (record): ReturnType<TableActions<TemplateRow>['render']> => [\n {\n disabled: (template): boolean =>\n !launchableTemplateIds.has(template.id),\n name: '發起',\n onClick: (): void => router.push(routes.caseNew(record.id)),\n variant: 'base-primary',\n },\n {\n name: '設計',\n onClick: (): void => router.push(routes.templateDesigner(record.id)),\n },\n {\n name: '版本',\n onClick: (): void => router.push(routes.templateVersions(record.id)),\n },\n {\n disabled: (template): boolean =>\n activationPendingTemplateId === template.id,\n name: record.isActive ? '停用' : '啟用',\n onClick: (template): void => {\n void toggleTemplateActivation(template);\n },\n variant: record.isActive ? 'destructive-secondary' : 'base-secondary',\n },\n ],\n variant: 'base-secondary',\n width: 264,\n }),\n [\n activationPendingTemplateId,\n launchableTemplateIds,\n router,\n toggleTemplateActivation,\n ],\n );\n\n return (\n <>\n <>\n <PageHeader>\n <ContentHeader\n description=\"建立流程模板、維護草稿與發布版本。\"\n title=\"簽核模板\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.templateCompose())}\n variant=\"base-primary\"\n >\n 建立模板\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.templateFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setTemplateSearchText(event.target.value);\n setTemplatePage(1);\n }}\n placeholder=\"關鍵字:搜尋模板名稱、分類或描述\"\n size=\"sub\"\n value={templateSearchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"templateCategoryFilter\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setCategoryFilter(\n readCategoryFilterOption(option, categoryOptions),\n );\n setTemplatePage(1);\n }}\n options={[\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION,\n ...categoryOptions,\n ]}\n placeholder=\"分類\"\n renderValue={(value): string =>\n `分類:${readTemplateCategoryFilterLabel(value)}`\n }\n size=\"sub\"\n value={categoryFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={templateStatus}\n onChange={(activeKey): void => {\n setTemplateStatus(readTemplateStatusTabKey(activeKey));\n setTemplatePage(1);\n }}\n >\n {TEMPLATE_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: templatePage,\n onChange: (page): void => {\n setTemplatePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setTemplatePage(1);\n setTemplatePageSize(pageSize);\n },\n pageSize: templatePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: TEMPLATE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: templateTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n </>\n );\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n\nfunction readTemplateStatusTabKey(activeKey: Key): TemplateStatusTabKey {\n if (activeKey === 'PUBLISHED' || activeKey === 'DRAFT') {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction TemplateStatusBadge({\n status,\n}: {\n readonly status: ApprovalTemplateListStatus;\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateActivationBadge({\n isActive,\n}: {\n readonly isActive: boolean;\n}): ReactElement {\n if (isActive) {\n return <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />;\n }\n\n return <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />;\n}\n\nfunction TemplateCategoryLabel({\n record,\n}: {\n readonly record: TemplateRow;\n}): ReactElement {\n if (record.categoryDetail?.isActive === false) {\n return (\n <Badge\n size=\"sub\"\n text={`${record.categoryLabel}(停用)`}\n variant=\"dot-inactive\"\n />\n );\n }\n\n return (\n <Typography component=\"span\" variant=\"body\">\n {record.categoryLabel}\n </Typography>\n );\n}\n\nconst UNCATEGORIZED_TEMPLATE_FILTER_OPTION: TemplateCategoryOption = {\n categoryId: null,\n id: 'ALL_CATEGORIES',\n name: '全部分類',\n};\n\nfunction readCategoryOption(\n category: ApprovalTemplateCategoryRecord,\n): TemplateCategoryOption {\n return {\n categoryId: category.id,\n id: category.id,\n name: category.name,\n };\n}\n\nfunction readCategoryFilterOption(\n value: unknown,\n options: readonly TemplateCategoryOption[],\n): TemplateCategoryOption {\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n const id = typeof value.id === 'string' ? value.id : null;\n\n if (id === UNCATEGORIZED_TEMPLATE_FILTER_OPTION.id) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION;\n }\n\n return (\n options.find((option) => option.id === id) ??\n UNCATEGORIZED_TEMPLATE_FILTER_OPTION\n );\n}\n\nfunction readTemplateCategoryFilterLabel(value: unknown): string {\n if (Array.isArray(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n if (!isRecord(value)) {\n return UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n }\n\n return typeof value.name === 'string'\n ? value.name\n : UNCATEGORIZED_TEMPLATE_FILTER_OPTION.name;\n}\n\nfunction readTemplateCategoryLabel(template: ApprovalTemplateRecord): string {\n return template.categoryDetail?.name ?? template.category ?? '未分類';\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === 'object' && value !== null;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { n as e, t } from "../../chunks/categories-BAdxjNSA.js";
2
+ import { n as e, t } from "../../chunks/categories-f7E-RJEc.js";
3
3
  import { t as n } from "../../chunks/format-date-time-B0LdmWg4.js";
4
4
  import { r as ee } from "../../chunks/router-adapter-CkxCyzf5.js";
5
5
  import { r as te } from "../../chunks/routes-config-BcNaWJWJ.js";
@@ -10,8 +10,8 @@ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
10
10
  import { listLaunchableTemplates as le } from "@rytass/bpm-core-client/workflow";
11
11
  import { FormFieldLayout as b } from "@mezzanine-ui/core/form";
12
12
  import ue from "@mezzanine-ui/react/ContentHeader";
13
- import { PlusIcon as de } from "@mezzanine-ui/icons";
14
- import { activateApprovalTemplate as fe, deactivateApprovalTemplate as pe, listApprovalTemplateCategoriesPage as me, listApprovalTemplatesPage as he } from "@rytass/bpm-core-client/template";
13
+ import { activateApprovalTemplate as de, deactivateApprovalTemplate as fe, listApprovalTemplateCategoriesPage as pe, listApprovalTemplatesPage as me } from "@rytass/bpm-core-client/template";
14
+ import { PlusIcon as he } from "@mezzanine-ui/icons";
15
15
  // src/views/templates/TemplatesView.tsx
16
16
  var x = [
17
17
  10,
@@ -40,13 +40,13 @@ function w() {
40
40
  e === Z.current && B(/* @__PURE__ */ new Set());
41
41
  });
42
42
  try {
43
- let [t, n] = await Promise.all([he({
43
+ let [t, n] = await Promise.all([me({
44
44
  categoryId: F.categoryId,
45
45
  page: W,
46
46
  pageSize: K,
47
47
  searchText: q,
48
48
  status: J === "ALL" ? null : J
49
- }), me({
49
+ }), pe({
50
50
  page: 1,
51
51
  pageSize: C,
52
52
  searchText: "",
@@ -72,7 +72,7 @@ function w() {
72
72
  let $ = i(async (e) => {
73
73
  X(e.id), H(null);
74
74
  try {
75
- await (e.isActive ? pe(e.id) : fe(e.id)), await Q();
75
+ await (e.isActive ? fe(e.id) : de(e.id)), await Q();
76
76
  } catch (e) {
77
77
  H(T(e));
78
78
  } finally {
@@ -152,7 +152,7 @@ function w() {
152
152
  description: "建立流程模板、維護草稿與發布版本。",
153
153
  title: "簽核模板",
154
154
  children: /* @__PURE__ */ v(re, {
155
- icon: de,
155
+ icon: he,
156
156
  iconType: "leading",
157
157
  onClick: () => t.push(r.templateCompose()),
158
158
  variant: "base-primary",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rytass/bpm-core-react",
3
- "version": "0.20.1",
3
+ "version": "0.21.0",
4
4
  "description": "BPM approval workflow React components and views for the Rytass BPM stack. Ships AuthProvider, NotificationDrawer + bell widget, host-facing hooks (useBPMMember / useBPMLogout / useBPMRoutes), and full page-body views for inbox / instances / templates / forms / admin / settings on top of Mezzanine UI and the BPM client functions. The host owns the navigation shell — BPM does not bundle a layout.",
5
5
  "keywords": [
6
6
  "bpm",
@@ -536,8 +536,8 @@
536
536
  "@mezzanine-ui/core": ">=1.0.0",
537
537
  "@mezzanine-ui/icons": ">=1.0.0",
538
538
  "@mezzanine-ui/react": ">=1.0.0",
539
- "@rytass/bpm-core-client": "^0.20.1",
540
- "@rytass/bpm-core-shared": "^0.20.1",
539
+ "@rytass/bpm-core-client": "^0.21.0",
540
+ "@rytass/bpm-core-shared": "^0.21.0",
541
541
  "@uiw/react-codemirror": ">=4.0.0",
542
542
  "@xyflow/react": ">=12.0.0",
543
543
  "ai": ">=6.0.0",