@rytass/bpm-core-react 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/chunks/{FormBuilderView-BVKY1j_0.js → FormBuilderView-Djlm3y4S.js} +485 -481
- package/dist/chunks/FormBuilderView-Djlm3y4S.js.map +1 -0
- package/dist/chunks/FormBuilderView-G6uRSywl.cjs +3 -0
- package/dist/chunks/FormBuilderView-G6uRSywl.cjs.map +1 -0
- package/dist/chunks/{FormRendererView-BsTwZkqU.js → FormRendererView-DHfVgbo6.js} +511 -274
- package/dist/chunks/FormRendererView-DHfVgbo6.js.map +1 -0
- package/dist/chunks/FormRendererView-DwfFbaip.cjs +6 -0
- package/dist/chunks/FormRendererView-DwfFbaip.cjs.map +1 -0
- package/dist/chunks/admin-pickers-BjbkBpSJ.cjs +2 -0
- package/dist/chunks/admin-pickers-BjbkBpSJ.cjs.map +1 -0
- package/dist/chunks/{admin-pickers-Djq3h-UR.js → admin-pickers-DfGxsjpp.js} +42 -42
- package/dist/chunks/admin-pickers-DfGxsjpp.js.map +1 -0
- package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js → approval-instance-list-page-BnI4t5mD.js} +7 -8
- package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js.map → approval-instance-list-page-BnI4t5mD.js.map} +1 -1
- package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs → approval-instance-list-page-fqvmkBlg.cjs} +2 -2
- package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs.map → approval-instance-list-page-fqvmkBlg.cjs.map} +1 -1
- package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -1
- package/dist/chunks/{auth-provider-B5oPmvk2.js → auth-provider-C2b-5mGt.js} +2 -3
- package/dist/chunks/{auth-provider-B5oPmvk2.js.map → auth-provider-C2b-5mGt.js.map} +1 -1
- package/dist/chunks/{bpm-form-field-Cao0rMol.js → bpm-form-field-9B-Det0u.js} +2 -3
- package/dist/chunks/{bpm-form-field-Cao0rMol.js.map → bpm-form-field-9B-Det0u.js.map} +1 -1
- package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -1
- package/dist/chunks/{categories-riC33J_j.js → categories-BAdxjNSA.js} +14 -15
- package/dist/chunks/{categories-riC33J_j.js.map → categories-BAdxjNSA.js.map} +1 -1
- package/dist/chunks/{categories-AxxhqjLZ.cjs → categories-DQUtVEiV.cjs} +2 -2
- package/dist/chunks/{categories-AxxhqjLZ.cjs.map → categories-DQUtVEiV.cjs.map} +1 -1
- package/dist/chunks/{compose-B1GlrZW9.js → compose-D6zBIc2Z.js} +131 -148
- package/dist/chunks/compose-D6zBIc2Z.js.map +1 -0
- package/dist/chunks/compose-NH6dsFXD.cjs +2 -0
- package/dist/chunks/compose-NH6dsFXD.cjs.map +1 -0
- package/dist/chunks/{dashboard-page-DdBvV6YI.js → dashboard-page-BoqNhjT_.js} +5 -6
- package/dist/chunks/{dashboard-page-DdBvV6YI.js.map → dashboard-page-BoqNhjT_.js.map} +1 -1
- package/dist/chunks/{dashboard-page-BWQBSGDq.cjs → dashboard-page-D7YJ3udk.cjs} +2 -2
- package/dist/chunks/{dashboard-page-BWQBSGDq.cjs.map → dashboard-page-D7YJ3udk.cjs.map} +1 -1
- package/dist/chunks/{delegations-MxF3uJGW.js → delegations-BfhCDz5e.js} +15 -16
- package/dist/chunks/{delegations-MxF3uJGW.js.map → delegations-BfhCDz5e.js.map} +1 -1
- package/dist/chunks/{delegations-Ckf03icM.cjs → delegations-BmFGcuhA.cjs} +2 -2
- package/dist/chunks/{delegations-Ckf03icM.cjs.map → delegations-BmFGcuhA.cjs.map} +1 -1
- package/dist/chunks/{delegations-V9HIe3_P.cjs → delegations-CcS0SHbf.cjs} +2 -2
- package/dist/chunks/{delegations-V9HIe3_P.cjs.map → delegations-CcS0SHbf.cjs.map} +1 -1
- package/dist/chunks/{delegations-xUt1tj8d.js → delegations-DBh5TT6G.js} +16 -17
- package/dist/chunks/{delegations-xUt1tj8d.js.map → delegations-DBh5TT6G.js.map} +1 -1
- package/dist/chunks/designer-Be9UI9Tg.cjs +65 -0
- package/dist/chunks/designer-Be9UI9Tg.cjs.map +1 -0
- package/dist/chunks/{designer-BCLrjb4H.js → designer-uhC_7m2i.js} +1791 -1407
- package/dist/chunks/designer-uhC_7m2i.js.map +1 -0
- package/dist/chunks/detail-6uw5dmTi.cjs +5 -0
- package/dist/chunks/detail-6uw5dmTi.cjs.map +1 -0
- package/dist/chunks/{detail-4F39ggBn.js → detail-_GeKqNC-.js} +1012 -972
- package/dist/chunks/detail-_GeKqNC-.js.map +1 -0
- package/dist/chunks/{format-date-time-CB-LxzqT.js → format-date-time-B0LdmWg4.js} +2 -3
- package/dist/chunks/{format-date-time-CB-LxzqT.js.map → format-date-time-B0LdmWg4.js.map} +1 -1
- package/dist/chunks/format-date-time-D-cx5M8z.cjs.map +1 -1
- package/dist/chunks/{format-member-label-DudVI55w.js → format-member-label-C73FuP-d.js} +2 -3
- package/dist/chunks/{format-member-label-DudVI55w.js.map → format-member-label-C73FuP-d.js.map} +1 -1
- package/dist/chunks/format-member-label-t7ANTF62.cjs.map +1 -1
- package/dist/chunks/{approver-filled-form-Dm3Iw7iw.cjs → instance-error-message-DTARGbGo.cjs} +2 -2
- package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +1 -0
- package/dist/chunks/{approver-filled-form-ZEwpmsHJ.js → instance-error-message-q6gy5evy.js} +50 -38
- package/dist/chunks/instance-error-message-q6gy5evy.js.map +1 -0
- package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +1 -1
- package/dist/chunks/{language-provider-B3cEbLe4.js → language-provider-phkWOapf.js} +2 -3
- package/dist/chunks/{language-provider-B3cEbLe4.js.map → language-provider-phkWOapf.js.map} +1 -1
- package/dist/chunks/{login-C6qlTC6F.js → login-D6cc3bo7.js} +4 -5
- package/dist/chunks/{login-C6qlTC6F.js.map → login-D6cc3bo7.js.map} +1 -1
- package/dist/chunks/{login-AtVxZBsC.cjs → login-uvVcltrS.cjs} +2 -2
- package/dist/chunks/{login-AtVxZBsC.cjs.map → login-uvVcltrS.cjs.map} +1 -1
- package/dist/chunks/notifications-Bc4mgSds.cjs.map +1 -1
- package/dist/chunks/{notifications-DJ5wzCye.js → notifications-Cvme5Qbl.js} +2 -3
- package/dist/chunks/{notifications-DJ5wzCye.js.map → notifications-Cvme5Qbl.js.map} +1 -1
- package/dist/chunks/orgs-B_2J2tLX.cjs +2 -0
- package/dist/chunks/{orgs-BeeDDWL1.cjs.map → orgs-B_2J2tLX.cjs.map} +1 -1
- package/dist/chunks/{orgs-8hje_l2n.js → orgs-DqxMds26.js} +48 -49
- package/dist/chunks/{orgs-8hje_l2n.js.map → orgs-DqxMds26.js.map} +1 -1
- package/dist/chunks/{providers-B_d5tbCL.js → providers-BbCs23sk.js} +21 -25
- package/dist/chunks/{providers-B_d5tbCL.js.map → providers-BbCs23sk.js.map} +1 -1
- package/dist/chunks/{providers-chuJvMgv.cjs → providers-D_KAgOOu.cjs} +2 -2
- package/dist/chunks/{providers-chuJvMgv.cjs.map → providers-D_KAgOOu.cjs.map} +1 -1
- package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -1
- package/dist/chunks/{router-adapter-DftlFTOd.js → router-adapter-CkxCyzf5.js} +2 -3
- package/dist/chunks/{router-adapter-DftlFTOd.js.map → router-adapter-CkxCyzf5.js.map} +1 -1
- package/dist/chunks/{routes-config-yZbESPlw.js → routes-config-BcNaWJWJ.js} +2 -3
- package/dist/chunks/{routes-config-yZbESPlw.js.map → routes-config-BcNaWJWJ.js.map} +1 -1
- package/dist/chunks/routes-config-C1j_vFKo.cjs.map +1 -1
- package/dist/chunks/task-decision-3d17ZvZE.js +29 -0
- package/dist/chunks/task-decision-3d17ZvZE.js.map +1 -0
- package/dist/chunks/task-decision-CqZ4WQOC.cjs +2 -0
- package/dist/chunks/task-decision-CqZ4WQOC.cjs.map +1 -0
- package/dist/chunks/{use-bpm-member-D57LKe_u.js → use-bpm-member-BPzcNU1g.js} +3 -4
- package/dist/chunks/{use-bpm-member-D57LKe_u.js.map → use-bpm-member-BPzcNU1g.js.map} +1 -1
- package/dist/chunks/use-bpm-member-DpNAQtNC.cjs.map +1 -1
- package/dist/chunks/{users-Pl6hY5Y5.js → users-BBtiZ9QQ.js} +22 -25
- package/dist/chunks/{users-Pl6hY5Y5.js.map → users-BBtiZ9QQ.js.map} +1 -1
- package/dist/chunks/{users-O2L_M3BK.cjs → users-EqSzDhuj.cjs} +2 -2
- package/dist/chunks/{users-O2L_M3BK.cjs.map → users-EqSzDhuj.cjs.map} +1 -1
- package/dist/components/admin-picker-options.d.cts +11 -0
- package/dist/components/admin-picker-options.d.ts +11 -0
- package/dist/components/admin-pickers.d.cts +2 -11
- package/dist/components/admin-pickers.d.ts +2 -11
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +17 -19
- package/dist/index.js.map +1 -1
- package/dist/lib/task-decision.d.cts +16 -0
- package/dist/lib/task-decision.d.ts +16 -0
- package/dist/lib/use-org-unit-names.d.cts +10 -0
- package/dist/lib/use-org-unit-names.d.ts +10 -0
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +7 -8
- package/dist/next/index.js.map +1 -1
- package/dist/next/workflow-chat-route.cjs +19 -1
- package/dist/next/workflow-chat-route.cjs.map +1 -1
- package/dist/next/workflow-chat-route.js +2 -3
- package/dist/next/workflow-chat-route.js.map +1 -1
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.cjs.map +1 -1
- package/dist/pages/admin/delegations/index.js +2 -3
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.cjs.map +1 -1
- package/dist/pages/admin/orgs/index.js +2 -3
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/index.cjs.map +1 -1
- package/dist/pages/admin/users/index.js +2 -3
- package/dist/pages/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/pages/admin/webhook-endpoints/index.js +1 -2
- package/dist/pages/cc/index.cjs.map +1 -1
- package/dist/pages/cc/index.js +1 -2
- package/dist/pages/dashboard/index.cjs.map +1 -1
- package/dist/pages/dashboard/index.js +1 -2
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.cjs.map +1 -1
- package/dist/pages/delegations/index.js +2 -3
- package/dist/pages/inbox/index.cjs.map +1 -1
- package/dist/pages/inbox/index.js +1 -2
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.cjs.map +1 -1
- package/dist/pages/instances/detail/index.js +2 -3
- package/dist/pages/instances/new/index.cjs.map +1 -1
- package/dist/pages/instances/new/index.js +1 -2
- package/dist/pages/login/index.cjs +1 -1
- package/dist/pages/login/index.cjs.map +1 -1
- package/dist/pages/login/index.js +2 -3
- package/dist/pages/root/index.cjs.map +1 -1
- package/dist/pages/root/index.js +1 -2
- package/dist/pages/search/index.cjs.map +1 -1
- package/dist/pages/search/index.js +1 -2
- package/dist/pages/sent/index.cjs.map +1 -1
- package/dist/pages/sent/index.js +1 -2
- package/dist/pages/settings/notifications/index.cjs.map +1 -1
- package/dist/pages/settings/notifications/index.js +2 -3
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.cjs.map +1 -1
- package/dist/pages/templates/categories/index.js +2 -3
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.cjs.map +1 -1
- package/dist/pages/templates/compose/index.js +2 -3
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.cjs.map +1 -1
- package/dist/pages/templates/designer/index.js +2 -3
- package/dist/pages/templates/index.cjs.map +1 -1
- package/dist/pages/templates/index.js +1 -2
- package/dist/pages/templates/versions/index.cjs.map +1 -1
- package/dist/pages/templates/versions/index.js +1 -2
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +3 -3
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/views/admin/webhook-endpoints/index.js +52 -53
- package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.cjs.map +1 -1
- package/dist/views/cc/index.js +2 -3
- package/dist/views/dashboard/index.cjs +1 -1
- package/dist/views/dashboard/index.cjs.map +1 -1
- package/dist/views/dashboard/index.js +2 -3
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/FormRendererView.d.cts +24 -1
- package/dist/views/forms/renderer/FormRendererView.d.ts +24 -1
- package/dist/views/forms/renderer/file-upload-field.d.cts +84 -0
- package/dist/views/forms/renderer/file-upload-field.d.ts +84 -0
- package/dist/views/forms/renderer/form-value-readers.d.cts +7 -0
- package/dist/views/forms/renderer/form-value-readers.d.ts +7 -0
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.d.cts +1 -0
- package/dist/views/forms/renderer/index.d.ts +1 -0
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/forms/renderer/org-unit-field-options.d.cts +44 -0
- package/dist/views/forms/renderer/org-unit-field-options.d.ts +44 -0
- package/dist/views/forms/renderer/org-unit-field.d.cts +23 -0
- package/dist/views/forms/renderer/org-unit-field.d.ts +23 -0
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +133 -137
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/approver-filled-form.d.cts +9 -2
- package/dist/views/instances/approver-filled-form.d.ts +9 -2
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +19 -2
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +19 -2
- package/dist/views/instances/detail/sections/InstanceHistorySection.d.cts +8 -1
- package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +8 -1
- package/dist/views/instances/detail/sections/container-helpers.d.cts +0 -1
- package/dist/views/instances/detail/sections/container-helpers.d.ts +0 -1
- package/dist/views/instances/detail/sections/shared.d.cts +3 -4
- package/dist/views/instances/detail/sections/shared.d.ts +3 -4
- package/dist/views/instances/instance-error-message.d.cts +5 -0
- package/dist/views/instances/instance-error-message.d.ts +5 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +78 -77
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/login/index.cjs +1 -1
- package/dist/views/login/index.js +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.cjs.map +1 -1
- package/dist/views/search/index.js +2 -3
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.cjs.map +1 -1
- package/dist/views/sent/index.js +2 -3
- package/dist/views/settings/index.js +1 -1
- package/dist/views/settings/notifications/index.js +1 -1
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/approver-resolver-model.d.cts +211 -0
- package/dist/views/templates/designer/approver-resolver-model.d.ts +211 -0
- package/dist/views/templates/designer/dry-run-assignee-label.d.cts +2 -0
- package/dist/views/templates/designer/dry-run-assignee-label.d.ts +2 -0
- package/dist/views/templates/designer/dry-run-sample-data.d.cts +6 -0
- package/dist/views/templates/designer/dry-run-sample-data.d.ts +6 -0
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +25 -0
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +25 -0
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.cts +38 -0
- package/dist/views/templates/designer/node-actor-resolver-options.d.ts +38 -0
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.cjs.map +1 -1
- package/dist/views/templates/index.js +50 -51
- package/dist/views/templates/index.js.map +1 -1
- package/dist/views/templates/versions/index.cjs +1 -1
- package/dist/views/templates/versions/index.cjs.map +1 -1
- package/dist/views/templates/versions/index.js +7 -8
- package/dist/views/templates/versions/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunks/FormBuilderView-BVKY1j_0.js.map +0 -1
- package/dist/chunks/FormBuilderView-SrGltzFT.cjs +0 -3
- package/dist/chunks/FormBuilderView-SrGltzFT.cjs.map +0 -1
- package/dist/chunks/FormRendererView-BsTwZkqU.js.map +0 -1
- package/dist/chunks/FormRendererView-GpsE03np.cjs +0 -4
- package/dist/chunks/FormRendererView-GpsE03np.cjs.map +0 -1
- package/dist/chunks/admin-pickers-BRHk3qKq.cjs +0 -2
- package/dist/chunks/admin-pickers-BRHk3qKq.cjs.map +0 -1
- package/dist/chunks/admin-pickers-Djq3h-UR.js.map +0 -1
- package/dist/chunks/approver-filled-form-Dm3Iw7iw.cjs.map +0 -1
- package/dist/chunks/approver-filled-form-ZEwpmsHJ.js.map +0 -1
- package/dist/chunks/compose-B1GlrZW9.js.map +0 -1
- package/dist/chunks/compose-DZk-SfHT.cjs +0 -2
- package/dist/chunks/compose-DZk-SfHT.cjs.map +0 -1
- package/dist/chunks/designer-BCLrjb4H.js.map +0 -1
- package/dist/chunks/designer-BYYxEN9L.cjs +0 -65
- package/dist/chunks/designer-BYYxEN9L.cjs.map +0 -1
- package/dist/chunks/detail-4F39ggBn.js.map +0 -1
- package/dist/chunks/detail-BkMtA_0K.cjs +0 -2
- package/dist/chunks/detail-BkMtA_0K.cjs.map +0 -1
- package/dist/chunks/orgs-BeeDDWL1.cjs +0 -2
- package/dist/chunks/task-node-label-BF6UllxP.cjs +0 -2
- package/dist/chunks/task-node-label-BF6UllxP.cjs.map +0 -1
- package/dist/chunks/task-node-label-CWZgOBj0.js +0 -9
- package/dist/chunks/task-node-label-CWZgOBj0.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-pickers-DfGxsjpp.js","names":["styles","formatMemberLabel","readOrgUnitOption","orgUnit","readPositionOption","position","admin_pickers_module_default","PICKER_MENU_MAX_HEIGHT","MemberPicker","loading","setLoading","useState","options","setOptions","value","handleSearch","searchMembers","searchText","readMemberOption","AutoComplete","onChange","readMemberOptionFromValue","option","readUniqueOption","open","mergeMemberOptions","OrgUnitPicker","useMemo","orgUnits","Select","readOrgUnitOptionFromValue","PositionPicker","positions","readPositionOptionFromValue","member","isRecord","email","id","name","normalized","matched","selected"],"sources":["../../src/components/admin-picker-options.ts","../../src/components/admin-pickers.module.scss","../../src/components/admin-pickers.tsx"],"sourcesContent":["import type {\n OrgUnitRecord,\n PositionRecord,\n} from '@rytass/bpm-core-client/organization';\n\nexport type OrgUnitOption = Readonly<{\n id: string;\n name: string;\n}>;\n\nexport type PositionOption = Readonly<{\n id: string;\n name: string;\n}>;\n\nexport function readOrgUnitOption(orgUnit: OrgUnitRecord): OrgUnitOption {\n return { id: orgUnit.id, name: `${orgUnit.name} · ${orgUnit.code}` };\n}\n\nexport function readPositionOption(position: PositionRecord): PositionOption {\n return { id: position.id, name: `${position.name} · ${position.code}` };\n}\n",".pickerHost {\n width: 100%;\n min-width: 0;\n\n :global(.mzn-auto-complete),\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n}\n","'use client';\n\nimport { useMemo, useState, type ReactElement } from 'react';\nimport { AutoComplete, Select } from '@mezzanine-ui/react';\nimport { searchMembers } from '@rytass/bpm-core-client';\nimport type {\n OrgUnitRecord,\n PositionRecord,\n} from '@rytass/bpm-core-client/organization';\nimport { formatMemberLabel } from '../lib/format-member-label';\nimport {\n type OrgUnitOption,\n type PositionOption,\n readOrgUnitOption,\n readPositionOption,\n} from './admin-picker-options';\nimport styles from './admin-pickers.module.scss';\n\nexport {\n type OrgUnitOption,\n type PositionOption,\n readOrgUnitOption,\n readPositionOption,\n};\n\nexport type MemberOption = Readonly<{\n email: string;\n id: string;\n name: string;\n}>;\n\n// Without a cap the Mezzanine dropdown grows with its options and never\n// mounts its scrollbar, so a long org-unit or position list runs off the\n// viewport with no way to reach the items below the fold. The pickers also\n// set `flip`: near the bottom of a modal the capped menu still overflows\n// unless it may open upwards.\nconst PICKER_MENU_MAX_HEIGHT = 320;\n\ninterface MemberPickerProps {\n readonly disabled?: boolean;\n readonly name: string;\n readonly onChange: (option: MemberOption | null) => void;\n readonly placeholder?: string;\n readonly size?: 'main' | 'sub';\n readonly value: MemberOption | null;\n}\n\ninterface OrgUnitPickerProps {\n readonly disabled?: boolean;\n readonly name: string;\n readonly onChange: (option: OrgUnitOption | null) => void;\n readonly orgUnits: readonly OrgUnitRecord[];\n readonly placeholder?: string;\n readonly size?: 'main' | 'sub';\n readonly value: OrgUnitOption | null;\n}\n\ninterface PositionPickerProps {\n readonly disabled?: boolean;\n readonly name: string;\n readonly onChange: (option: PositionOption | null) => void;\n readonly placeholder?: string;\n readonly positions: readonly PositionRecord[];\n readonly size?: 'main' | 'sub';\n readonly value: PositionOption | null;\n}\n\n/**\n * AutoComplete-backed picker that searches the BPM member directory via\n * `searchMembers()`. Emits a {@link MemberOption} `{ id, name, email }`\n * on selection (or `null` when cleared).\n */\nexport function MemberPicker({\n disabled = false,\n name,\n onChange,\n placeholder = '搜尋姓名或信箱',\n size,\n value,\n}: MemberPickerProps): ReactElement {\n const [loading, setLoading] = useState(false);\n const [options, setOptions] = useState<readonly MemberOption[]>(\n value ? [value] : [],\n );\n\n async function handleSearch(searchText: string): Promise<void> {\n setLoading(true);\n try {\n setOptions((await searchMembers(searchText)).map(readMemberOption));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <div className={styles.pickerHost}>\n <AutoComplete\n asyncData\n disabled={disabled}\n disabledOptionsFilter\n emptyText=\"沒有符合的會員\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name,\n spellCheck: false,\n }}\n loading={loading}\n loadingText=\"搜尋會員中...\"\n mode=\"single\"\n onChange={(option): void => onChange(readMemberOptionFromValue(option))}\n onSearch={handleSearch}\n onSearchTextChange={(searchText): void =>\n onChange(readUniqueOption(searchText, options))\n }\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearch('');\n }\n }}\n options={[...mergeMemberOptions(value ? [value] : [], options)]}\n placeholder={placeholder}\n searchDebounceTime={300}\n size={size}\n value={value}\n />\n </div>\n );\n}\n\n/**\n * Static `<Select>` over a pre-fetched list of org units. Caller is\n * responsible for fetching the org units (typically via\n * `readOrganizationDashboard` from `@rytass/bpm-core-client/organization`).\n */\nexport function OrgUnitPicker({\n disabled = false,\n onChange,\n orgUnits,\n placeholder = '選擇組織',\n size,\n value,\n}: OrgUnitPickerProps): ReactElement {\n const options = useMemo(\n (): readonly OrgUnitOption[] => orgUnits.map(readOrgUnitOption),\n [orgUnits],\n );\n return (\n <div className={styles.pickerHost}>\n <Select\n clearable\n disabled={disabled}\n flip\n fullWidth\n menuMaxHeight={PICKER_MENU_MAX_HEIGHT}\n onChange={(option): void => onChange(readOrgUnitOptionFromValue(option))}\n options={[...options]}\n placeholder={placeholder}\n size={size}\n value={value}\n />\n </div>\n );\n}\n\n/**\n * Static `<Select>` over a pre-fetched list of positions.\n */\nexport function PositionPicker({\n disabled = false,\n onChange,\n placeholder = '選擇職位',\n positions,\n size,\n value,\n}: PositionPickerProps): ReactElement {\n const options = useMemo(\n (): readonly PositionOption[] => positions.map(readPositionOption),\n [positions],\n );\n return (\n <div className={styles.pickerHost}>\n <Select\n clearable\n disabled={disabled}\n flip\n fullWidth\n menuMaxHeight={PICKER_MENU_MAX_HEIGHT}\n onChange={(option): void => onChange(readPositionOptionFromValue(option))}\n options={[...options]}\n placeholder={placeholder}\n size={size}\n value={value}\n />\n </div>\n );\n}\n\nexport function readMemberOption(member: {\n readonly email: string;\n readonly memberId: string;\n readonly name: string;\n}): MemberOption {\n return {\n email: member.email,\n id: member.memberId,\n name: formatMemberLabel(member.name, member.email, 'dot'),\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) return null;\n const email = value.email;\n const id = value.id;\n const name = value.name;\n return typeof email === 'string' &&\n typeof id === 'string' &&\n typeof name === 'string'\n ? { email, id, name }\n : null;\n}\n\nfunction readOrgUnitOptionFromValue(value: unknown): OrgUnitOption | null {\n if (!isRecord(value)) return null;\n const id = value.id;\n const name = value.name;\n return typeof id === 'string' && typeof name === 'string'\n ? { id, name }\n : null;\n}\n\nfunction readPositionOptionFromValue(value: unknown): PositionOption | null {\n if (!isRecord(value)) return null;\n const id = value.id;\n const name = value.name;\n return typeof id === 'string' && typeof name === 'string'\n ? { id, name }\n : null;\n}\n\nfunction readUniqueOption(\n searchText: string,\n options: readonly MemberOption[],\n): MemberOption | null {\n const normalized = searchText.trim().toLocaleLowerCase();\n if (!normalized) return null;\n const matched = options.filter(\n (option) =>\n option.id.toLocaleLowerCase() === normalized ||\n option.email.toLocaleLowerCase() === normalized ||\n option.name.toLocaleLowerCase() === normalized,\n );\n return matched.length === 1 ? matched[0] : null;\n}\n\nfunction mergeMemberOptions(\n selected: readonly MemberOption[],\n options: readonly MemberOption[],\n): readonly MemberOption[] {\n const byId = new Map(\n [...selected, ...options].map(\n (option): readonly [string, MemberOption] => [option.id, option],\n ),\n );\n return [...byId.values()];\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,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { r as e } from "./router-adapter-
|
|
3
|
-
import { t } from "./
|
|
4
|
-
import {
|
|
2
|
+
import { r as e } from "./router-adapter-CkxCyzf5.js";
|
|
3
|
+
import { r as t } from "./routes-config-BcNaWJWJ.js";
|
|
4
|
+
import { t as n } from "./format-date-time-B0LdmWg4.js";
|
|
5
5
|
import { useCallback as r, useEffect as i, useMemo as a, useRef as o, useState as s } from "react";
|
|
6
6
|
import { Filter as c, FilterArea as ee, FilterLine as te, FormField as l, Input as u, PageHeader as d, Section as ne, SectionGroup as f, Select as p, Table as m, Typography as h } from "@mezzanine-ui/react";
|
|
7
7
|
import { resolveMembers as re } from "@rytass/bpm-core-client";
|
|
@@ -56,7 +56,7 @@ import '../approval-instance-list-page.css';var S = { instanceFilterArea: "bpm_i
|
|
|
56
56
|
}
|
|
57
57
|
];
|
|
58
58
|
function T({ defaultState: y, description: T, emptyMessage: O, searchPlaceholder: k, title: N, view: P }) {
|
|
59
|
-
let F = e(), I =
|
|
59
|
+
let F = e(), I = t(), [L, R] = s(null), [z, B] = s(/* @__PURE__ */ new Map()), [V, H] = s(1), [U, W] = s(10), [G, K] = s(0), [q, J] = s(!0), [Y, se] = s([]), [X, ce] = s(""), [Z, le] = s(D(y)), Q = o(0), $ = r(async () => {
|
|
60
60
|
let e = Q.current + 1;
|
|
61
61
|
Q.current = e, J(!0), R(null);
|
|
62
62
|
try {
|
|
@@ -137,7 +137,7 @@ function T({ defaultState: y, description: T, emptyMessage: O, searchPlaceholder
|
|
|
137
137
|
render: (e) => /* @__PURE__ */ _(h, {
|
|
138
138
|
component: "span",
|
|
139
139
|
variant: "body",
|
|
140
|
-
children:
|
|
140
|
+
children: n(e.startedAt)
|
|
141
141
|
}),
|
|
142
142
|
title: "發起時間",
|
|
143
143
|
width: 220
|
|
@@ -147,7 +147,7 @@ function T({ defaultState: y, description: T, emptyMessage: O, searchPlaceholder
|
|
|
147
147
|
render: (e) => /* @__PURE__ */ _(h, {
|
|
148
148
|
component: "span",
|
|
149
149
|
variant: "body",
|
|
150
|
-
children:
|
|
150
|
+
children: n(e.completedAt)
|
|
151
151
|
}),
|
|
152
152
|
title: "完成時間",
|
|
153
153
|
width: 220
|
|
@@ -274,7 +274,6 @@ function j(e, t) {
|
|
|
274
274
|
function M(e) {
|
|
275
275
|
return e instanceof Error ? e.message : "讀取簽核案件失敗。";
|
|
276
276
|
}
|
|
277
|
-
//#endregion
|
|
278
277
|
export { T as t };
|
|
279
278
|
|
|
280
|
-
//# sourceMappingURL=approval-instance-list-page-
|
|
279
|
+
//# sourceMappingURL=approval-instance-list-page-BnI4t5mD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-instance-list-page-CPXMP3PL.js","names":["_Fragment","styles","useRouterAdapter","useBPMRoutes","Fragment$1","ContentHeader","approval_instance_list_page_module_default","INSTANCE_PAGE_SIZE_OPTIONS","STATE_FILTER_OPTIONS","ApprovalInstanceListPage","router","routes","error","setError","useState","initiatorProfilesById","setInitiatorProfilesById","instancePage","setInstancePage","instancePageSize","setInstancePageSize","instanceTotalCount","setInstanceTotalCount","loading","setLoading","rows","setRows","searchText","setSearchText","stateFilter","setStateFilter","readStateFilterOption","defaultState","refreshRequestIdRef","useRef","refreshInstances","useCallback","requestId","result","listApprovalInstancesPage","readApprovalInstanceRow","requestError","readErrorMessage","view","useEffect","initiatorMemberIds","row","cancelled","profiles","resolveMembers","profile","columns","useMemo","Typography","readInstanceStateColor","record","readInitiatorLabel","formatDateTime","tableActions","PageHeader","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","Input","event","searchPlaceholder","Select","readSelectedStateFilterOption","option","readStateFilterLabel","value","emptyMessage","Table","page","pageSize","from","to","total","instance","readApprovalInstanceCaseTitle","readInstanceStateLabel","isStateFilterOption","state","trimmedMemberId","initiatorMemberId"],"sources":["../../src/components/approval-instance-list-page.module.scss","../../src/components/approval-instance-list-page.tsx"],"sourcesContent":[".instanceFilterArea {\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n","'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n resolveMembers,\n type MemberProfileRecord,\n} from '@rytass/bpm-core-client';\nimport {\n listApprovalInstancesPage,\n readApprovalInstanceCaseTitle,\n type ApprovalInstanceRecord,\n type ApprovalInstanceState,\n type ApprovalInstanceView,\n} from '@rytass/bpm-core-client/workflow';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\nimport { formatDateTime } from '../lib/format-date-time';\nimport styles from './approval-instance-list-page.module.scss';\n\nexport interface ApprovalInstanceListPageProps {\n readonly defaultState: ApprovalInstanceState | null;\n readonly description: string;\n readonly emptyMessage: string;\n readonly searchPlaceholder: string;\n readonly title: string;\n readonly view: ApprovalInstanceView;\n}\n\ntype StateFilterOption = Readonly<{\n id: 'ALL' | ApprovalInstanceState;\n name: string;\n state: ApprovalInstanceState | null;\n}>;\n\ntype ApprovalInstanceRow = Readonly<\n Record<string, unknown> &\n ApprovalInstanceRecord & {\n caseTitle: string;\n key: string;\n stateLabel: string;\n }\n>;\n\nconst INSTANCE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst STATE_FILTER_OPTIONS: readonly StateFilterOption[] = [\n { id: 'ALL', name: '全部狀態', state: null },\n { id: 'RUNNING', name: '進行中', state: 'RUNNING' },\n { id: 'APPROVED', name: '已通過', state: 'APPROVED' },\n { id: 'REJECTED', name: '已拒絕', state: 'REJECTED' },\n { id: 'RETURNED', name: '已退回', state: 'RETURNED' },\n { id: 'CANCELLED', name: '已取消', state: 'CANCELLED' },\n { id: 'EXPIRED', name: '已逾期', state: 'EXPIRED' },\n { id: 'DRAFT', name: '草稿', state: 'DRAFT' },\n];\n\n/**\n * Shared list page for any approval-instance \"view\" (inbox / sent / cc /\n * delegated). Caller picks the view + default state filter; the page renders\n * the standard BPM filter bar + paginated table and navigates to\n * `/instances/:id` on row action.\n */\nexport function ApprovalInstanceListPage({\n defaultState,\n description,\n emptyMessage,\n searchPlaceholder,\n title,\n view,\n}: ApprovalInstanceListPageProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [error, setError] = useState<string | null>(null);\n const [initiatorProfilesById, setInitiatorProfilesById] = useState<\n ReadonlyMap<string, MemberProfileRecord>\n >(new Map());\n const [instancePage, setInstancePage] = useState(1);\n const [instancePageSize, setInstancePageSize] = useState(10);\n const [instanceTotalCount, setInstanceTotalCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [rows, setRows] = useState<readonly ApprovalInstanceRow[]>([]);\n const [searchText, setSearchText] = useState('');\n const [stateFilter, setStateFilter] = useState<StateFilterOption>(\n readStateFilterOption(defaultState),\n );\n const refreshRequestIdRef = useRef(0);\n\n const refreshInstances = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n\n try {\n const result = await listApprovalInstancesPage({\n page: instancePage,\n pageSize: instancePageSize,\n searchText,\n state: stateFilter.state,\n templateId: null,\n view,\n });\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setRows(result.instances.map(readApprovalInstanceRow));\n setInstanceTotalCount(result.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 }, [instancePage, instancePageSize, searchText, stateFilter, view]);\n\n useEffect((): void => {\n void refreshInstances();\n }, [refreshInstances]);\n\n useEffect((): (() => void) | void => {\n const initiatorMemberIds = Array.from(\n new Set(rows.map((row) => row.initiatorMemberId).filter(Boolean)),\n );\n\n if (initiatorMemberIds.length === 0) {\n setInitiatorProfilesById(new Map());\n\n return;\n }\n\n let cancelled = false;\n\n void (async (): Promise<void> => {\n try {\n const profiles = await resolveMembers(initiatorMemberIds);\n\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(\n new Map(profiles.map((profile) => [profile.memberId, profile])),\n );\n } catch {\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(new Map());\n }\n })();\n\n return (): void => {\n cancelled = true;\n };\n }, [rows]);\n\n const columns = useMemo(\n (): TableColumn<ApprovalInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 300 },\n {\n key: 'state',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.state)}\n component=\"span\"\n variant=\"body\"\n >\n {record.stateLabel}\n </Typography>\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'initiatorMemberId',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {readInitiatorLabel(\n record.initiatorMemberId,\n initiatorProfilesById,\n )}\n </Typography>\n ),\n title: '發起人',\n width: 180,\n },\n {\n key: 'startedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n {\n key: 'completedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.completedAt)}\n </Typography>\n ),\n title: '完成時間',\n width: 220,\n },\n ],\n [initiatorProfilesById],\n );\n const tableActions = useMemo(\n (): TableActions<ApprovalInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalInstanceRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n return (\n <>\n <PageHeader>\n <ContentHeader description={description} title={title} />\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.instanceFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setInstancePage(1);\n }}\n placeholder={searchPlaceholder}\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceState\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setStateFilter(readSelectedStateFilterOption(option));\n setInstancePage(1);\n }}\n options={[...STATE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n renderValue={(value): string =>\n `狀態:${readStateFilterLabel(value)}`\n }\n size=\"sub\"\n value={stateFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {!error && !loading && rows.length === 0 ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n {emptyMessage}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={{\n current: instancePage,\n onChange: (page): void => {\n setInstancePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setInstancePage(1);\n setInstancePageSize(pageSize);\n },\n pageSize: instancePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: INSTANCE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: instanceTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readApprovalInstanceRow(\n instance: ApprovalInstanceRecord,\n): ApprovalInstanceRow {\n return {\n ...instance,\n caseTitle: readApprovalInstanceCaseTitle(instance),\n key: instance.id,\n stateLabel: readInstanceStateLabel(instance.state),\n };\n}\n\nfunction readSelectedStateFilterOption(option: unknown): StateFilterOption {\n if (!isStateFilterOption(option)) {\n return STATE_FILTER_OPTIONS[0];\n }\n return readStateFilterOption(option.state);\n}\n\nfunction readStateFilterOption(\n state: ApprovalInstanceState | null,\n): StateFilterOption {\n return (\n STATE_FILTER_OPTIONS.find((option) => option.state === state) ??\n STATE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readStateFilterLabel(value: unknown): string {\n return isStateFilterOption(value) ? value.name : STATE_FILTER_OPTIONS[0].name;\n}\n\nfunction isStateFilterOption(value: unknown): value is StateFilterOption {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n 'name' in value &&\n 'state' in value\n );\n}\n\nfunction readInstanceStateLabel(state: ApprovalInstanceState): string {\n if (state === 'RUNNING') return '進行中';\n if (state === 'APPROVED') return '已通過';\n if (state === 'REJECTED') return '已拒絕';\n if (state === 'RETURNED') return '已退回';\n if (state === 'CANCELLED') return '已取消';\n if (state === 'EXPIRED') return '已逾期';\n return '草稿';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceState,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') return 'text-success';\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n return 'text-neutral';\n}\n\nfunction readInitiatorLabel(\n initiatorMemberId: string | null | undefined,\n initiatorProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string {\n const trimmedMemberId = (initiatorMemberId ?? '').trim();\n if (!trimmedMemberId) return '未知發起人';\n return initiatorProfilesById.get(trimmedMemberId)?.name ?? trimmedMemberId;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取簽核案件失敗。';\n}\n"],"mappings":";;;;;;;;;;;gEC4DMO,IAA6B;CAAC;CAAI;CAAI;AAAE,GACxCC,IAAqD;CACzD;EAAE,IAAI;EAAO,MAAM;EAAQ,OAAO;CAAK;CACvC;EAAE,IAAI;EAAW,MAAM;EAAO,OAAO;CAAU;CAC/C;EAAE,IAAI;EAAY,MAAM;EAAO,OAAO;CAAW;CACjD;EAAE,IAAI;EAAY,MAAM;EAAO,OAAO;CAAW;CACjD;EAAE,IAAI;EAAY,MAAM;EAAO,OAAO;CAAW;CACjD;EAAE,IAAI;EAAa,MAAM;EAAO,OAAO;CAAY;CACnD;EAAE,IAAI;EAAW,MAAM;EAAO,OAAO;CAAU;CAC/C;EAAE,IAAI;EAAS,MAAM;EAAM,OAAO;CAAQ;AAC5C;AAQA,SAAgBC,EAAyB,EACvC,iBACA,gBACA,iBACA,sBACA,UACA,WAC8C;CAC9C,IAAMC,IAASR,EAAiB,GAC1BS,IAASR,EAAa,GACtB,CAACS,GAAOC,KAAYC,EAAwB,IAAI,GAChD,CAACC,GAAuBC,KAA4BF,kBAExD,IAAI,IAAI,CAAC,GACL,CAACG,GAAcC,KAAmBJ,EAAS,CAAC,GAC5C,CAACK,GAAkBC,KAAuBN,EAAS,EAAE,GACrD,CAACO,GAAoBC,KAAyBR,EAAS,CAAC,GACxD,CAACS,GAASC,KAAcV,EAAS,EAAI,GACrC,CAACW,GAAMC,MAAWZ,EAAyC,CAAC,CAAC,GAC7D,CAACa,GAAYC,MAAiBd,EAAS,EAAE,GACzC,CAACe,GAAaC,MAAkBhB,EACpCiB,EAAsBC,CAAY,CACpC,GACMC,IAAsBC,EAAO,CAAC,GAE9BC,IAAmBC,EAAY,YAA2B;EAC9D,IAAMC,IAAYJ,EAAoB,UAAU;EAGhD,AAFA,EAAoB,UAAUI,GAC9Bb,EAAW,EAAI,GACfX,EAAS,IAAI;EAEb,IAAI;GACF,IAAMyB,IAAS,MAAMC,GAA0B;IAC7C,MAAMtB;IACN,UAAUE;IACV;IACA,OAAOU,EAAY;IACnB,YAAY;IACZ;GACF,CAAC;GAED,IAAIQ,MAAcJ,EAAoB,SACpC;GAIF,AADAP,GAAQY,EAAO,UAAU,IAAIE,CAAuB,CAAC,GACrDlB,EAAsBgB,EAAO,UAAU;EACzC,SAASG,GAAuB;GAC9B,AAAIJ,MAAcJ,EAAoB,WACpCpB,EAAS6B,EAAiBD,CAAY,CAAC;EAE3C,UAAU;GACR,AAAIJ,MAAcJ,EAAoB,WACpCT,EAAW,EAAK;EAEpB;CACF,GAAG;EAACP;EAAcE;EAAkBQ;EAAYE;EAAac;CAAI,CAAC;CAMlE,AAJAC,QAAsB;EACpB,EAAsB;CACxB,GAAG,CAACT,CAAgB,CAAC,GAErBS,QAAqC;EACnC,IAAMC,IAAqB,MAAM,KAC/B,IAAI,IAAIpB,EAAK,KAAK,MAAQqB,EAAI,iBAAiB,CAAC,CAAC,OAAO,OAAO,CAAC,CAClE;EAEA,IAAID,EAAmB,WAAW,GAAG;GACnC,kBAAyB,IAAI,IAAI,CAAC;GAElC;EACF;EAEA,IAAIE,IAAY;EAsBhB,QApBM,YAA2B;GAC/B,IAAI;IACF,IAAMC,IAAW,MAAMC,GAAeJ,CAAkB;IAExD,IAAIE,GACF;IAGF,EACE,IAAI,IAAIC,EAAS,KAAK,MAAY,CAACE,EAAQ,UAAUA,CAAO,CAAC,CAAC,CAChE;GACF,QAAQ;IACN,IAAIH,GACF;IAGF,kBAAyB,IAAI,IAAI,CAAC;GACpC;EACF,EAAA,CAAG,SAEgB;GACjB,IAAY;EACd;CACF,GAAG,CAACtB,CAAI,CAAC;CAET,IAAM0B,KAAUC,QAC4B;EACxC;GAAE,WAAW;GAAa,KAAK;GAAa,OAAO;GAAM,OAAO;EAAI;EACpE;GACE,KAAK;GACL,SAAS,MACP,kBAACC,GAAD;IACE,OAAOC,EAAuBC,EAAO,KAAK;IAC1C,WAAU;IACV,SAAQ;IAEP,UAAAA,EAAO;GACE,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACF,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAAG,EACCD,EAAO,mBACPxC,CACF;GACU,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACsC,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAAI,EAAeF,EAAO,SAAS;GACtB,CAAA;GAEd,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACP,kBAACF,GAAD;IAAY,WAAU;IAAO,SAAQ;IAClC,UAAAI,EAAeF,EAAO,WAAW;GACxB,CAAA;GAEd,OAAO;GACP,OAAO;EACT;CACF,GACA,CAACxC,CAAqB,CACxB,GACM2C,KAAeN,SACuB;EACxC,SACE,MAC4D,CAC5D;GACE,MAAM;GACN,eAAqB1C,EAAO,KAAKC,EAAO,WAAW4C,EAAO,EAAE,CAAC;EAC/D,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC7C,CAAM,CACT;CAEA,OACE,kBAAAV,GAAA,EAAA,UAAA,CACE,kBAAC2D,GAAD,EAAA,UACE,kBAACtD,GAAD;EAA4B;EAAoB;CAAQ,CAAA,EAC9C,CAAA,GAEZ,kBAACuD,GAAD,EAAA,UACE,kBAACC,IAAD;EACE,YACE,kBAACC,IAAD;GAAY,WAAW7D,EAAO;GAAoB,MAAK;GACrD,UAAA,kBAAC8D,IAAD,EAAA,UAAA,CACE,kBAACC,GAAD;IAAQ,MAAM;IACZ,UAAA,kBAACC,GAAD;KACE,WAAA;KACA,QAAQC,EAAgB;KACxB,MAAK;KAEL,UAAA,kBAACC,GAAD;MACE,WAAA;MACA,WACE,MACS;OAET,AADAvC,GAAcwC,EAAM,OAAO,KAAK,GAChClD,EAAgB,CAAC;MACnB;MACA,aAAamD;MACb,MAAK;MACL,OAAO1C;MACP,SAAQ;KACT,CAAA;IACQ,CAAA;GACL,CAAA,GACR,kBAACqC,GAAD;IAAQ,MAAM;IACZ,UAAA,kBAACC,GAAD;KACE,WAAA;KACA,QAAQC,EAAgB;KACxB,MAAK;KAEL,UAAA,kBAACI,GAAD;MACE,WAAW;MACX,WAAA;MACA,WAAW,MAAiB;OAE1B,AADAxC,GAAeyC,GAA8BC,CAAM,CAAC,GACpDtD,EAAgB,CAAC;MACnB;MACA,SAAS,CAAC,GAAGV,CAAoB;MACjC,aAAY;MACZ,cAAc,MACZ,MAAMiE,GAAqBC,CAAK;MAElC,MAAK;MACL,OAAO7C;KACR,CAAA;IACQ,CAAA;GACL,CAAA,CACE,EAAA,CAAA;EACF,CAAA;EAjDhB,UAAA;GAoDGjB,IACC,kBAACyC,GAAD;IAAY,OAAM;IAAa,SAAQ;IACpC,UAAAzC;GACS,CAAA,IACV;GACH,CAACA,KAAS,CAACW,KAAWE,EAAK,WAAW,IACrC,kBAAC4B,GAAD;IAAY,OAAM;IAAe,SAAQ;IACtC,UAAAsB;GACS,CAAA,IACV;GACJ,kBAACC,GAAD;IACE,SAASlB;IACA;IACT,YAAY,CAAC,GAAGjC,CAAI;IACpB,WAAA;IACS;IACT,YAAY;KACV,SAASR;KACT,WAAW,MAAe;MACxB,EAAgB4D,CAAI;KACtB;KACA,mBAAmB,MAAmB;MAEpC,AADA3D,EAAgB,CAAC,GACjBE,EAAoB0D,CAAQ;KAC9B;KACA,UAAU3D;KACV,eAAe;KACf,iBAAiBZ;KACjB,sBAAsB,GAAM,GAAI,MAC9B,MAAMwE,EAAK,GAAGC,EAAG,OAAOC,EAAM;KAChC,qBAAqB;KACrB,OAAO5D;IACT;GACD,CAAA;EACM;CACG,CAAA,EAAA,CAAA,CACd,EAAA,CAAA;AAEN;AAEA,SAASmB,EACP,GACqB;CACrB,OAAO;EACL,GAAG0C;EACH,WAAWC,EAA8BD,CAAQ;EACjD,KAAKA,EAAS;EACd,YAAYE,EAAuBF,EAAS,KAAK;CACnD;AACF;AAEA,SAASX,GAA8B,GAAoC;CAIzE,OAHKc,EAAoBb,CAAM,IAGxBzC,EAAsByC,EAAO,KAAK,IAFhChE,EAAqB;AAGhC;AAEA,SAASuB,EACP,GACmB;CACnB,OACEvB,EAAqB,MAAM,MAAWgE,EAAO,UAAUc,CAAK,KAC5D9E,EAAqB;AAEzB;AAEA,SAASiE,GAAqB,GAAwB;CACpD,OAAOY,EAAoBX,CAAK,IAAIA,EAAM,OAAOlE,EAAqB,EAAE,CAAC;AAC3E;AAEA,SAAS6E,EAAoB,GAA4C;CACvE,OACE,OAAOX,KAAU,cACjBA,KACA,QAAQA,KACR,UAAUA,KACV,WAAWA;AAEf;AAEA,SAASU,EAAuB,GAAsC;CAOpE,OANIE,MAAU,YAAkB,QAC5BA,MAAU,aAAmB,QAC7BA,MAAU,aAAmB,QAC7BA,MAAU,aAAmB,QAC7BA,MAAU,cAAoB,QAC9BA,MAAU,YAAkB,QACzB;AACT;AAEA,SAAShC,EACP,GACgD;CAKhD,OAJIgC,MAAU,aAAmB,iBAC7BA,MAAU,cAAcA,MAAU,eAAeA,MAAU,YACtD,eAEF;AACT;AAEA,SAAS9B,EACP,GACA,GACQ;CACR,IAAM+B,KAAmBC,KAAqB,GAAA,CAAI,KAAK;CAEvD,OADKD,IACExE,EAAsB,IAAIwE,CAAe,CAAC,EAAE,QAAQA,IAD9B;AAE/B;AAEA,SAAS7C,EAAiB,GAAwB;CAChD,OAAO9B,aAAiB,QAAQA,EAAM,UAAU;AAClD"}
|
|
1
|
+
{"version":3,"file":"approval-instance-list-page-BnI4t5mD.js","names":["_Fragment","styles","useRouterAdapter","useBPMRoutes","formatDateTime","Fragment$1","ContentHeader","approval_instance_list_page_module_default","INSTANCE_PAGE_SIZE_OPTIONS","STATE_FILTER_OPTIONS","ApprovalInstanceListPage","router","routes","error","setError","useState","initiatorProfilesById","setInitiatorProfilesById","instancePage","setInstancePage","instancePageSize","setInstancePageSize","instanceTotalCount","setInstanceTotalCount","loading","setLoading","rows","setRows","searchText","setSearchText","stateFilter","setStateFilter","readStateFilterOption","defaultState","refreshRequestIdRef","useRef","refreshInstances","useCallback","requestId","result","listApprovalInstancesPage","readApprovalInstanceRow","requestError","readErrorMessage","view","useEffect","initiatorMemberIds","row","cancelled","profiles","resolveMembers","profile","columns","useMemo","Typography","readInstanceStateColor","record","readInitiatorLabel","tableActions","PageHeader","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","Input","event","searchPlaceholder","Select","readSelectedStateFilterOption","option","readStateFilterLabel","value","emptyMessage","Table","page","pageSize","from","to","total","instance","readApprovalInstanceCaseTitle","readInstanceStateLabel","isStateFilterOption","state","trimmedMemberId","initiatorMemberId"],"sources":["../../src/components/approval-instance-list-page.module.scss","../../src/components/approval-instance-list-page.tsx"],"sourcesContent":[".instanceFilterArea {\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n","'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n resolveMembers,\n type MemberProfileRecord,\n} from '@rytass/bpm-core-client';\nimport {\n listApprovalInstancesPage,\n readApprovalInstanceCaseTitle,\n type ApprovalInstanceRecord,\n type ApprovalInstanceState,\n type ApprovalInstanceView,\n} from '@rytass/bpm-core-client/workflow';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\nimport { formatDateTime } from '../lib/format-date-time';\nimport styles from './approval-instance-list-page.module.scss';\n\nexport interface ApprovalInstanceListPageProps {\n readonly defaultState: ApprovalInstanceState | null;\n readonly description: string;\n readonly emptyMessage: string;\n readonly searchPlaceholder: string;\n readonly title: string;\n readonly view: ApprovalInstanceView;\n}\n\ntype StateFilterOption = Readonly<{\n id: 'ALL' | ApprovalInstanceState;\n name: string;\n state: ApprovalInstanceState | null;\n}>;\n\ntype ApprovalInstanceRow = Readonly<\n Record<string, unknown> &\n ApprovalInstanceRecord & {\n caseTitle: string;\n key: string;\n stateLabel: string;\n }\n>;\n\nconst INSTANCE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst STATE_FILTER_OPTIONS: readonly StateFilterOption[] = [\n { id: 'ALL', name: '全部狀態', state: null },\n { id: 'RUNNING', name: '進行中', state: 'RUNNING' },\n { id: 'APPROVED', name: '已通過', state: 'APPROVED' },\n { id: 'REJECTED', name: '已拒絕', state: 'REJECTED' },\n { id: 'RETURNED', name: '已退回', state: 'RETURNED' },\n { id: 'CANCELLED', name: '已取消', state: 'CANCELLED' },\n { id: 'EXPIRED', name: '已逾期', state: 'EXPIRED' },\n { id: 'DRAFT', name: '草稿', state: 'DRAFT' },\n];\n\n/**\n * Shared list page for any approval-instance \"view\" (inbox / sent / cc /\n * delegated). Caller picks the view + default state filter; the page renders\n * the standard BPM filter bar + paginated table and navigates to\n * `/instances/:id` on row action.\n */\nexport function ApprovalInstanceListPage({\n defaultState,\n description,\n emptyMessage,\n searchPlaceholder,\n title,\n view,\n}: ApprovalInstanceListPageProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [error, setError] = useState<string | null>(null);\n const [initiatorProfilesById, setInitiatorProfilesById] = useState<\n ReadonlyMap<string, MemberProfileRecord>\n >(new Map());\n const [instancePage, setInstancePage] = useState(1);\n const [instancePageSize, setInstancePageSize] = useState(10);\n const [instanceTotalCount, setInstanceTotalCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [rows, setRows] = useState<readonly ApprovalInstanceRow[]>([]);\n const [searchText, setSearchText] = useState('');\n const [stateFilter, setStateFilter] = useState<StateFilterOption>(\n readStateFilterOption(defaultState),\n );\n const refreshRequestIdRef = useRef(0);\n\n const refreshInstances = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n\n try {\n const result = await listApprovalInstancesPage({\n page: instancePage,\n pageSize: instancePageSize,\n searchText,\n state: stateFilter.state,\n templateId: null,\n view,\n });\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setRows(result.instances.map(readApprovalInstanceRow));\n setInstanceTotalCount(result.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 }, [instancePage, instancePageSize, searchText, stateFilter, view]);\n\n useEffect((): void => {\n void refreshInstances();\n }, [refreshInstances]);\n\n useEffect((): (() => void) | void => {\n const initiatorMemberIds = Array.from(\n new Set(rows.map((row) => row.initiatorMemberId).filter(Boolean)),\n );\n\n if (initiatorMemberIds.length === 0) {\n setInitiatorProfilesById(new Map());\n\n return;\n }\n\n let cancelled = false;\n\n void (async (): Promise<void> => {\n try {\n const profiles = await resolveMembers(initiatorMemberIds);\n\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(\n new Map(profiles.map((profile) => [profile.memberId, profile])),\n );\n } catch {\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(new Map());\n }\n })();\n\n return (): void => {\n cancelled = true;\n };\n }, [rows]);\n\n const columns = useMemo(\n (): TableColumn<ApprovalInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 300 },\n {\n key: 'state',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.state)}\n component=\"span\"\n variant=\"body\"\n >\n {record.stateLabel}\n </Typography>\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'initiatorMemberId',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {readInitiatorLabel(\n record.initiatorMemberId,\n initiatorProfilesById,\n )}\n </Typography>\n ),\n title: '發起人',\n width: 180,\n },\n {\n key: 'startedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n {\n key: 'completedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.completedAt)}\n </Typography>\n ),\n title: '完成時間',\n width: 220,\n },\n ],\n [initiatorProfilesById],\n );\n const tableActions = useMemo(\n (): TableActions<ApprovalInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalInstanceRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n return (\n <>\n <PageHeader>\n <ContentHeader description={description} title={title} />\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.instanceFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setInstancePage(1);\n }}\n placeholder={searchPlaceholder}\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceState\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setStateFilter(readSelectedStateFilterOption(option));\n setInstancePage(1);\n }}\n options={[...STATE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n renderValue={(value): string =>\n `狀態:${readStateFilterLabel(value)}`\n }\n size=\"sub\"\n value={stateFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {!error && !loading && rows.length === 0 ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n {emptyMessage}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={{\n current: instancePage,\n onChange: (page): void => {\n setInstancePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setInstancePage(1);\n setInstancePageSize(pageSize);\n },\n pageSize: instancePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: INSTANCE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: instanceTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readApprovalInstanceRow(\n instance: ApprovalInstanceRecord,\n): ApprovalInstanceRow {\n return {\n ...instance,\n caseTitle: readApprovalInstanceCaseTitle(instance),\n key: instance.id,\n stateLabel: readInstanceStateLabel(instance.state),\n };\n}\n\nfunction readSelectedStateFilterOption(option: unknown): StateFilterOption {\n if (!isStateFilterOption(option)) {\n return STATE_FILTER_OPTIONS[0];\n }\n return readStateFilterOption(option.state);\n}\n\nfunction readStateFilterOption(\n state: ApprovalInstanceState | null,\n): StateFilterOption {\n return (\n STATE_FILTER_OPTIONS.find((option) => option.state === state) ??\n STATE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readStateFilterLabel(value: unknown): string {\n return isStateFilterOption(value) ? value.name : STATE_FILTER_OPTIONS[0].name;\n}\n\nfunction isStateFilterOption(value: unknown): value is StateFilterOption {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n 'name' in value &&\n 'state' in value\n );\n}\n\nfunction readInstanceStateLabel(state: ApprovalInstanceState): string {\n if (state === 'RUNNING') return '進行中';\n if (state === 'APPROVED') return '已通過';\n if (state === 'REJECTED') return '已拒絕';\n if (state === 'RETURNED') return '已退回';\n if (state === 'CANCELLED') return '已取消';\n if (state === 'EXPIRED') return '已逾期';\n return '草稿';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceState,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') return 'text-success';\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n return 'text-neutral';\n}\n\nfunction readInitiatorLabel(\n initiatorMemberId: string | null | undefined,\n initiatorProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string {\n const trimmedMemberId = (initiatorMemberId ?? '').trim();\n if (!trimmedMemberId) return '未知發起人';\n return initiatorProfilesById.get(trimmedMemberId)?.name ?? trimmedMemberId;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取簽核案件失敗。';\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";require('../approval-instance-list-page.css');const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./router-adapter--gYs13E8.cjs"),n=require("./
|
|
2
|
-
//# sourceMappingURL=approval-instance-list-page-
|
|
1
|
+
"use client";require('../approval-instance-list-page.css');const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./router-adapter--gYs13E8.cjs"),n=require("./routes-config-C1j_vFKo.cjs"),r=require("./format-date-time-D-cx5M8z.cjs");let i=require("react"),a=require("@mezzanine-ui/react"),o=require("@rytass/bpm-core-client"),s=require("react/jsx-runtime"),c=require("@rytass/bpm-core-client/workflow"),l=require("@mezzanine-ui/core/form"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);var d={instanceFilterArea:`bpm_instanceFilterArea_qpvJq`},f=[10,20,50],p=[{id:`ALL`,name:`全部狀態`,state:null},{id:`RUNNING`,name:`進行中`,state:`RUNNING`},{id:`APPROVED`,name:`已通過`,state:`APPROVED`},{id:`REJECTED`,name:`已拒絕`,state:`REJECTED`},{id:`RETURNED`,name:`已退回`,state:`RETURNED`},{id:`CANCELLED`,name:`已取消`,state:`CANCELLED`},{id:`EXPIRED`,name:`已逾期`,state:`EXPIRED`},{id:`DRAFT`,name:`草稿`,state:`DRAFT`}];function m({defaultState:e,description:m,emptyMessage:y,searchPlaceholder:b,title:w,view:T}){let E=t.r(),D=n.r(),[O,k]=(0,i.useState)(null),[A,j]=(0,i.useState)(new Map),[M,N]=(0,i.useState)(1),[P,F]=(0,i.useState)(10),[I,L]=(0,i.useState)(0),[R,z]=(0,i.useState)(!0),[B,V]=(0,i.useState)([]),[H,U]=(0,i.useState)(``),[W,G]=(0,i.useState)(_(e)),K=(0,i.useRef)(0),q=(0,i.useCallback)(async()=>{let e=K.current+1;K.current=e,z(!0),k(null);try{let t=await(0,c.listApprovalInstancesPage)({page:M,pageSize:P,searchText:H,state:W.state,templateId:null,view:T});if(e!==K.current)return;V(t.instances.map(h)),L(t.totalCount)}catch(t){e===K.current&&k(C(t))}finally{e===K.current&&z(!1)}},[M,P,H,W,T]);(0,i.useEffect)(()=>{q()},[q]),(0,i.useEffect)(()=>{let e=Array.from(new Set(B.map(e=>e.initiatorMemberId).filter(Boolean)));if(e.length===0){j(new Map);return}let t=!1;return(async()=>{try{let n=await(0,o.resolveMembers)(e);if(t)return;j(new Map(n.map(e=>[e.memberId,e])))}catch{if(t)return;j(new Map)}})(),()=>{t=!0}},[B]);let J=(0,i.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:300},{key:`state`,render:e=>(0,s.jsx)(a.Typography,{color:x(e.state),component:`span`,variant:`body`,children:e.stateLabel}),title:`狀態`,width:120},{key:`initiatorMemberId`,render:e=>(0,s.jsx)(a.Typography,{component:`span`,variant:`body`,children:S(e.initiatorMemberId,A)}),title:`發起人`,width:180},{key:`startedAt`,render:e=>(0,s.jsx)(a.Typography,{component:`span`,variant:`body`,children:r.t(e.startedAt)}),title:`發起時間`,width:220},{key:`completedAt`,render:e=>(0,s.jsx)(a.Typography,{component:`span`,variant:`body`,children:r.t(e.completedAt)}),title:`完成時間`,width:220}],[A]),Y=(0,i.useMemo)(()=>({render:e=>[{name:`查看`,onClick:()=>E.push(D.caseDetail(e.id))}],variant:`base-secondary`,width:88}),[E]);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(a.PageHeader,{children:(0,s.jsx)(u.default,{description:m,title:w})}),(0,s.jsx)(a.SectionGroup,{children:(0,s.jsxs)(a.Section,{filterArea:(0,s.jsx)(a.FilterArea,{className:d.instanceFilterArea,size:`sub`,children:(0,s.jsxs)(a.FilterLine,{children:[(0,s.jsx)(a.Filter,{span:3,children:(0,s.jsx)(a.FormField,{fullWidth:!0,layout:l.FormFieldLayout.VERTICAL,name:`instanceSearchText`,children:(0,s.jsx)(a.Input,{fullWidth:!0,onChange:e=>{U(e.target.value),N(1)},placeholder:b,size:`sub`,value:H,variant:`base`})})}),(0,s.jsx)(a.Filter,{span:2,children:(0,s.jsx)(a.FormField,{fullWidth:!0,layout:l.FormFieldLayout.VERTICAL,name:`instanceState`,children:(0,s.jsx)(a.Select,{clearable:!1,fullWidth:!0,onChange:e=>{G(g(e)),N(1)},options:[...p],placeholder:`狀態`,renderValue:e=>`狀態:${v(e)}`,size:`sub`,value:W})})})]})}),children:[O?(0,s.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:O}):null,!O&&!R&&B.length===0?(0,s.jsx)(a.Typography,{color:`text-neutral`,variant:`body`,children:y}):null,(0,s.jsx)(a.Table,{actions:Y,columns:J,dataSource:[...B],fullWidth:!0,loading:R,pagination:{current:M,onChange:e=>{N(e)},onChangePageSize:e=>{N(1),F(e)},pageSize:P,pageSizeLabel:`每頁筆數`,pageSizeOptions:f,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:I}})]})})]})}function h(e){return{...e,caseTitle:(0,c.readApprovalInstanceCaseTitle)(e),key:e.id,stateLabel:b(e.state)}}function g(e){return y(e)?_(e.state):p[0]}function _(e){return p.find(t=>t.state===e)??p[0]}function v(e){return y(e)?e.name:p[0].name}function y(e){return typeof e==`object`&&!!e&&`id`in e&&`name`in e&&`state`in e}function b(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:`草稿`}function x(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function S(e,t){let n=(e??``).trim();return n?t.get(n)?.name??n:`未知發起人`}function C(e){return e instanceof Error?e.message:`讀取簽核案件失敗。`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return m}});
|
|
2
|
+
//# sourceMappingURL=approval-instance-list-page-fqvmkBlg.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approval-instance-list-page-ax0pm8bt.cjs","names":["useRouterAdapter","useBPMRoutes","useState","useRef","useCallback","listApprovalInstancesPage","resolveMembers","useMemo","Typography","formatDateTime","_Fragment","PageHeader","ContentHeader","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Select","Table","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_format_date_time","require_routes_config","react","_mezzanine_ui_react","_rytass_bpm_core_client","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","approval_instance_list_page_module_default","INSTANCE_PAGE_SIZE_OPTIONS","STATE_FILTER_OPTIONS","ApprovalInstanceListPage","router","routes","error","setError","initiatorProfilesById","setInitiatorProfilesById","instancePage","setInstancePage","instancePageSize","setInstancePageSize","instanceTotalCount","setInstanceTotalCount","loading","setLoading","rows","setRows","searchText","setSearchText","stateFilter","setStateFilter","readStateFilterOption","defaultState","refreshRequestIdRef","refreshInstances","requestId","result","readApprovalInstanceRow","requestError","readErrorMessage","view","initiatorMemberIds","row","cancelled","profiles","profile","columns","readInstanceStateColor","record","readInitiatorLabel","tableActions","event","searchPlaceholder","readSelectedStateFilterOption","option","readStateFilterLabel","value","emptyMessage","page","pageSize","from","to","total","instance","readInstanceStateLabel","isStateFilterOption","state","trimmedMemberId","initiatorMemberId"],"sources":["../../src/components/approval-instance-list-page.module.scss","../../src/components/approval-instance-list-page.tsx"],"sourcesContent":[".instanceFilterArea {\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n","'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n resolveMembers,\n type MemberProfileRecord,\n} from '@rytass/bpm-core-client';\nimport {\n listApprovalInstancesPage,\n readApprovalInstanceCaseTitle,\n type ApprovalInstanceRecord,\n type ApprovalInstanceState,\n type ApprovalInstanceView,\n} from '@rytass/bpm-core-client/workflow';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\nimport { formatDateTime } from '../lib/format-date-time';\nimport styles from './approval-instance-list-page.module.scss';\n\nexport interface ApprovalInstanceListPageProps {\n readonly defaultState: ApprovalInstanceState | null;\n readonly description: string;\n readonly emptyMessage: string;\n readonly searchPlaceholder: string;\n readonly title: string;\n readonly view: ApprovalInstanceView;\n}\n\ntype StateFilterOption = Readonly<{\n id: 'ALL' | ApprovalInstanceState;\n name: string;\n state: ApprovalInstanceState | null;\n}>;\n\ntype ApprovalInstanceRow = Readonly<\n Record<string, unknown> &\n ApprovalInstanceRecord & {\n caseTitle: string;\n key: string;\n stateLabel: string;\n }\n>;\n\nconst INSTANCE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst STATE_FILTER_OPTIONS: readonly StateFilterOption[] = [\n { id: 'ALL', name: '全部狀態', state: null },\n { id: 'RUNNING', name: '進行中', state: 'RUNNING' },\n { id: 'APPROVED', name: '已通過', state: 'APPROVED' },\n { id: 'REJECTED', name: '已拒絕', state: 'REJECTED' },\n { id: 'RETURNED', name: '已退回', state: 'RETURNED' },\n { id: 'CANCELLED', name: '已取消', state: 'CANCELLED' },\n { id: 'EXPIRED', name: '已逾期', state: 'EXPIRED' },\n { id: 'DRAFT', name: '草稿', state: 'DRAFT' },\n];\n\n/**\n * Shared list page for any approval-instance \"view\" (inbox / sent / cc /\n * delegated). Caller picks the view + default state filter; the page renders\n * the standard BPM filter bar + paginated table and navigates to\n * `/instances/:id` on row action.\n */\nexport function ApprovalInstanceListPage({\n defaultState,\n description,\n emptyMessage,\n searchPlaceholder,\n title,\n view,\n}: ApprovalInstanceListPageProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [error, setError] = useState<string | null>(null);\n const [initiatorProfilesById, setInitiatorProfilesById] = useState<\n ReadonlyMap<string, MemberProfileRecord>\n >(new Map());\n const [instancePage, setInstancePage] = useState(1);\n const [instancePageSize, setInstancePageSize] = useState(10);\n const [instanceTotalCount, setInstanceTotalCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [rows, setRows] = useState<readonly ApprovalInstanceRow[]>([]);\n const [searchText, setSearchText] = useState('');\n const [stateFilter, setStateFilter] = useState<StateFilterOption>(\n readStateFilterOption(defaultState),\n );\n const refreshRequestIdRef = useRef(0);\n\n const refreshInstances = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n\n try {\n const result = await listApprovalInstancesPage({\n page: instancePage,\n pageSize: instancePageSize,\n searchText,\n state: stateFilter.state,\n templateId: null,\n view,\n });\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setRows(result.instances.map(readApprovalInstanceRow));\n setInstanceTotalCount(result.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 }, [instancePage, instancePageSize, searchText, stateFilter, view]);\n\n useEffect((): void => {\n void refreshInstances();\n }, [refreshInstances]);\n\n useEffect((): (() => void) | void => {\n const initiatorMemberIds = Array.from(\n new Set(rows.map((row) => row.initiatorMemberId).filter(Boolean)),\n );\n\n if (initiatorMemberIds.length === 0) {\n setInitiatorProfilesById(new Map());\n\n return;\n }\n\n let cancelled = false;\n\n void (async (): Promise<void> => {\n try {\n const profiles = await resolveMembers(initiatorMemberIds);\n\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(\n new Map(profiles.map((profile) => [profile.memberId, profile])),\n );\n } catch {\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(new Map());\n }\n })();\n\n return (): void => {\n cancelled = true;\n };\n }, [rows]);\n\n const columns = useMemo(\n (): TableColumn<ApprovalInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 300 },\n {\n key: 'state',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.state)}\n component=\"span\"\n variant=\"body\"\n >\n {record.stateLabel}\n </Typography>\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'initiatorMemberId',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {readInitiatorLabel(\n record.initiatorMemberId,\n initiatorProfilesById,\n )}\n </Typography>\n ),\n title: '發起人',\n width: 180,\n },\n {\n key: 'startedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n {\n key: 'completedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.completedAt)}\n </Typography>\n ),\n title: '完成時間',\n width: 220,\n },\n ],\n [initiatorProfilesById],\n );\n const tableActions = useMemo(\n (): TableActions<ApprovalInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalInstanceRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n return (\n <>\n <PageHeader>\n <ContentHeader description={description} title={title} />\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.instanceFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setInstancePage(1);\n }}\n placeholder={searchPlaceholder}\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceState\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setStateFilter(readSelectedStateFilterOption(option));\n setInstancePage(1);\n }}\n options={[...STATE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n renderValue={(value): string =>\n `狀態:${readStateFilterLabel(value)}`\n }\n size=\"sub\"\n value={stateFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {!error && !loading && rows.length === 0 ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n {emptyMessage}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={{\n current: instancePage,\n onChange: (page): void => {\n setInstancePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setInstancePage(1);\n setInstancePageSize(pageSize);\n },\n pageSize: instancePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: INSTANCE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: instanceTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readApprovalInstanceRow(\n instance: ApprovalInstanceRecord,\n): ApprovalInstanceRow {\n return {\n ...instance,\n caseTitle: readApprovalInstanceCaseTitle(instance),\n key: instance.id,\n stateLabel: readInstanceStateLabel(instance.state),\n };\n}\n\nfunction readSelectedStateFilterOption(option: unknown): StateFilterOption {\n if (!isStateFilterOption(option)) {\n return STATE_FILTER_OPTIONS[0];\n }\n return readStateFilterOption(option.state);\n}\n\nfunction readStateFilterOption(\n state: ApprovalInstanceState | null,\n): StateFilterOption {\n return (\n STATE_FILTER_OPTIONS.find((option) => option.state === state) ??\n STATE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readStateFilterLabel(value: unknown): string {\n return isStateFilterOption(value) ? value.name : STATE_FILTER_OPTIONS[0].name;\n}\n\nfunction isStateFilterOption(value: unknown): value is StateFilterOption {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n 'name' in value &&\n 'state' in value\n );\n}\n\nfunction readInstanceStateLabel(state: ApprovalInstanceState): string {\n if (state === 'RUNNING') return '進行中';\n if (state === 'APPROVED') return '已通過';\n if (state === 'REJECTED') return '已拒絕';\n if (state === 'RETURNED') return '已退回';\n if (state === 'CANCELLED') return '已取消';\n if (state === 'EXPIRED') return '已逾期';\n return '草稿';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceState,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') return 'text-success';\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n return 'text-neutral';\n}\n\nfunction readInitiatorLabel(\n initiatorMemberId: string | null | undefined,\n initiatorProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string {\n const trimmedMemberId = (initiatorMemberId ?? '').trim();\n if (!trimmedMemberId) return '未知發起人';\n return initiatorProfilesById.get(trimmedMemberId)?.name ?? trimmedMemberId;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取簽核案件失敗。';\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"approval-instance-list-page-fqvmkBlg.cjs","names":["useRouterAdapter","useBPMRoutes","useState","useRef","useCallback","listApprovalInstancesPage","resolveMembers","useMemo","Typography","formatDateTime","_Fragment","PageHeader","ContentHeader","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","FormFieldLayout","Input","Select","Table","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_routes_config","require_format_date_time","react","_mezzanine_ui_react","_rytass_bpm_core_client","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","approval_instance_list_page_module_default","INSTANCE_PAGE_SIZE_OPTIONS","STATE_FILTER_OPTIONS","ApprovalInstanceListPage","router","routes","error","setError","initiatorProfilesById","setInitiatorProfilesById","instancePage","setInstancePage","instancePageSize","setInstancePageSize","instanceTotalCount","setInstanceTotalCount","loading","setLoading","rows","setRows","searchText","setSearchText","stateFilter","setStateFilter","readStateFilterOption","defaultState","refreshRequestIdRef","refreshInstances","requestId","result","readApprovalInstanceRow","requestError","readErrorMessage","view","initiatorMemberIds","row","cancelled","profiles","profile","columns","readInstanceStateColor","record","readInitiatorLabel","tableActions","event","searchPlaceholder","readSelectedStateFilterOption","option","readStateFilterLabel","value","emptyMessage","page","pageSize","from","to","total","instance","readInstanceStateLabel","isStateFilterOption","state","trimmedMemberId","initiatorMemberId"],"sources":["../../src/components/approval-instance-list-page.module.scss","../../src/components/approval-instance-list-page.tsx"],"sourcesContent":[".instanceFilterArea {\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-form-field__label-area) {\n display: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n}\n","'use client';\n\nimport type { ChangeEvent, ReactElement } from 'react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n resolveMembers,\n type MemberProfileRecord,\n} from '@rytass/bpm-core-client';\nimport {\n listApprovalInstancesPage,\n readApprovalInstanceCaseTitle,\n type ApprovalInstanceRecord,\n type ApprovalInstanceState,\n type ApprovalInstanceView,\n} from '@rytass/bpm-core-client/workflow';\nimport { useRouterAdapter } from '../lib/router-adapter';\nimport { useBPMRoutes } from '../lib/routes-config';\nimport { formatDateTime } from '../lib/format-date-time';\nimport styles from './approval-instance-list-page.module.scss';\n\nexport interface ApprovalInstanceListPageProps {\n readonly defaultState: ApprovalInstanceState | null;\n readonly description: string;\n readonly emptyMessage: string;\n readonly searchPlaceholder: string;\n readonly title: string;\n readonly view: ApprovalInstanceView;\n}\n\ntype StateFilterOption = Readonly<{\n id: 'ALL' | ApprovalInstanceState;\n name: string;\n state: ApprovalInstanceState | null;\n}>;\n\ntype ApprovalInstanceRow = Readonly<\n Record<string, unknown> &\n ApprovalInstanceRecord & {\n caseTitle: string;\n key: string;\n stateLabel: string;\n }\n>;\n\nconst INSTANCE_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst STATE_FILTER_OPTIONS: readonly StateFilterOption[] = [\n { id: 'ALL', name: '全部狀態', state: null },\n { id: 'RUNNING', name: '進行中', state: 'RUNNING' },\n { id: 'APPROVED', name: '已通過', state: 'APPROVED' },\n { id: 'REJECTED', name: '已拒絕', state: 'REJECTED' },\n { id: 'RETURNED', name: '已退回', state: 'RETURNED' },\n { id: 'CANCELLED', name: '已取消', state: 'CANCELLED' },\n { id: 'EXPIRED', name: '已逾期', state: 'EXPIRED' },\n { id: 'DRAFT', name: '草稿', state: 'DRAFT' },\n];\n\n/**\n * Shared list page for any approval-instance \"view\" (inbox / sent / cc /\n * delegated). Caller picks the view + default state filter; the page renders\n * the standard BPM filter bar + paginated table and navigates to\n * `/instances/:id` on row action.\n */\nexport function ApprovalInstanceListPage({\n defaultState,\n description,\n emptyMessage,\n searchPlaceholder,\n title,\n view,\n}: ApprovalInstanceListPageProps): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const [error, setError] = useState<string | null>(null);\n const [initiatorProfilesById, setInitiatorProfilesById] = useState<\n ReadonlyMap<string, MemberProfileRecord>\n >(new Map());\n const [instancePage, setInstancePage] = useState(1);\n const [instancePageSize, setInstancePageSize] = useState(10);\n const [instanceTotalCount, setInstanceTotalCount] = useState(0);\n const [loading, setLoading] = useState(true);\n const [rows, setRows] = useState<readonly ApprovalInstanceRow[]>([]);\n const [searchText, setSearchText] = useState('');\n const [stateFilter, setStateFilter] = useState<StateFilterOption>(\n readStateFilterOption(defaultState),\n );\n const refreshRequestIdRef = useRef(0);\n\n const refreshInstances = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n setLoading(true);\n setError(null);\n\n try {\n const result = await listApprovalInstancesPage({\n page: instancePage,\n pageSize: instancePageSize,\n searchText,\n state: stateFilter.state,\n templateId: null,\n view,\n });\n\n if (requestId !== refreshRequestIdRef.current) {\n return;\n }\n\n setRows(result.instances.map(readApprovalInstanceRow));\n setInstanceTotalCount(result.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 }, [instancePage, instancePageSize, searchText, stateFilter, view]);\n\n useEffect((): void => {\n void refreshInstances();\n }, [refreshInstances]);\n\n useEffect((): (() => void) | void => {\n const initiatorMemberIds = Array.from(\n new Set(rows.map((row) => row.initiatorMemberId).filter(Boolean)),\n );\n\n if (initiatorMemberIds.length === 0) {\n setInitiatorProfilesById(new Map());\n\n return;\n }\n\n let cancelled = false;\n\n void (async (): Promise<void> => {\n try {\n const profiles = await resolveMembers(initiatorMemberIds);\n\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(\n new Map(profiles.map((profile) => [profile.memberId, profile])),\n );\n } catch {\n if (cancelled) {\n return;\n }\n\n setInitiatorProfilesById(new Map());\n }\n })();\n\n return (): void => {\n cancelled = true;\n };\n }, [rows]);\n\n const columns = useMemo(\n (): TableColumn<ApprovalInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 300 },\n {\n key: 'state',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.state)}\n component=\"span\"\n variant=\"body\"\n >\n {record.stateLabel}\n </Typography>\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'initiatorMemberId',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {readInitiatorLabel(\n record.initiatorMemberId,\n initiatorProfilesById,\n )}\n </Typography>\n ),\n title: '發起人',\n width: 180,\n },\n {\n key: 'startedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n {\n key: 'completedAt',\n render: (record: ApprovalInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.completedAt)}\n </Typography>\n ),\n title: '完成時間',\n width: 220,\n },\n ],\n [initiatorProfilesById],\n );\n const tableActions = useMemo(\n (): TableActions<ApprovalInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalInstanceRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router],\n );\n\n return (\n <>\n <PageHeader>\n <ContentHeader description={description} title={title} />\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.instanceFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setInstancePage(1);\n }}\n placeholder={searchPlaceholder}\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"instanceState\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setStateFilter(readSelectedStateFilterOption(option));\n setInstancePage(1);\n }}\n options={[...STATE_FILTER_OPTIONS]}\n placeholder=\"狀態\"\n renderValue={(value): string =>\n `狀態:${readStateFilterLabel(value)}`\n }\n size=\"sub\"\n value={stateFilter}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {!error && !loading && rows.length === 0 ? (\n <Typography color=\"text-neutral\" variant=\"body\">\n {emptyMessage}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={[...rows]}\n fullWidth\n loading={loading}\n pagination={{\n current: instancePage,\n onChange: (page): void => {\n setInstancePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setInstancePage(1);\n setInstancePageSize(pageSize);\n },\n pageSize: instancePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: INSTANCE_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: instanceTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readApprovalInstanceRow(\n instance: ApprovalInstanceRecord,\n): ApprovalInstanceRow {\n return {\n ...instance,\n caseTitle: readApprovalInstanceCaseTitle(instance),\n key: instance.id,\n stateLabel: readInstanceStateLabel(instance.state),\n };\n}\n\nfunction readSelectedStateFilterOption(option: unknown): StateFilterOption {\n if (!isStateFilterOption(option)) {\n return STATE_FILTER_OPTIONS[0];\n }\n return readStateFilterOption(option.state);\n}\n\nfunction readStateFilterOption(\n state: ApprovalInstanceState | null,\n): StateFilterOption {\n return (\n STATE_FILTER_OPTIONS.find((option) => option.state === state) ??\n STATE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readStateFilterLabel(value: unknown): string {\n return isStateFilterOption(value) ? value.name : STATE_FILTER_OPTIONS[0].name;\n}\n\nfunction isStateFilterOption(value: unknown): value is StateFilterOption {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'id' in value &&\n 'name' in value &&\n 'state' in value\n );\n}\n\nfunction readInstanceStateLabel(state: ApprovalInstanceState): string {\n if (state === 'RUNNING') return '進行中';\n if (state === 'APPROVED') return '已通過';\n if (state === 'REJECTED') return '已拒絕';\n if (state === 'RETURNED') return '已退回';\n if (state === 'CANCELLED') return '已取消';\n if (state === 'EXPIRED') return '已逾期';\n return '草稿';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceState,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') return 'text-success';\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n return 'text-neutral';\n}\n\nfunction readInitiatorLabel(\n initiatorMemberId: string | null | undefined,\n initiatorProfilesById: ReadonlyMap<string, MemberProfileRecord>,\n): string {\n const trimmedMemberId = (initiatorMemberId ?? '').trim();\n if (!trimmedMemberId) return '未知發起人';\n return initiatorProfilesById.get(trimmedMemberId)?.name ?? trimmedMemberId;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取簽核案件失敗。';\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider-4BeCw7cI.cjs","names":["createContext","useRouterAdapter","useState","useCallback","readApiCurrentMember","loginApi","logoutApi","useMemo","useContext","styles","Typography","require_router_adapter","react","_mezzanine_ui_react","_rytass_bpm_core_client","react_jsx_runtime","auth_provider_module_default","AuthContext","AuthProvider","router","loading","setLoading","member","setMember","refresh","current","login","next","input","logout","loginPath","active","isPublicPath","publicPaths","readCurrentPath","value","AuthLoadingState","useAuth","ctx","label","p","pathname"],"sources":["../../src/lib/auth-provider.module.scss","../../src/lib/auth-provider.tsx"],"sourcesContent":[".authLoading {\n align-items: center;\n background: var(--mzn-color-bg-body);\n display: flex;\n min-height: 100vh;\n justify-content: center;\n padding: 32px;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport {\n loginApi,\n logoutApi,\n readApiCurrentMember,\n type ApiMember,\n} from '@rytass/bpm-core-client';\nimport { useRouterAdapter } from './router-adapter';\nimport styles from './auth-provider.module.scss';\n\ninterface AuthContextValue {\n readonly loading: boolean;\n readonly member: ApiMember | null;\n readonly login: (input: {\n readonly identifier: string;\n readonly password: string;\n }) => Promise<ApiMember>;\n readonly logout: () => Promise<void>;\n readonly refresh: () => Promise<ApiMember | null>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n readonly children: ReactNode;\n /**\n * Paths that should not redirect to `/login` when there is no session.\n * Defaults to `['/login']`. Override when your host runs the login UI\n * under a different path.\n */\n readonly publicPaths?: readonly string[];\n /**\n * Where to send unauthenticated users. Defaults to `'/login'`.\n */\n readonly loginPath?: string;\n}\n\n/**\n * BPM auth context provider. Reads / writes the host BPM API session via\n * `@rytass/bpm-core-client` (`loginApi` / `logoutApi` / `readApiCurrentMember`)\n * and uses the host-supplied {@link useRouterAdapter} to redirect\n * unauthenticated users.\n */\nexport function AuthProvider({\n children,\n publicPaths = ['/login'],\n loginPath = '/login',\n}: AuthProviderProps): ReactElement {\n const router = useRouterAdapter();\n const [loading, setLoading] = useState(true);\n const [member, setMember] = useState<ApiMember | null>(null);\n\n const refresh = useCallback(async (): Promise<ApiMember | null> => {\n const current = await readApiCurrentMember();\n setMember(current);\n return current;\n }, []);\n\n const login = useCallback(\n async (input: {\n readonly identifier: string;\n readonly password: string;\n }): Promise<ApiMember> => {\n const next = await loginApi(input);\n setMember(next);\n return next;\n },\n [],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n await logoutApi();\n setMember(null);\n router.replace(loginPath);\n }, [loginPath, router]);\n\n useEffect((): (() => void) => {\n let active = true;\n setLoading(true);\n void (async () => {\n try {\n const current = await readApiCurrentMember();\n if (active) setMember(current);\n } catch {\n if (active) setMember(null);\n } finally {\n if (active) setLoading(false);\n }\n })();\n return (): void => {\n active = false;\n };\n }, []);\n\n useEffect((): void => {\n if (loading || isPublicPath(router.pathname, publicPaths) || member) return;\n router.replace(\n `${loginPath}?next=${encodeURIComponent(readCurrentPath(router.pathname))}`,\n );\n }, [loading, loginPath, member, publicPaths, router]);\n\n const value = useMemo<AuthContextValue>(\n () => ({ loading, login, logout, member, refresh }),\n [loading, login, logout, member, refresh],\n );\n\n if (loading && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"確認登入狀態\" />;\n }\n if (!loading && !member && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"前往登入頁\" />;\n }\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Access the BPM auth context. Throws when used outside `<AuthProvider>`.\n */\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');\n return ctx;\n}\n\nfunction AuthLoadingState({\n label,\n}: {\n readonly label: string;\n}): ReactElement {\n return (\n <main className={styles.authLoading}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {label}\n </Typography>\n </main>\n );\n}\n\nfunction isPublicPath(\n pathname: string | null,\n publicPaths: readonly string[],\n): boolean {\n return publicPaths.some((p) => p === pathname);\n}\n\nfunction readCurrentPath(pathname: string | null): string {\n if (typeof window === 'undefined') return pathname ?? '/';\n return `${window.location.pathname}${window.location.search}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth-provider-4BeCw7cI.cjs","names":["createContext","useRouterAdapter","useState","useCallback","readApiCurrentMember","loginApi","logoutApi","useMemo","useContext","styles","Typography","require_router_adapter","react","_mezzanine_ui_react","_rytass_bpm_core_client","react_jsx_runtime","auth_provider_module_default","AuthContext","AuthProvider","router","loading","setLoading","member","setMember","refresh","current","login","next","input","logout","loginPath","active","isPublicPath","publicPaths","readCurrentPath","value","AuthLoadingState","useAuth","ctx","label","p","pathname"],"sources":["../../src/lib/auth-provider.module.scss","../../src/lib/auth-provider.tsx"],"sourcesContent":[".authLoading {\n align-items: center;\n background: var(--mzn-color-bg-body);\n display: flex;\n min-height: 100vh;\n justify-content: center;\n padding: 32px;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport {\n loginApi,\n logoutApi,\n readApiCurrentMember,\n type ApiMember,\n} from '@rytass/bpm-core-client';\nimport { useRouterAdapter } from './router-adapter';\nimport styles from './auth-provider.module.scss';\n\ninterface AuthContextValue {\n readonly loading: boolean;\n readonly member: ApiMember | null;\n readonly login: (input: {\n readonly identifier: string;\n readonly password: string;\n }) => Promise<ApiMember>;\n readonly logout: () => Promise<void>;\n readonly refresh: () => Promise<ApiMember | null>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n readonly children: ReactNode;\n /**\n * Paths that should not redirect to `/login` when there is no session.\n * Defaults to `['/login']`. Override when your host runs the login UI\n * under a different path.\n */\n readonly publicPaths?: readonly string[];\n /**\n * Where to send unauthenticated users. Defaults to `'/login'`.\n */\n readonly loginPath?: string;\n}\n\n/**\n * BPM auth context provider. Reads / writes the host BPM API session via\n * `@rytass/bpm-core-client` (`loginApi` / `logoutApi` / `readApiCurrentMember`)\n * and uses the host-supplied {@link useRouterAdapter} to redirect\n * unauthenticated users.\n */\nexport function AuthProvider({\n children,\n publicPaths = ['/login'],\n loginPath = '/login',\n}: AuthProviderProps): ReactElement {\n const router = useRouterAdapter();\n const [loading, setLoading] = useState(true);\n const [member, setMember] = useState<ApiMember | null>(null);\n\n const refresh = useCallback(async (): Promise<ApiMember | null> => {\n const current = await readApiCurrentMember();\n setMember(current);\n return current;\n }, []);\n\n const login = useCallback(\n async (input: {\n readonly identifier: string;\n readonly password: string;\n }): Promise<ApiMember> => {\n const next = await loginApi(input);\n setMember(next);\n return next;\n },\n [],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n await logoutApi();\n setMember(null);\n router.replace(loginPath);\n }, [loginPath, router]);\n\n useEffect((): (() => void) => {\n let active = true;\n setLoading(true);\n void (async () => {\n try {\n const current = await readApiCurrentMember();\n if (active) setMember(current);\n } catch {\n if (active) setMember(null);\n } finally {\n if (active) setLoading(false);\n }\n })();\n return (): void => {\n active = false;\n };\n }, []);\n\n useEffect((): void => {\n if (loading || isPublicPath(router.pathname, publicPaths) || member) return;\n router.replace(\n `${loginPath}?next=${encodeURIComponent(readCurrentPath(router.pathname))}`,\n );\n }, [loading, loginPath, member, publicPaths, router]);\n\n const value = useMemo<AuthContextValue>(\n () => ({ loading, login, logout, member, refresh }),\n [loading, login, logout, member, refresh],\n );\n\n if (loading && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"確認登入狀態\" />;\n }\n if (!loading && !member && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"前往登入頁\" />;\n }\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Access the BPM auth context. Throws when used outside `<AuthProvider>`.\n */\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');\n return ctx;\n}\n\nfunction AuthLoadingState({\n label,\n}: {\n readonly label: string;\n}): ReactElement {\n return (\n <main className={styles.authLoading}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {label}\n </Typography>\n </main>\n );\n}\n\nfunction isPublicPath(\n pathname: string | null,\n publicPaths: readonly string[],\n): boolean {\n return publicPaths.some((p) => p === pathname);\n}\n\nfunction readCurrentPath(pathname: string | null): string {\n if (typeof window === 'undefined') return pathname ?? '/';\n return `${window.location.pathname}${window.location.search}`;\n}\n"],"mappings":"A,sOCiCMiB,GAAA,EAAcjB,EAAAA,cAAAA,CAAuC,IAAI,EAsB/D,SAAgBkB,EAAa,CAC3B,WACA,cAAc,CAAC,QAAQ,EACvB,YAAY,UACsB,CAClC,IAAMC,EAASlB,EAAAA,EAAiB,EAC1B,CAACmB,EAASC,IAAA,EAAcnB,EAAAA,SAAAA,CAAS,EAAI,EACrC,CAACoB,EAAQC,IAAA,EAAarB,EAAAA,SAAAA,CAA2B,IAAI,EAErDsB,GAAA,EAAUrB,EAAAA,YAAAA,CAAY,SAAuC,CACjE,IAAMsB,EAAU,MAAA,EAAMrB,EAAAA,qBAAAA,CAAqB,EAE3C,OADAmB,EAAUE,CAAO,EACVA,CACT,EAAG,CAAC,CAAC,EAECC,GAAA,EAAQvB,EAAAA,YAAAA,CACZ,KAAO,IAGmB,CACxB,IAAMwB,EAAO,MAAA,EAAMtB,EAAAA,SAAAA,CAASuB,CAAK,EAEjC,OADAL,EAAUI,CAAI,EACPA,CACT,EACA,CAAC,CACH,EAEME,GAAA,EAAS1B,EAAAA,YAAAA,CAAY,SAA2B,CACpD,MAAA,EAAMG,EAAAA,UAAAA,CAAU,EAChBiB,EAAU,IAAI,EACdJ,EAAO,QAAQW,CAAS,CAC1B,EAAG,CAACA,EAAWX,CAAM,CAAC,GAEtB,EAAAP,EAAA,UAAA,KAA8B,CAC5B,IAAImB,EAAS,GAYb,OAXAV,EAAW,EAAI,GACT,SAAY,CAChB,GAAI,CACF,IAAMI,EAAU,MAAA,EAAMrB,EAAAA,qBAAAA,CAAqB,EACvC2B,GAAQR,EAAUE,CAAO,CAC/B,MAAQ,CACFM,GAAQR,EAAU,IAAI,CAC5B,QAAU,CACJQ,GAAQV,EAAW,EAAK,CAC9B,CACF,EAAA,CAAG,MACgB,CACjB,EAAS,EACX,CACF,EAAG,CAAC,CAAC,GAEL,EAAAT,EAAA,UAAA,KAAsB,CAChBQ,GAAWY,EAAab,EAAO,SAAUc,CAAW,GAAKX,GAC7DH,EAAO,QACL,GAAGW,EAAU,QAAQ,mBAAmBI,EAAgBf,EAAO,QAAQ,CAAC,GAC1E,CACF,EAAG,CAACC,EAASU,EAAWR,EAAQW,EAAad,CAAM,CAAC,EAEpD,IAAMgB,GAAA,EAAQ5B,EAAAA,QAAAA,MACL,CAAE,UAAS,QAAO,SAAQ,SAAQ,SAAQ,GACjD,CAACa,EAASM,EAAOG,EAAQP,EAAQE,CAAO,CAC1C,EAQA,OANIJ,GAAW,CAACY,EAAab,EAAO,SAAUc,CAAW,GAChD,EAAAlB,EAAA,IAAA,CAACqB,EAAD,CAAkB,MAAM,QAAU,CAAA,EAEvC,CAAChB,GAAW,CAACE,GAAU,CAACU,EAAab,EAAO,SAAUc,CAAW,GAC5D,EAAAlB,EAAA,IAAA,CAACqB,EAAD,CAAkB,MAAM,OAAS,CAAA,GAEnC,EAAArB,EAAA,IAAA,CAACE,EAAY,SAAb,CAA6B,QAAQ,UAA+B,CAAA,CAC7E,CAKA,SAAgBoB,GAA4B,CAC1C,IAAMC,GAAA,EAAM9B,EAAAA,WAAAA,CAAWS,CAAW,EAClC,GAAI,CAACqB,EAAK,MAAU,MAAM,4CAA4C,EACtE,OAAOA,CACT,CAEA,SAASF,EAAiB,CACxB,SAGe,CACf,OACE,EAAArB,EAAA,IAAA,CAAC,OAAD,CAAM,UAAWN,EAAO,YACtB,UAAA,EAAAM,EAAA,IAAA,CAACL,EAAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,OACtC,SAAA6B,CACS,CAAA,CACR,CAAA,CAEV,CAEA,SAASP,EACP,EACA,EACS,CACT,OAAOC,EAAY,KAAM,GAAMO,IAAMC,CAAQ,CAC/C,CAEA,SAASP,EAAgB,EAAiC,CAExD,OADI,OAAO,OAAW,IAAoBO,GAAY,IAC/C,GAAG,OAAO,SAAS,WAAW,OAAO,SAAS,QACvD,C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { r as e } from "./router-adapter-
|
|
2
|
+
import { r as e } from "./router-adapter-CkxCyzf5.js";
|
|
3
3
|
import { createContext as t, useCallback as n, useContext as r, useEffect as i, useMemo as a, useState as o } from "react";
|
|
4
4
|
import { Typography as s } from "@mezzanine-ui/react";
|
|
5
5
|
import { loginApi as c, logoutApi as l, readApiCurrentMember as u } from "@rytass/bpm-core-client";
|
|
@@ -77,7 +77,6 @@ function _(e, t) {
|
|
|
77
77
|
function v(e) {
|
|
78
78
|
return typeof window > "u" ? e ?? "/" : `${window.location.pathname}${window.location.search}`;
|
|
79
79
|
}
|
|
80
|
-
//#endregion
|
|
81
80
|
export { h as n, m as t };
|
|
82
81
|
|
|
83
|
-
//# sourceMappingURL=auth-provider-
|
|
82
|
+
//# sourceMappingURL=auth-provider-C2b-5mGt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider-
|
|
1
|
+
{"version":3,"file":"auth-provider-C2b-5mGt.js","names":["styles","useRouterAdapter","auth_provider_module_default","AuthContext","createContext","AuthProvider","router","loading","setLoading","useState","member","setMember","refresh","useCallback","current","readApiCurrentMember","login","next","loginApi","input","logout","logoutApi","loginPath","useEffect","active","isPublicPath","publicPaths","readCurrentPath","value","useMemo","AuthLoadingState","useAuth","ctx","useContext","Typography","label","p","pathname"],"sources":["../../src/lib/auth-provider.module.scss","../../src/lib/auth-provider.tsx"],"sourcesContent":[".authLoading {\n align-items: center;\n background: var(--mzn-color-bg-body);\n display: flex;\n min-height: 100vh;\n justify-content: center;\n padding: 32px;\n}\n","'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport { Typography } from '@mezzanine-ui/react';\nimport {\n loginApi,\n logoutApi,\n readApiCurrentMember,\n type ApiMember,\n} from '@rytass/bpm-core-client';\nimport { useRouterAdapter } from './router-adapter';\nimport styles from './auth-provider.module.scss';\n\ninterface AuthContextValue {\n readonly loading: boolean;\n readonly member: ApiMember | null;\n readonly login: (input: {\n readonly identifier: string;\n readonly password: string;\n }) => Promise<ApiMember>;\n readonly logout: () => Promise<void>;\n readonly refresh: () => Promise<ApiMember | null>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n readonly children: ReactNode;\n /**\n * Paths that should not redirect to `/login` when there is no session.\n * Defaults to `['/login']`. Override when your host runs the login UI\n * under a different path.\n */\n readonly publicPaths?: readonly string[];\n /**\n * Where to send unauthenticated users. Defaults to `'/login'`.\n */\n readonly loginPath?: string;\n}\n\n/**\n * BPM auth context provider. Reads / writes the host BPM API session via\n * `@rytass/bpm-core-client` (`loginApi` / `logoutApi` / `readApiCurrentMember`)\n * and uses the host-supplied {@link useRouterAdapter} to redirect\n * unauthenticated users.\n */\nexport function AuthProvider({\n children,\n publicPaths = ['/login'],\n loginPath = '/login',\n}: AuthProviderProps): ReactElement {\n const router = useRouterAdapter();\n const [loading, setLoading] = useState(true);\n const [member, setMember] = useState<ApiMember | null>(null);\n\n const refresh = useCallback(async (): Promise<ApiMember | null> => {\n const current = await readApiCurrentMember();\n setMember(current);\n return current;\n }, []);\n\n const login = useCallback(\n async (input: {\n readonly identifier: string;\n readonly password: string;\n }): Promise<ApiMember> => {\n const next = await loginApi(input);\n setMember(next);\n return next;\n },\n [],\n );\n\n const logout = useCallback(async (): Promise<void> => {\n await logoutApi();\n setMember(null);\n router.replace(loginPath);\n }, [loginPath, router]);\n\n useEffect((): (() => void) => {\n let active = true;\n setLoading(true);\n void (async () => {\n try {\n const current = await readApiCurrentMember();\n if (active) setMember(current);\n } catch {\n if (active) setMember(null);\n } finally {\n if (active) setLoading(false);\n }\n })();\n return (): void => {\n active = false;\n };\n }, []);\n\n useEffect((): void => {\n if (loading || isPublicPath(router.pathname, publicPaths) || member) return;\n router.replace(\n `${loginPath}?next=${encodeURIComponent(readCurrentPath(router.pathname))}`,\n );\n }, [loading, loginPath, member, publicPaths, router]);\n\n const value = useMemo<AuthContextValue>(\n () => ({ loading, login, logout, member, refresh }),\n [loading, login, logout, member, refresh],\n );\n\n if (loading && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"確認登入狀態\" />;\n }\n if (!loading && !member && !isPublicPath(router.pathname, publicPaths)) {\n return <AuthLoadingState label=\"前往登入頁\" />;\n }\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\n/**\n * Access the BPM auth context. Throws when used outside `<AuthProvider>`.\n */\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error('useAuth must be used inside <AuthProvider>');\n return ctx;\n}\n\nfunction AuthLoadingState({\n label,\n}: {\n readonly label: string;\n}): ReactElement {\n return (\n <main className={styles.authLoading}>\n <Typography color=\"text-neutral\" variant=\"body\">\n {label}\n </Typography>\n </main>\n );\n}\n\nfunction isPublicPath(\n pathname: string | null,\n publicPaths: readonly string[],\n): boolean {\n return publicPaths.some((p) => p === pathname);\n}\n\nfunction readCurrentPath(pathname: string | null): string {\n if (typeof window === 'undefined') return pathname ?? '/';\n return `${window.location.pathname}${window.location.search}`;\n}\n"],"mappings":";;;;;;A,kDCiCMG,IAAcC,EAAuC,IAAI;AAsB/D,SAAgBC,EAAa,EAC3B,aACA,iBAAc,CAAC,QAAQ,GACvB,eAAY,YACsB;CAClC,IAAMC,IAASL,EAAiB,GAC1B,CAACM,GAASC,KAAcC,EAAS,EAAI,GACrC,CAACC,GAAQC,KAAaF,EAA2B,IAAI,GAErDG,IAAUC,EAAY,YAAuC;EACjE,IAAMC,IAAU,MAAMC,EAAqB;EAE3C,OADAJ,EAAUG,CAAO,GACVA;CACT,GAAG,CAAC,CAAC,GAECE,IAAQH,EACZ,OAAO,MAGmB;EACxB,IAAMI,IAAO,MAAMC,EAASC,CAAK;EAEjC,OADAR,EAAUM,CAAI,GACPA;CACT,GACA,CAAC,CACH,GAEMG,IAASP,EAAY,YAA2B;EAGpD,AAFA,MAAMQ,EAAU,GAChBV,EAAU,IAAI,GACdL,EAAO,QAAQgB,CAAS;CAC1B,GAAG,CAACA,GAAWhB,CAAM,CAAC;CAoBtB,AAlBAiB,QAA8B;EAC5B,IAAIC,IAAS;EAYb,OAXAhB,EAAW,EAAI,IACT,YAAY;GAChB,IAAI;IACF,IAAMM,IAAU,MAAMC,EAAqB;IAC3C,AAAIS,KAAQb,EAAUG,CAAO;GAC/B,QAAQ;IACN,AAAIU,KAAQb,EAAU,IAAI;GAC5B,UAAU;IACR,AAAIa,KAAQhB,EAAW,EAAK;GAC9B;EACF,EAAA,CAAG,SACgB;GACjB,IAAS;EACX;CACF,GAAG,CAAC,CAAC,GAELe,QAAsB;EACpB,AAAIhB,KAAWkB,EAAanB,EAAO,UAAUoB,CAAW,KAAKhB,KAC7DJ,EAAO,QACL,GAAGgB,EAAU,QAAQ,mBAAmBK,EAAgBrB,EAAO,QAAQ,CAAC,GAC1E;CACF,GAAG;EAACC;EAASe;EAAWZ;EAAQgB;EAAapB;CAAM,CAAC;CAEpD,IAAMsB,IAAQC,SACL;EAAE;EAAS;EAAO;EAAQ;EAAQ;CAAQ,IACjD;EAACtB;EAASS;EAAOI;EAAQV;EAAQE;CAAO,CAC1C;CAQA,OANIL,KAAW,CAACkB,EAAanB,EAAO,UAAUoB,CAAW,IAChD,kBAACI,GAAD,EAAkB,OAAM,SAAU,CAAA,IAEvC,CAACvB,KAAW,CAACG,KAAU,CAACe,EAAanB,EAAO,UAAUoB,CAAW,IAC5D,kBAACI,GAAD,EAAkB,OAAM,QAAS,CAAA,IAEnC,kBAAC3B,EAAY,UAAb;EAA6B;EAAQ;CAA+B,CAAA;AAC7E;AAKA,SAAgB4B,IAA4B;CAC1C,IAAMC,IAAMC,EAAW9B,CAAW;CAClC,IAAI,CAAC6B,GAAK,MAAU,MAAM,4CAA4C;CACtE,OAAOA;AACT;AAEA,SAASF,EAAiB,EACxB,YAGe;CACf,OACE,kBAAC,QAAD;EAAM,WAAW9B,EAAO;EACtB,UAAA,kBAACkC,GAAD;GAAY,OAAM;GAAe,SAAQ;GACtC,UAAAC;EACS,CAAA;CACR,CAAA;AAEV;AAEA,SAASV,EACP,GACA,GACS;CACT,OAAOC,EAAY,MAAM,MAAMU,MAAMC,CAAQ;AAC/C;AAEA,SAASV,EAAgB,GAAiC;CAExD,OADI,OAAO,SAAW,MAAoBU,KAAY,MAC/C,GAAG,OAAO,SAAS,WAAW,OAAO,SAAS;AACvD"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { FormField as e } from "@mezzanine-ui/react";
|
|
3
3
|
import { jsx as t } from "react/jsx-runtime";
|
|
4
4
|
import { FormFieldDensity as n, FormFieldLayout as r } from "@mezzanine-ui/core/form";
|
|
5
|
-
|
|
5
|
+
// src/components/bpm-form-field.tsx
|
|
6
6
|
function i({ density: i = n.TIGHT, fullWidth: a = !0, layout: o = r.HORIZONTAL, ...s }) {
|
|
7
7
|
return /* @__PURE__ */ t(e, {
|
|
8
8
|
density: i,
|
|
@@ -11,7 +11,6 @@ function i({ density: i = n.TIGHT, fullWidth: a = !0, layout: o = r.HORIZONTAL,
|
|
|
11
11
|
...s
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
//#endregion
|
|
15
14
|
export { i as t };
|
|
16
15
|
|
|
17
|
-
//# sourceMappingURL=bpm-form-field-
|
|
16
|
+
//# sourceMappingURL=bpm-form-field-9B-Det0u.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bpm-form-field-
|
|
1
|
+
{"version":3,"file":"bpm-form-field-9B-Det0u.js","names":["BPMFormField","FormFieldDensity","FormFieldLayout","props","FormField"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":";;;;;AAiBA,SAAgBA,EAAa,EAC3B,aAAUC,EAAiB,OAC3B,eAAY,IACZ,YAASC,EAAgB,YACzB,GAAGC,KAC+B;CAClC,OACE,kBAACC,GAAD;EACW;EACE;EACH;EACR,GAAID;CACL,CAAA;AAEL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bpm-form-field-Bc6k4ZEO.cjs","names":["FormFieldDensity","FormFieldLayout","FormField","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","BPMFormField","props"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":"sHAiBA,SAAgBM,EAAa,CAC3B,UAAUN,EAAAA,iBAAiB,MAC3B,YAAY,GACZ,SAASC,EAAAA,gBAAgB,WACzB,GAAGM,GAC+B,CAClC,OACE,EAAAH,EAAA,IAAA,CAACF,EAAAA,UAAD,CACW,UACE,YACH,SACR,GAAIK,CACL,CAAA,CAEL"}
|
|
1
|
+
{"version":3,"file":"bpm-form-field-Bc6k4ZEO.cjs","names":["FormFieldDensity","FormFieldLayout","FormField","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_core_form","BPMFormField","props"],"sources":["../../src/components/bpm-form-field.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactElement } from 'react';\nimport { FormField, type FormFieldProps } from '@mezzanine-ui/react';\nimport { FormFieldDensity, FormFieldLayout } from '@mezzanine-ui/core/form';\n\ntype BPMFormFieldProps = Omit<\n FormFieldProps,\n 'density' | 'fullWidth' | 'layout'\n> &\n Partial<Pick<FormFieldProps, 'density' | 'fullWidth' | 'layout'>>;\n\n/**\n * Mezzanine `<FormField>` pre-configured with the BPM admin defaults\n * (`TIGHT` density, `HORIZONTAL` layout, full width). Use everywhere a\n * label-aligned field is needed.\n */\nexport function BPMFormField({\n density = FormFieldDensity.TIGHT,\n fullWidth = true,\n layout = FormFieldLayout.HORIZONTAL,\n ...props\n}: BPMFormFieldProps): ReactElement {\n return (\n <FormField\n density={density}\n fullWidth={fullWidth}\n layout={layout}\n {...props}\n />\n );\n}\n"],"mappings":"A,sHAiBA,SAAgBM,EAAa,CAC3B,UAAUN,EAAAA,iBAAiB,MAC3B,YAAY,GACZ,SAASC,EAAAA,gBAAgB,WACzB,GAAGM,GAC+B,CAClC,OACE,EAAAH,EAAA,IAAA,CAACF,EAAAA,UAAD,CACW,UACE,YACH,SACR,GAAIK,CACL,CAAA,CAEL,C"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as e } from "./
|
|
3
|
-
import { t } from "./
|
|
2
|
+
import { t as e } from "./bpm-form-field-9B-Det0u.js";
|
|
3
|
+
import { t } from "./format-date-time-B0LdmWg4.js";
|
|
4
4
|
import { useCallback as n, useEffect as r, useMemo as i, useState as a } from "react";
|
|
5
5
|
import { Badge as o, Button as s, Filter as c, FilterArea as l, FilterLine as u, FormField as d, Input as f, Modal as p, PageHeader as m, Section as h, SectionGroup as g, Tab as _, TabItem as v, Table as y, Textarea as b, Typography as x } from "@mezzanine-ui/react";
|
|
6
6
|
import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
@@ -30,7 +30,7 @@ import '../categories.css';var A = {
|
|
|
30
30
|
}
|
|
31
31
|
];
|
|
32
32
|
function N() {
|
|
33
|
-
let [
|
|
33
|
+
let [e, o] = a([]), [b, N] = a(1), [F, I] = a(10), [L, R] = a("ALL"), [z, B] = a(0), [V, H] = a(null), [U, W] = a(null), [G, K] = a(!0), [q, J] = a(null), [Y, X] = a(!1), [Z, oe] = a(""), Q = n(async () => {
|
|
34
34
|
K(!0), W(null);
|
|
35
35
|
try {
|
|
36
36
|
let e = await O({
|
|
@@ -54,11 +54,11 @@ function N() {
|
|
|
54
54
|
r(() => {
|
|
55
55
|
Q();
|
|
56
56
|
}, [Q]);
|
|
57
|
-
let se = i(() =>
|
|
58
|
-
...
|
|
59
|
-
key:
|
|
60
|
-
updatedAtLabel: e
|
|
61
|
-
})), [
|
|
57
|
+
let se = i(() => e.map((e) => ({
|
|
58
|
+
...e,
|
|
59
|
+
key: e.id,
|
|
60
|
+
updatedAtLabel: t(e.updatedAt)
|
|
61
|
+
})), [e]), ce = i(() => [
|
|
62
62
|
{
|
|
63
63
|
dataIndex: "name",
|
|
64
64
|
key: "name",
|
|
@@ -266,7 +266,7 @@ function N() {
|
|
|
266
266
|
})
|
|
267
267
|
] });
|
|
268
268
|
}
|
|
269
|
-
function ne({ loading:
|
|
269
|
+
function ne({ loading: t, modal: n, onClose: i, onSubmit: o }) {
|
|
270
270
|
let [s, c] = a(""), [l, u] = a(null), [d, m] = a(""), [h, g] = a("0");
|
|
271
271
|
r(() => {
|
|
272
272
|
n && (c(n.record?.description ?? ""), u(null), m(n.record?.name ?? ""), g(String(n.record?.sortOrder ?? 0)));
|
|
@@ -290,7 +290,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
|
|
|
290
290
|
cancelText: "取消",
|
|
291
291
|
confirmButtonProps: { disabled: !d.trim() },
|
|
292
292
|
confirmText: n?.type === "EDIT" ? "儲存" : "建立",
|
|
293
|
-
loading:
|
|
293
|
+
loading: t,
|
|
294
294
|
modalType: "standard",
|
|
295
295
|
onCancel: i,
|
|
296
296
|
onClose: i,
|
|
@@ -303,7 +303,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
|
|
|
303
303
|
children: [/* @__PURE__ */ w("div", {
|
|
304
304
|
className: A.templateModalFields,
|
|
305
305
|
children: [
|
|
306
|
-
/* @__PURE__ */ C(
|
|
306
|
+
/* @__PURE__ */ C(e, {
|
|
307
307
|
label: "分類名稱",
|
|
308
308
|
name: "categoryName",
|
|
309
309
|
required: !0,
|
|
@@ -318,7 +318,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
|
|
|
318
318
|
variant: "base"
|
|
319
319
|
})
|
|
320
320
|
}),
|
|
321
|
-
/* @__PURE__ */ C(
|
|
321
|
+
/* @__PURE__ */ C(e, {
|
|
322
322
|
label: "排序",
|
|
323
323
|
name: "categorySortOrder",
|
|
324
324
|
children: /* @__PURE__ */ C(f, {
|
|
@@ -331,7 +331,7 @@ function ne({ loading: e, modal: n, onClose: i, onSubmit: o }) {
|
|
|
331
331
|
variant: "base"
|
|
332
332
|
})
|
|
333
333
|
}),
|
|
334
|
-
/* @__PURE__ */ C(
|
|
334
|
+
/* @__PURE__ */ C(e, {
|
|
335
335
|
label: "說明",
|
|
336
336
|
name: "categoryDescription",
|
|
337
337
|
children: /* @__PURE__ */ C(b, {
|
|
@@ -370,7 +370,6 @@ function ae(e) {
|
|
|
370
370
|
function P(e) {
|
|
371
371
|
return e instanceof Error ? e.message : "發生未知錯誤";
|
|
372
372
|
}
|
|
373
|
-
//#endregion
|
|
374
373
|
export { A as n, N as t };
|
|
375
374
|
|
|
376
|
-
//# sourceMappingURL=categories-
|
|
375
|
+
//# sourceMappingURL=categories-BAdxjNSA.js.map
|