@rytass/bpm-core-react 0.2.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/LICENSE +21 -0
- package/README.md +56 -0
- package/dist/AdminDelegationsView.css +1 -0
- package/dist/AdminOrgsView.css +1 -0
- package/dist/AdminUsersView.css +1 -0
- package/dist/DelegationsView.css +1 -0
- package/dist/InstanceDetailView.css +1 -0
- package/dist/LoginView.css +1 -0
- package/dist/SettingsNotificationsView.css +1 -0
- package/dist/admin-pickers.css +1 -0
- package/dist/app-navigation.css +1 -0
- package/dist/approval-instance-list-page.css +1 -0
- package/dist/auth-provider.css +1 -0
- package/dist/chunks/AdminDelegationsView-CqNmlVWx.cjs +2 -0
- package/dist/chunks/AdminDelegationsView-CqNmlVWx.cjs.map +1 -0
- package/dist/chunks/AdminDelegationsView-DydMZ9ED.js +642 -0
- package/dist/chunks/AdminDelegationsView-DydMZ9ED.js.map +1 -0
- package/dist/chunks/AdminOrgsView-DZaVAbaQ.js +1945 -0
- package/dist/chunks/AdminOrgsView-DZaVAbaQ.js.map +1 -0
- package/dist/chunks/AdminOrgsView-bSsIyMvk.cjs +2 -0
- package/dist/chunks/AdminOrgsView-bSsIyMvk.cjs.map +1 -0
- package/dist/chunks/AdminUsersView-C0oO05Br.js +215 -0
- package/dist/chunks/AdminUsersView-C0oO05Br.js.map +1 -0
- package/dist/chunks/AdminUsersView-DlArLlIr.cjs +2 -0
- package/dist/chunks/AdminUsersView-DlArLlIr.cjs.map +1 -0
- package/dist/chunks/CcView-BsVsya5F.cjs +2 -0
- package/dist/chunks/CcView-BsVsya5F.cjs.map +1 -0
- package/dist/chunks/CcView-Bv0GzA5C.js +19 -0
- package/dist/chunks/CcView-Bv0GzA5C.js.map +1 -0
- package/dist/chunks/DashboardView-Dk1ZQmmk.js +11 -0
- package/dist/chunks/DashboardView-Dk1ZQmmk.js.map +1 -0
- package/dist/chunks/DashboardView-_0zh-rxT.cjs +2 -0
- package/dist/chunks/DashboardView-_0zh-rxT.cjs.map +1 -0
- package/dist/chunks/DelegationsView-DQUqOUV5.js +569 -0
- package/dist/chunks/DelegationsView-DQUqOUV5.js.map +1 -0
- package/dist/chunks/DelegationsView-pKeFV2LN.cjs +2 -0
- package/dist/chunks/DelegationsView-pKeFV2LN.cjs.map +1 -0
- package/dist/chunks/FormBuilderView-BKtyW55e.cjs +3 -0
- package/dist/chunks/FormBuilderView-BKtyW55e.cjs.map +1 -0
- package/dist/chunks/FormBuilderView-CvChAvgD.js +1300 -0
- package/dist/chunks/FormBuilderView-CvChAvgD.js.map +1 -0
- package/dist/chunks/FormRendererView-BwVsH2eX.cjs +2 -0
- package/dist/chunks/FormRendererView-BwVsH2eX.cjs.map +1 -0
- package/dist/chunks/FormRendererView-DrHsuSVo.js +220 -0
- package/dist/chunks/FormRendererView-DrHsuSVo.js.map +1 -0
- package/dist/chunks/FormsView-DYEuik8W.js +185 -0
- package/dist/chunks/FormsView-DYEuik8W.js.map +1 -0
- package/dist/chunks/FormsView-RjJEkIfZ.cjs +2 -0
- package/dist/chunks/FormsView-RjJEkIfZ.cjs.map +1 -0
- package/dist/chunks/InboxView-DDWwmWhA.cjs +2 -0
- package/dist/chunks/InboxView-DDWwmWhA.cjs.map +1 -0
- package/dist/chunks/InboxView-YSoyrYLk.js +291 -0
- package/dist/chunks/InboxView-YSoyrYLk.js.map +1 -0
- package/dist/chunks/InstanceDetailView-C-A-LOCG.js +1519 -0
- package/dist/chunks/InstanceDetailView-C-A-LOCG.js.map +1 -0
- package/dist/chunks/InstanceDetailView-l_kNDCz2.cjs +2 -0
- package/dist/chunks/InstanceDetailView-l_kNDCz2.cjs.map +1 -0
- package/dist/chunks/InstanceNewView-B5hz-FWd.js +190 -0
- package/dist/chunks/InstanceNewView-B5hz-FWd.js.map +1 -0
- package/dist/chunks/InstanceNewView-CdCsxQIu.cjs +2 -0
- package/dist/chunks/InstanceNewView-CdCsxQIu.cjs.map +1 -0
- package/dist/chunks/LoginView-BED07v-7.cjs +2 -0
- package/dist/chunks/LoginView-BED07v-7.cjs.map +1 -0
- package/dist/chunks/LoginView-a1iu3cfc.js +157 -0
- package/dist/chunks/LoginView-a1iu3cfc.js.map +1 -0
- package/dist/chunks/RootClientView-rXJt4TDd.cjs +2 -0
- package/dist/chunks/RootClientView-rXJt4TDd.cjs.map +1 -0
- package/dist/chunks/RootClientView-wAkXUEZw.js +34 -0
- package/dist/chunks/RootClientView-wAkXUEZw.js.map +1 -0
- package/dist/chunks/SearchView-CgXPssgE.cjs +2 -0
- package/dist/chunks/SearchView-CgXPssgE.cjs.map +1 -0
- package/dist/chunks/SearchView-WXMbZwRw.js +19 -0
- package/dist/chunks/SearchView-WXMbZwRw.js.map +1 -0
- package/dist/chunks/SentView-BTDoFBrG.cjs +2 -0
- package/dist/chunks/SentView-BTDoFBrG.cjs.map +1 -0
- package/dist/chunks/SentView-CdOL92Rq.js +19 -0
- package/dist/chunks/SentView-CdOL92Rq.js.map +1 -0
- package/dist/chunks/SettingsNotificationsView-B6F6fa7U.js +194 -0
- package/dist/chunks/SettingsNotificationsView-B6F6fa7U.js.map +1 -0
- package/dist/chunks/SettingsNotificationsView-Bnz0CmoJ.cjs +2 -0
- package/dist/chunks/SettingsNotificationsView-Bnz0CmoJ.cjs.map +1 -0
- package/dist/chunks/TemplateCategoriesView-CgZciaSd.js +382 -0
- package/dist/chunks/TemplateCategoriesView-CgZciaSd.js.map +1 -0
- package/dist/chunks/TemplateCategoriesView-U0stGUBc.cjs +2 -0
- package/dist/chunks/TemplateCategoriesView-U0stGUBc.cjs.map +1 -0
- package/dist/chunks/TemplateDesignerView-A38DyYD4.cjs +51 -0
- package/dist/chunks/TemplateDesignerView-A38DyYD4.cjs.map +1 -0
- package/dist/chunks/TemplateDesignerView-Dffx-VZ-.js +2272 -0
- package/dist/chunks/TemplateDesignerView-Dffx-VZ-.js.map +1 -0
- package/dist/chunks/TemplateVersionsView-6sVQbBem.js +110 -0
- package/dist/chunks/TemplateVersionsView-6sVQbBem.js.map +1 -0
- package/dist/chunks/TemplateVersionsView-CMqw3ieU.cjs +2 -0
- package/dist/chunks/TemplateVersionsView-CMqw3ieU.cjs.map +1 -0
- package/dist/chunks/TemplatesView-BLj9f-XI.js +380 -0
- package/dist/chunks/TemplatesView-BLj9f-XI.js.map +1 -0
- package/dist/chunks/TemplatesView-DIOQTUUl.cjs +2 -0
- package/dist/chunks/TemplatesView-DIOQTUUl.cjs.map +1 -0
- package/dist/chunks/admin-pickers-Btvij1at.cjs +2 -0
- package/dist/chunks/admin-pickers-Btvij1at.cjs.map +1 -0
- package/dist/chunks/admin-pickers-DLlG_1du.js +140 -0
- package/dist/chunks/admin-pickers-DLlG_1du.js.map +1 -0
- package/dist/chunks/app-navigation-CATITRM7.js +263 -0
- package/dist/chunks/app-navigation-CATITRM7.js.map +1 -0
- package/dist/chunks/app-navigation-DAC5gFbG.cjs +2 -0
- package/dist/chunks/app-navigation-DAC5gFbG.cjs.map +1 -0
- package/dist/chunks/approval-instance-list-page-B6vAGvOb.js +278 -0
- package/dist/chunks/approval-instance-list-page-B6vAGvOb.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-DIAmwhvl.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-DIAmwhvl.cjs.map +1 -0
- package/dist/chunks/auth-provider-D2P-qWmY.cjs +2 -0
- package/dist/chunks/auth-provider-D2P-qWmY.cjs.map +1 -0
- package/dist/chunks/auth-provider-TTO9eNZV.js +83 -0
- package/dist/chunks/auth-provider-TTO9eNZV.js.map +1 -0
- package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs +2 -0
- package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -0
- package/dist/chunks/bpm-form-field-Cao0rMol.js +17 -0
- package/dist/chunks/bpm-form-field-Cao0rMol.js.map +1 -0
- package/dist/chunks/dashboard-page-BsW8t104.js +115 -0
- package/dist/chunks/dashboard-page-BsW8t104.js.map +1 -0
- package/dist/chunks/dashboard-page-udYhnyMW.cjs +2 -0
- package/dist/chunks/dashboard-page-udYhnyMW.cjs.map +1 -0
- package/dist/chunks/form-name-modal-C3OEvkCV.js +64 -0
- package/dist/chunks/form-name-modal-C3OEvkCV.js.map +1 -0
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs +2 -0
- package/dist/chunks/form-name-modal-uZCHbtRH.cjs.map +1 -0
- package/dist/chunks/format-date-time-BQyH5U8z.cjs +2 -0
- package/dist/chunks/format-date-time-BQyH5U8z.cjs.map +1 -0
- package/dist/chunks/format-date-time-CB-LxzqT.js +9 -0
- package/dist/chunks/format-date-time-CB-LxzqT.js.map +1 -0
- package/dist/chunks/router-adapter-BdHZXLS3.js +23 -0
- package/dist/chunks/router-adapter-BdHZXLS3.js.map +1 -0
- package/dist/chunks/router-adapter-BybHrCNP.cjs +2 -0
- package/dist/chunks/router-adapter-BybHrCNP.cjs.map +1 -0
- package/dist/chunks/templates.module-B5bg_goX.js +8 -0
- package/dist/chunks/templates.module-B5bg_goX.js.map +1 -0
- package/dist/chunks/templates.module-ClRnQQX4.cjs +2 -0
- package/dist/chunks/templates.module-ClRnQQX4.cjs.map +1 -0
- package/dist/components/admin-pickers.d.ts +65 -0
- package/dist/components/app-navigation.d.ts +34 -0
- package/dist/components/approval-instance-list-page.d.ts +18 -0
- package/dist/components/bpm-form-field.d.ts +10 -0
- package/dist/components/dashboard-page.d.ts +10 -0
- package/dist/components/notification-drawer.d.ts +10 -0
- package/dist/components/org-unit-tree-draft-editor.d.ts +24 -0
- package/dist/components/pdf-preview.d.ts +12 -0
- package/dist/dashboard-page.css +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/auth-provider.d.ts +37 -0
- package/dist/lib/format-date-time.d.ts +5 -0
- package/dist/lib/notification-drawer-provider.d.ts +26 -0
- package/dist/lib/notification-unread-provider.d.ts +24 -0
- package/dist/lib/org-tree-draft.d.ts +27 -0
- package/dist/lib/providers.d.ts +30 -0
- package/dist/lib/router-adapter.d.ts +47 -0
- package/dist/pages/admin/delegations/AdminDelegationsClientView.cjs +2 -0
- package/dist/pages/admin/delegations/AdminDelegationsClientView.cjs.map +1 -0
- package/dist/pages/admin/delegations/AdminDelegationsClientView.d.ts +3 -0
- package/dist/pages/admin/delegations/AdminDelegationsClientView.js +28 -0
- package/dist/pages/admin/delegations/AdminDelegationsClientView.js.map +1 -0
- package/dist/pages/admin/delegations/index.cjs +2 -0
- package/dist/pages/admin/delegations/index.cjs.map +1 -0
- package/dist/pages/admin/delegations/index.d.ts +4 -0
- package/dist/pages/admin/delegations/index.js +14 -0
- package/dist/pages/admin/delegations/index.js.map +1 -0
- package/dist/pages/admin/orgs/AdminOrgsClientView.cjs +2 -0
- package/dist/pages/admin/orgs/AdminOrgsClientView.cjs.map +1 -0
- package/dist/pages/admin/orgs/AdminOrgsClientView.d.ts +3 -0
- package/dist/pages/admin/orgs/AdminOrgsClientView.js +28 -0
- package/dist/pages/admin/orgs/AdminOrgsClientView.js.map +1 -0
- package/dist/pages/admin/orgs/index.cjs +2 -0
- package/dist/pages/admin/orgs/index.cjs.map +1 -0
- package/dist/pages/admin/orgs/index.d.ts +4 -0
- package/dist/pages/admin/orgs/index.js +14 -0
- package/dist/pages/admin/orgs/index.js.map +1 -0
- package/dist/pages/admin/users/AdminUsersClientView.cjs +2 -0
- package/dist/pages/admin/users/AdminUsersClientView.cjs.map +1 -0
- package/dist/pages/admin/users/AdminUsersClientView.d.ts +3 -0
- package/dist/pages/admin/users/AdminUsersClientView.js +28 -0
- package/dist/pages/admin/users/AdminUsersClientView.js.map +1 -0
- package/dist/pages/admin/users/index.cjs +2 -0
- package/dist/pages/admin/users/index.cjs.map +1 -0
- package/dist/pages/admin/users/index.d.ts +4 -0
- package/dist/pages/admin/users/index.js +14 -0
- package/dist/pages/admin/users/index.js.map +1 -0
- package/dist/pages/cc/CcClientView.cjs +2 -0
- package/dist/pages/cc/CcClientView.cjs.map +1 -0
- package/dist/pages/cc/CcClientView.d.ts +7 -0
- package/dist/pages/cc/CcClientView.js +28 -0
- package/dist/pages/cc/CcClientView.js.map +1 -0
- package/dist/pages/cc/index.cjs +2 -0
- package/dist/pages/cc/index.cjs.map +1 -0
- package/dist/pages/cc/index.d.ts +16 -0
- package/dist/pages/cc/index.js +11 -0
- package/dist/pages/cc/index.js.map +1 -0
- package/dist/pages/dashboard/DashboardClientView.cjs +2 -0
- package/dist/pages/dashboard/DashboardClientView.cjs.map +1 -0
- package/dist/pages/dashboard/DashboardClientView.d.ts +9 -0
- package/dist/pages/dashboard/DashboardClientView.js +28 -0
- package/dist/pages/dashboard/DashboardClientView.js.map +1 -0
- package/dist/pages/dashboard/index.cjs +2 -0
- package/dist/pages/dashboard/index.cjs.map +1 -0
- package/dist/pages/dashboard/index.d.ts +16 -0
- package/dist/pages/dashboard/index.js +11 -0
- package/dist/pages/dashboard/index.js.map +1 -0
- package/dist/pages/delegations/DelegationsClientView.cjs +2 -0
- package/dist/pages/delegations/DelegationsClientView.cjs.map +1 -0
- package/dist/pages/delegations/DelegationsClientView.d.ts +3 -0
- package/dist/pages/delegations/DelegationsClientView.js +28 -0
- package/dist/pages/delegations/DelegationsClientView.js.map +1 -0
- package/dist/pages/delegations/index.cjs +2 -0
- package/dist/pages/delegations/index.cjs.map +1 -0
- package/dist/pages/delegations/index.d.ts +4 -0
- package/dist/pages/delegations/index.js +14 -0
- package/dist/pages/delegations/index.js.map +1 -0
- package/dist/pages/forms/FormsClientView.cjs +2 -0
- package/dist/pages/forms/FormsClientView.cjs.map +1 -0
- package/dist/pages/forms/FormsClientView.d.ts +10 -0
- package/dist/pages/forms/FormsClientView.js +28 -0
- package/dist/pages/forms/FormsClientView.js.map +1 -0
- package/dist/pages/forms/builder/FormBuilderClientView.cjs +2 -0
- package/dist/pages/forms/builder/FormBuilderClientView.cjs.map +1 -0
- package/dist/pages/forms/builder/FormBuilderClientView.d.ts +11 -0
- package/dist/pages/forms/builder/FormBuilderClientView.js +28 -0
- package/dist/pages/forms/builder/FormBuilderClientView.js.map +1 -0
- package/dist/pages/forms/builder/index.cjs +2 -0
- package/dist/pages/forms/builder/index.cjs.map +1 -0
- package/dist/pages/forms/builder/index.d.ts +23 -0
- package/dist/pages/forms/builder/index.js +15 -0
- package/dist/pages/forms/builder/index.js.map +1 -0
- package/dist/pages/forms/index.cjs +2 -0
- package/dist/pages/forms/index.cjs.map +1 -0
- package/dist/pages/forms/index.d.ts +17 -0
- package/dist/pages/forms/index.js +14 -0
- package/dist/pages/forms/index.js.map +1 -0
- package/dist/pages/inbox/InboxClientView.cjs +2 -0
- package/dist/pages/inbox/InboxClientView.cjs.map +1 -0
- package/dist/pages/inbox/InboxClientView.d.ts +9 -0
- package/dist/pages/inbox/InboxClientView.js +28 -0
- package/dist/pages/inbox/InboxClientView.js.map +1 -0
- package/dist/pages/inbox/index.cjs +2 -0
- package/dist/pages/inbox/index.cjs.map +1 -0
- package/dist/pages/inbox/index.d.ts +16 -0
- package/dist/pages/inbox/index.js +11 -0
- package/dist/pages/inbox/index.js.map +1 -0
- package/dist/pages/instances/detail/InstanceDetailClientView.cjs +2 -0
- package/dist/pages/instances/detail/InstanceDetailClientView.cjs.map +1 -0
- package/dist/pages/instances/detail/InstanceDetailClientView.d.ts +9 -0
- package/dist/pages/instances/detail/InstanceDetailClientView.js +28 -0
- package/dist/pages/instances/detail/InstanceDetailClientView.js.map +1 -0
- package/dist/pages/instances/detail/index.cjs +2 -0
- package/dist/pages/instances/detail/index.cjs.map +1 -0
- package/dist/pages/instances/detail/index.d.ts +23 -0
- package/dist/pages/instances/detail/index.js +12 -0
- package/dist/pages/instances/detail/index.js.map +1 -0
- package/dist/pages/instances/new/InstanceNewClientView.cjs +2 -0
- package/dist/pages/instances/new/InstanceNewClientView.cjs.map +1 -0
- package/dist/pages/instances/new/InstanceNewClientView.d.ts +8 -0
- package/dist/pages/instances/new/InstanceNewClientView.js +28 -0
- package/dist/pages/instances/new/InstanceNewClientView.js.map +1 -0
- package/dist/pages/instances/new/index.cjs +2 -0
- package/dist/pages/instances/new/index.cjs.map +1 -0
- package/dist/pages/instances/new/index.d.ts +16 -0
- package/dist/pages/instances/new/index.js +11 -0
- package/dist/pages/instances/new/index.js.map +1 -0
- package/dist/pages/login/LoginClientView.cjs +2 -0
- package/dist/pages/login/LoginClientView.cjs.map +1 -0
- package/dist/pages/login/LoginClientView.d.ts +11 -0
- package/dist/pages/login/LoginClientView.js +29 -0
- package/dist/pages/login/LoginClientView.js.map +1 -0
- package/dist/pages/login/index.cjs +2 -0
- package/dist/pages/login/index.cjs.map +1 -0
- package/dist/pages/login/index.d.ts +17 -0
- package/dist/pages/login/index.js +14 -0
- package/dist/pages/login/index.js.map +1 -0
- package/dist/pages/root/RootClientView.cjs +1 -0
- package/dist/pages/root/RootClientView.d.ts +8 -0
- package/dist/pages/root/RootClientView.js +2 -0
- package/dist/pages/root/index.cjs +2 -0
- package/dist/pages/root/index.cjs.map +1 -0
- package/dist/pages/root/index.d.ts +16 -0
- package/dist/pages/root/index.js +11 -0
- package/dist/pages/root/index.js.map +1 -0
- package/dist/pages/search/SearchClientView.cjs +2 -0
- package/dist/pages/search/SearchClientView.cjs.map +1 -0
- package/dist/pages/search/SearchClientView.d.ts +7 -0
- package/dist/pages/search/SearchClientView.js +28 -0
- package/dist/pages/search/SearchClientView.js.map +1 -0
- package/dist/pages/search/index.cjs +2 -0
- package/dist/pages/search/index.cjs.map +1 -0
- package/dist/pages/search/index.d.ts +16 -0
- package/dist/pages/search/index.js +11 -0
- package/dist/pages/search/index.js.map +1 -0
- package/dist/pages/sent/SentClientView.cjs +2 -0
- package/dist/pages/sent/SentClientView.cjs.map +1 -0
- package/dist/pages/sent/SentClientView.d.ts +7 -0
- package/dist/pages/sent/SentClientView.js +28 -0
- package/dist/pages/sent/SentClientView.js.map +1 -0
- package/dist/pages/sent/index.cjs +2 -0
- package/dist/pages/sent/index.cjs.map +1 -0
- package/dist/pages/sent/index.d.ts +16 -0
- package/dist/pages/sent/index.js +11 -0
- package/dist/pages/sent/index.js.map +1 -0
- package/dist/pages/settings/notifications/SettingsNotificationsClientView.cjs +2 -0
- package/dist/pages/settings/notifications/SettingsNotificationsClientView.cjs.map +1 -0
- package/dist/pages/settings/notifications/SettingsNotificationsClientView.d.ts +3 -0
- package/dist/pages/settings/notifications/SettingsNotificationsClientView.js +28 -0
- package/dist/pages/settings/notifications/SettingsNotificationsClientView.js.map +1 -0
- package/dist/pages/settings/notifications/index.cjs +2 -0
- package/dist/pages/settings/notifications/index.cjs.map +1 -0
- package/dist/pages/settings/notifications/index.d.ts +4 -0
- package/dist/pages/settings/notifications/index.js +14 -0
- package/dist/pages/settings/notifications/index.js.map +1 -0
- package/dist/pages/templates/TemplatesClientView.cjs +2 -0
- package/dist/pages/templates/TemplatesClientView.cjs.map +1 -0
- package/dist/pages/templates/TemplatesClientView.d.ts +3 -0
- package/dist/pages/templates/TemplatesClientView.js +28 -0
- package/dist/pages/templates/TemplatesClientView.js.map +1 -0
- package/dist/pages/templates/categories/TemplateCategoriesClientView.cjs +2 -0
- package/dist/pages/templates/categories/TemplateCategoriesClientView.cjs.map +1 -0
- package/dist/pages/templates/categories/TemplateCategoriesClientView.d.ts +3 -0
- package/dist/pages/templates/categories/TemplateCategoriesClientView.js +28 -0
- package/dist/pages/templates/categories/TemplateCategoriesClientView.js.map +1 -0
- package/dist/pages/templates/categories/index.cjs +2 -0
- package/dist/pages/templates/categories/index.cjs.map +1 -0
- package/dist/pages/templates/categories/index.d.ts +4 -0
- package/dist/pages/templates/categories/index.js +14 -0
- package/dist/pages/templates/categories/index.js.map +1 -0
- package/dist/pages/templates/designer/TemplateDesignerClientView.cjs +2 -0
- package/dist/pages/templates/designer/TemplateDesignerClientView.cjs.map +1 -0
- package/dist/pages/templates/designer/TemplateDesignerClientView.d.ts +3 -0
- package/dist/pages/templates/designer/TemplateDesignerClientView.js +28 -0
- package/dist/pages/templates/designer/TemplateDesignerClientView.js.map +1 -0
- package/dist/pages/templates/designer/index.cjs +2 -0
- package/dist/pages/templates/designer/index.cjs.map +1 -0
- package/dist/pages/templates/designer/index.d.ts +10 -0
- package/dist/pages/templates/designer/index.js +15 -0
- package/dist/pages/templates/designer/index.js.map +1 -0
- package/dist/pages/templates/index.cjs +2 -0
- package/dist/pages/templates/index.cjs.map +1 -0
- package/dist/pages/templates/index.d.ts +4 -0
- package/dist/pages/templates/index.js +14 -0
- package/dist/pages/templates/index.js.map +1 -0
- package/dist/pages/templates/versions/TemplateVersionsClientView.cjs +2 -0
- package/dist/pages/templates/versions/TemplateVersionsClientView.cjs.map +1 -0
- package/dist/pages/templates/versions/TemplateVersionsClientView.d.ts +3 -0
- package/dist/pages/templates/versions/TemplateVersionsClientView.js +28 -0
- package/dist/pages/templates/versions/TemplateVersionsClientView.js.map +1 -0
- package/dist/pages/templates/versions/index.cjs +2 -0
- package/dist/pages/templates/versions/index.cjs.map +1 -0
- package/dist/pages/templates/versions/index.d.ts +10 -0
- package/dist/pages/templates/versions/index.js +15 -0
- package/dist/pages/templates/versions/index.js.map +1 -0
- package/dist/templates.css +1 -0
- package/dist/views/admin/delegations/AdminDelegationsView.d.ts +5 -0
- package/dist/views/admin/delegations/index.cjs +1 -0
- package/dist/views/admin/delegations/index.d.ts +1 -0
- package/dist/views/admin/delegations/index.js +2 -0
- package/dist/views/admin/orgs/AdminOrgsView.d.ts +5 -0
- package/dist/views/admin/orgs/index.cjs +1 -0
- package/dist/views/admin/orgs/index.d.ts +1 -0
- package/dist/views/admin/orgs/index.js +2 -0
- package/dist/views/admin/users/AdminUsersView.d.ts +5 -0
- package/dist/views/admin/users/index.cjs +1 -0
- package/dist/views/admin/users/index.d.ts +1 -0
- package/dist/views/admin/users/index.js +2 -0
- package/dist/views/cc/CcView.d.ts +9 -0
- package/dist/views/cc/index.cjs +1 -0
- package/dist/views/cc/index.d.ts +1 -0
- package/dist/views/cc/index.js +2 -0
- package/dist/views/dashboard/DashboardView.d.ts +9 -0
- package/dist/views/dashboard/index.cjs +1 -0
- package/dist/views/dashboard/index.d.ts +1 -0
- package/dist/views/dashboard/index.js +2 -0
- package/dist/views/delegations/DelegationsView.d.ts +5 -0
- package/dist/views/delegations/index.cjs +1 -0
- package/dist/views/delegations/index.d.ts +1 -0
- package/dist/views/delegations/index.js +2 -0
- package/dist/views/forms/FormsView.d.ts +4 -0
- package/dist/views/forms/builder/FormBuilderView.d.ts +9 -0
- package/dist/views/forms/builder/index.cjs +1 -0
- package/dist/views/forms/builder/index.d.ts +1 -0
- package/dist/views/forms/builder/index.js +2 -0
- package/dist/views/forms/builder/json-code-editor.d.ts +11 -0
- package/dist/views/forms/form-name-modal.d.ts +12 -0
- package/dist/views/forms/index.cjs +1 -0
- package/dist/views/forms/index.d.ts +1 -0
- package/dist/views/forms/index.js +2 -0
- package/dist/views/forms/renderer/FormRendererView.d.ts +19 -0
- package/dist/views/forms/renderer/index.cjs +1 -0
- package/dist/views/forms/renderer/index.d.ts +1 -0
- package/dist/views/forms/renderer/index.js +2 -0
- package/dist/views/inbox/InboxView.d.ts +9 -0
- package/dist/views/inbox/index.cjs +1 -0
- package/dist/views/inbox/index.d.ts +1 -0
- package/dist/views/inbox/index.js +2 -0
- package/dist/views/instances/detail/InstanceDetailView.d.ts +12 -0
- package/dist/views/instances/detail/index.cjs +1 -0
- package/dist/views/instances/detail/index.d.ts +1 -0
- package/dist/views/instances/detail/index.js +2 -0
- package/dist/views/instances/new/InstanceNewView.d.ts +15 -0
- package/dist/views/instances/new/index.cjs +1 -0
- package/dist/views/instances/new/index.d.ts +1 -0
- package/dist/views/instances/new/index.js +2 -0
- package/dist/views/login/LoginView.d.ts +47 -0
- package/dist/views/login/index.cjs +1 -0
- package/dist/views/login/index.d.ts +1 -0
- package/dist/views/login/index.js +2 -0
- package/dist/views/root/RootView.d.ts +12 -0
- package/dist/views/root/index.d.ts +1 -0
- package/dist/views/search/SearchView.d.ts +9 -0
- package/dist/views/search/index.cjs +1 -0
- package/dist/views/search/index.d.ts +1 -0
- package/dist/views/search/index.js +2 -0
- package/dist/views/sent/SentView.d.ts +9 -0
- package/dist/views/sent/index.cjs +1 -0
- package/dist/views/sent/index.d.ts +1 -0
- package/dist/views/sent/index.js +2 -0
- package/dist/views/settings/notifications/SettingsNotificationsView.d.ts +5 -0
- package/dist/views/settings/notifications/index.cjs +1 -0
- package/dist/views/settings/notifications/index.d.ts +1 -0
- package/dist/views/settings/notifications/index.js +2 -0
- package/dist/views/templates/TemplatesView.d.ts +5 -0
- package/dist/views/templates/categories/TemplateCategoriesView.d.ts +5 -0
- package/dist/views/templates/categories/index.cjs +1 -0
- package/dist/views/templates/categories/index.d.ts +1 -0
- package/dist/views/templates/categories/index.js +2 -0
- package/dist/views/templates/designer/TemplateDesignerView.d.ts +6 -0
- package/dist/views/templates/designer/index.cjs +1 -0
- package/dist/views/templates/designer/index.d.ts +1 -0
- package/dist/views/templates/designer/index.js +2 -0
- package/dist/views/templates/index.cjs +1 -0
- package/dist/views/templates/index.d.ts +1 -0
- package/dist/views/templates/index.js +2 -0
- package/dist/views/templates/template-name-modal.d.ts +22 -0
- package/dist/views/templates/versions/TemplateVersionsView.d.ts +6 -0
- package/dist/views/templates/versions/index.cjs +1 -0
- package/dist/views/templates/versions/index.d.ts +1 -0
- package/dist/views/templates/versions/index.js +2 -0
- package/package.json +272 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelegationsView-DQUqOUV5.js","names":[],"sources":["../../src/views/delegations/delegations.module.scss","../../src/views/delegations/DelegationsView.tsx"],"sourcesContent":[".delegationFilterArea {\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\n.delegationModalFields {\n display: grid;\n gap: 12px;\n width: 100%;\n\n :global(.mzn-form-field--horizontal) {\n align-items: flex-start;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label-area) {\n flex: 0 0 112px;\n width: 112px;\n min-width: 112px;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label) {\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__data-entry) {\n flex: 1 1 auto;\n align-items: stretch;\n min-width: 0;\n max-width: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-autocomplete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-picker),\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 :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.memberNameWithTooltip {\n cursor: help;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n","'use client';\n\nimport {\n Key,\n ReactElement,\n RefCallback,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Badge,\n Button,\n DateTimePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Layout,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Tooltip,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { BPMFormField } from '../../components/bpm-form-field';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { AppNavigation } from '../../components/app-navigation';\nimport { useAuth } from '../../lib/auth-provider';\nimport {\n DelegationRuleRecord,\n DelegationRuleStatus,\n DelegationScopeType,\n MemberProfileRecord,\n createDelegationRule,\n listDelegationRulesPage,\n revokeDelegationRule,\n searchMembers,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n ApprovalTemplateRecord,\n listApprovalTemplates,\n} from '@rytass/bpm-core-client/template';\nimport styles from './delegations.module.scss';\n\ntype DelegationStatusTabKey = 'ALL' | DelegationRuleStatus;\n\ntype MemberOption = Readonly<{\n displayName: string;\n email: string | null;\n id: string;\n name: string;\n}>;\n\ntype ScopeOption = Readonly<{\n id: DelegationScopeType;\n name: string;\n}>;\n\ntype ScopeFilterOption = Readonly<{\n id: 'ALL_SCOPES' | DelegationScopeType;\n name: string;\n scopeType: DelegationScopeType | null;\n}>;\n\ntype TemplateOption = Readonly<{\n id: string;\n name: string;\n}>;\n\ntype DelegationRuleRow = Readonly<\n Record<string, unknown> &\n DelegationRuleRecord & {\n agentEmail: string | null;\n agentName: string;\n key: string;\n scopeLabel: string;\n }\n>;\n\nconst DELEGATION_MODAL_FIELD_LAYOUT = FormFieldLayout.HORIZONTAL;\nconst DELEGATION_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst DELEGATION_STATUS_TABS: readonly {\n readonly key: DelegationStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'ACTIVE', label: '啟用中' },\n { key: 'REVOKED', label: '已撤銷' },\n { key: 'EXPIRED', label: '已過期' },\n];\nconst SCOPE_FILTER_OPTIONS: readonly ScopeFilterOption[] = [\n { id: 'ALL_SCOPES', name: '全部範圍', scopeType: null },\n { id: 'ALL', name: '全部簽核', scopeType: 'ALL' },\n { id: 'TEMPLATE_LIST', name: '指定模板', scopeType: 'TEMPLATE_LIST' },\n];\nconst SCOPE_OPTIONS: readonly ScopeOption[] = [\n { id: 'ALL', name: '全部簽核' },\n { id: 'TEMPLATE_LIST', name: '指定模板' },\n];\n\nexport interface DelegationsViewProps {\n readonly activeHref?: string;\n}\n\nexport function DelegationsView({\n activeHref = '/delegations',\n}: DelegationsViewProps = {}): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [agentMember, setAgentMember] = useState<MemberOption | null>(null);\n const [endAt, setEndAt] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [memberLoading, setMemberLoading] = useState(false);\n const [memberOptions, setMemberOptions] = useState<readonly MemberOption[]>(\n [],\n );\n const [modalOpen, setModalOpen] = useState(false);\n const [rulePage, setRulePage] = useState(1);\n const [rulePageSize, setRulePageSize] = useState(10);\n const [ruleStatus, setRuleStatus] = useState<DelegationStatusTabKey>('ALL');\n const [ruleTotalCount, setRuleTotalCount] = useState(0);\n const [rules, setRules] = useState<readonly DelegationRuleRecord[]>([]);\n const [saving, setSaving] = useState(false);\n const [scopeFilterType, setScopeFilterType] = useState<ScopeFilterOption>(\n SCOPE_FILTER_OPTIONS[0],\n );\n const [scopeTemplates, setScopeTemplates] = useState<\n readonly TemplateOption[]\n >([]);\n const [scopeType, setScopeType] = useState<ScopeOption>(SCOPE_OPTIONS[0]);\n const [startAt, setStartAt] = useState('');\n const [templateLoading, setTemplateLoading] = useState(false);\n const [templateOptions, setTemplateOptions] = useState<\n readonly TemplateOption[]\n >([]);\n\n const refreshRules = useCallback(async (): Promise<void> => {\n if (!currentMemberId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const [rulePageResult, members] = await Promise.all([\n listDelegationRulesPage({\n includeInactive: true,\n page: rulePage,\n pageSize: rulePageSize,\n principalMemberId: currentMemberId,\n scopeType: scopeFilterType.scopeType,\n status: ruleStatus === 'ALL' ? null : ruleStatus,\n }),\n searchMembers(''),\n ]);\n\n setRules(rulePageResult.rules);\n setRuleTotalCount(rulePageResult.totalCount);\n setMemberOptions(members.map(readMemberOption));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [currentMemberId, rulePage, rulePageSize, ruleStatus, scopeFilterType]);\n\n useEffect((): void => {\n void refreshRules();\n }, [refreshRules]);\n\n const membersById = useMemo(\n (): ReadonlyMap<string, MemberOption> =>\n new Map(memberOptions.map((option) => [option.id, option])),\n [memberOptions],\n );\n const rows = useMemo(\n (): DelegationRuleRow[] =>\n rules.map((rule) => ({\n ...rule,\n agentEmail: membersById.get(rule.agentMemberId)?.email ?? null,\n agentName:\n membersById.get(rule.agentMemberId)?.displayName ??\n rule.agentMemberId,\n key: rule.id,\n scopeLabel: readScopeLabel(rule),\n })),\n [membersById, rules],\n );\n const selectedScopeType =\n SCOPE_OPTIONS.find((option) => option.id === scopeType.id) ??\n SCOPE_OPTIONS[0];\n const columns = useMemo(\n (): TableColumn<DelegationRuleRow>[] => [\n {\n key: 'agent',\n render: (record: DelegationRuleRow): ReactElement => (\n <MemberNameWithEmailTooltip\n email={record.agentEmail}\n name={record.agentName}\n />\n ),\n title: '代理人',\n width: 220,\n },\n { dataIndex: 'scopeLabel', key: 'scope', title: '代理範圍', width: 220 },\n {\n key: 'status',\n render: (record: DelegationRuleRow): ReactElement => (\n <DelegationStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'startAt',\n render: (record: DelegationRuleRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startAt)}\n </Typography>\n ),\n title: '開始時間',\n width: 220,\n },\n {\n key: 'endAt',\n render: (record: DelegationRuleRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.endAt ? formatDateTime(record.endAt) : '-'}\n </Typography>\n ),\n title: '結束時間',\n width: 220,\n },\n ],\n [],\n );\n const handleRevoke = useCallback(\n async (id: string): Promise<void> => {\n if (!currentMemberId) {\n return;\n }\n\n setError(null);\n\n try {\n await revokeDelegationRule({\n id,\n revokedByMemberId: currentMemberId,\n });\n await refreshRules();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n }\n },\n [currentMemberId, refreshRules],\n );\n const tableActions = useMemo(\n (): TableActions<DelegationRuleRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<DelegationRuleRow>['render']> =>\n record.status === 'ACTIVE'\n ? [\n {\n name: '撤銷',\n onClick: (): void => void handleRevoke(record.id),\n },\n ]\n : [],\n variant: 'destructive-secondary',\n width: 88,\n }),\n [handleRevoke],\n );\n\n async function handleSearchMembers(searchText: string): Promise<void> {\n setMemberLoading(true);\n\n try {\n setMemberOptions((await searchMembers(searchText)).map(readMemberOption));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setMemberLoading(false);\n }\n }\n\n async function handleSearchTemplates(\n searchText: string,\n selectedOptions: readonly TemplateOption[] = scopeTemplates,\n ): Promise<void> {\n setTemplateLoading(true);\n\n try {\n const nextOptions = (await listApprovalTemplates()).map(\n readTemplateOption,\n );\n\n setTemplateOptions(\n mergeTemplateOptions(\n selectedOptions,\n filterTemplateOptions(nextOptions, searchText),\n ),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setTemplateLoading(false);\n }\n }\n\n function openCreateModal(): void {\n setAgentMember(null);\n setEndAt('');\n setScopeTemplates([]);\n setScopeType(SCOPE_OPTIONS[0]);\n setStartAt('');\n setTemplateOptions([]);\n void handleSearchTemplates('', []);\n setModalOpen(true);\n }\n\n function closeCreateModal(): void {\n if (saving) {\n return;\n }\n\n setModalOpen(false);\n }\n\n async function handleCreate(): Promise<void> {\n if (!currentMemberId) {\n return;\n }\n\n if (!agentMember) {\n setError('請選擇代理人');\n return;\n }\n\n if (agentMember.id === currentMemberId) {\n setError('代理人不可設定為自己');\n return;\n }\n\n if (selectedScopeType.id === 'TEMPLATE_LIST' && scopeTemplates.length < 1) {\n setError('請選擇至少一個簽核模板');\n return;\n }\n\n if (isInvalidDelegationDateRange(startAt, endAt)) {\n setError('結束時間必須晚於起始時間');\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await createDelegationRule({\n agentMemberId: agentMember.id,\n createdByMemberId: currentMemberId,\n endAt: endAt || null,\n principalMemberId: currentMemberId,\n priority: 100,\n requiresConfirmation: false,\n scopeConditionCel: null,\n scopeTemplateIds:\n selectedScopeType.id === 'TEMPLATE_LIST'\n ? scopeTemplates.map((template) => template.id)\n : [],\n scopeType: selectedScopeType.id,\n startAt: startAt || null,\n });\n setModalOpen(false);\n\n if (rulePage === 1) {\n await refreshRules();\n } else {\n setRulePage(1);\n }\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Layout>\n <AppNavigation activeHref={activeHref} />\n\n <Layout.Main>\n <PageHeader>\n <ContentHeader\n description=\"設定自己的簽核代理,讓指定期間內的新待簽任務自動交由代理人處理。\"\n title=\"我的代理\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={openCreateModal}\n variant=\"base-primary\"\n >\n 建立代理\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.delegationFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"scopeFilterType\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setScopeFilterType(readScopeFilterOption(option));\n setRulePage(1);\n }}\n options={[...SCOPE_FILTER_OPTIONS]}\n placeholder=\"代理範圍\"\n size=\"sub\"\n value={scopeFilterType}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={ruleStatus}\n onChange={(activeKey): void => {\n setRuleStatus(readDelegationStatusTabKey(activeKey));\n setRulePage(1);\n }}\n >\n {DELEGATION_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: rulePage,\n onChange: (page): void => {\n setRulePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setRulePage(1);\n setRulePageSize(pageSize);\n },\n pageSize: rulePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: DELEGATION_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: ruleTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !agentMember,\n }}\n confirmText=\"建立代理\"\n loading={saving}\n modalType=\"standard\"\n onCancel={closeCreateModal}\n onClose={closeCreateModal}\n onConfirm={(): void => void handleCreate()}\n open={modalOpen}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"代理生效後,後續建立的待簽任務會依範圍自動指派給代理人。\"\n title=\"建立個人代理\"\n >\n <div className={styles.delegationModalFields}>\n <MemberAutoCompleteField\n label=\"代理人\"\n loading={memberLoading}\n name=\"agentMemberId\"\n onChange={setAgentMember}\n onSearch={handleSearchMembers}\n options={memberOptions}\n value={agentMember}\n />\n <BPMFormField label=\"代理範圍\" name=\"scopeType\" required>\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setScopeType(readScopeOptionFromValue(option))\n }\n options={[...SCOPE_OPTIONS]}\n placeholder=\"選擇代理範圍\"\n value={selectedScopeType}\n />\n </BPMFormField>\n {selectedScopeType.id === 'TEMPLATE_LIST' ? (\n <BPMFormField label=\"簽核模板\" name=\"scopeTemplateIds\" required>\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的模板\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'scopeTemplateIds',\n spellCheck: false,\n }}\n loading={templateLoading}\n loadingText=\"搜尋模板中...\"\n mode=\"multiple\"\n onChange={(nextTemplates): void => {\n const selectedTemplates =\n readTemplateOptionsFromValue(nextTemplates);\n\n setScopeTemplates(selectedTemplates);\n setTemplateOptions((currentOptions) =>\n mergeTemplateOptions(selectedTemplates, currentOptions),\n );\n }}\n onSearch={handleSearchTemplates}\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchTemplates('');\n }\n }}\n options={[...templateOptions]}\n overflowStrategy=\"wrap\"\n placeholder=\"搜尋並選取簽核模板\"\n searchDebounceTime={300}\n value={[...scopeTemplates]}\n />\n </BPMFormField>\n ) : null}\n <BPMFormField label=\"起始時間\" name=\"startAt\">\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n fullWidth\n hideSecond\n onChange={(nextValue): void =>\n setStartAt(formatDelegationDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"留空立即生效\"\n placeholderRight=\"選擇時間\"\n value={readDelegationDateTimePickerValue(startAt)}\n />\n </BPMFormField>\n <BPMFormField label=\"結束時間\" name=\"endAt\">\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n fullWidth\n hideSecond\n onChange={(nextValue): void =>\n setEndAt(formatDelegationDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"可留空\"\n placeholderRight=\"選擇時間\"\n value={readDelegationDateTimePickerValue(endAt)}\n />\n </BPMFormField>\n </div>\n </Modal>\n </Layout.Main>\n </Layout>\n );\n}\n\nfunction MemberAutoCompleteField({\n label,\n loading,\n name,\n onChange,\n onSearch,\n options,\n value,\n}: {\n readonly label: string;\n readonly loading: boolean;\n readonly name: string;\n readonly onChange: (option: MemberOption | null) => void;\n readonly onSearch: (searchText: string) => Promise<void>;\n readonly options: readonly MemberOption[];\n readonly value: MemberOption | null;\n}): ReactElement {\n return (\n <BPMFormField\n label={label}\n layout={DELEGATION_MODAL_FIELD_LAYOUT}\n name={name}\n required\n >\n <AutoComplete\n asyncData\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={onSearch}\n onSearchTextChange={(searchText): void =>\n onChange(readUniqueMemberOption(searchText, options))\n }\n onVisibilityChange={(open): void => {\n if (open) {\n void onSearch('');\n }\n }}\n options={[...options]}\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={value}\n />\n </BPMFormField>\n );\n}\n\nfunction MemberNameWithEmailTooltip({\n email,\n name,\n}: {\n readonly email: string | null;\n readonly name: string;\n}): ReactElement {\n if (!email) {\n return <span>{name}</span>;\n }\n\n return (\n <Tooltip title={email}>\n {({ onMouseEnter, onMouseLeave, ref }): ReactElement => (\n <span\n className={styles.memberNameWithTooltip}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n ref={ref as RefCallback<HTMLSpanElement>}\n >\n {name}\n </span>\n )}\n </Tooltip>\n );\n}\n\nfunction readMemberOption(member: MemberProfileRecord): MemberOption {\n return {\n displayName: member.name,\n email: member.email,\n id: member.memberId,\n name: `${member.name} (${member.email})`,\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const displayName = value.displayName;\n const email = value.email;\n const id = value.id;\n const name = value.name;\n\n return typeof id === 'string' && typeof name === 'string'\n ? {\n displayName: typeof displayName === 'string' ? displayName : name,\n email: typeof email === 'string' ? email : null,\n id,\n name,\n }\n : null;\n}\n\nfunction readUniqueMemberOption(\n searchText: string,\n options: readonly MemberOption[],\n): MemberOption | null {\n const normalizedSearchText = searchText.trim().toLocaleLowerCase();\n\n if (!normalizedSearchText) {\n return null;\n }\n\n const matches = options.filter((option) =>\n [option.id, option.name, option.email ?? ''].some((value) =>\n value.toLocaleLowerCase().includes(normalizedSearchText),\n ),\n );\n\n return matches.length === 1 ? (matches[0] ?? null) : null;\n}\n\nfunction readTemplateOption(template: ApprovalTemplateRecord): TemplateOption {\n return {\n id: template.id,\n name: template.name,\n };\n}\n\nfunction readTemplateOptionsFromValue(\n value: readonly unknown[],\n): readonly TemplateOption[] {\n return value.flatMap((item): readonly TemplateOption[] => {\n if (!isRecord(item)) {\n return [];\n }\n\n const id = item.id;\n const name = item.name;\n\n return typeof id === 'string' && typeof name === 'string'\n ? [{ id, name }]\n : [];\n });\n}\n\nfunction filterTemplateOptions(\n options: readonly TemplateOption[],\n searchText: string,\n): readonly TemplateOption[] {\n const normalizedSearchText = searchText.trim().toLocaleLowerCase();\n\n if (!normalizedSearchText) {\n return options;\n }\n\n return options.filter((option) =>\n [option.id, option.name].some((value) =>\n value.toLocaleLowerCase().includes(normalizedSearchText),\n ),\n );\n}\n\nfunction mergeTemplateOptions(\n selectedOptions: readonly TemplateOption[],\n availableOptions: readonly TemplateOption[],\n): readonly TemplateOption[] {\n return [...selectedOptions, ...availableOptions].reduce<TemplateOption[]>(\n (options, option) =>\n options.some((currentOption) => currentOption.id === option.id)\n ? options\n : [...options, option],\n [],\n );\n}\n\nfunction readScopeFilterOption(value: unknown): ScopeFilterOption {\n if (!isRecord(value)) {\n return SCOPE_FILTER_OPTIONS[0];\n }\n\n const id = value.id;\n\n return (\n SCOPE_FILTER_OPTIONS.find((option) => option.id === id) ??\n SCOPE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readScopeLabel(rule: DelegationRuleRecord): string {\n if (rule.scopeType === 'ALL') {\n return '全部簽核';\n }\n\n if (rule.scopeType === 'TEMPLATE_LIST') {\n return `指定模板:${rule.scopeTemplateIds.length}`;\n }\n\n return rule.scopeConditionCel ? `條件:${rule.scopeConditionCel}` : '條件式';\n}\n\nfunction readScopeOptionFromValue(value: unknown): ScopeOption {\n if (!isRecord(value) || !isSelectableDelegationScopeType(value.id)) {\n return SCOPE_OPTIONS[0];\n }\n\n return (\n SCOPE_OPTIONS.find((option) => option.id === value.id) ?? SCOPE_OPTIONS[0]\n );\n}\n\nfunction isSelectableDelegationScopeType(\n value: unknown,\n): value is ScopeOption['id'] {\n return value === 'ALL' || value === 'TEMPLATE_LIST';\n}\n\nfunction DelegationStatusBadge({\n status,\n}: {\n readonly status: DelegationRuleRecord['status'];\n}): ReactElement {\n if (status === 'ACTIVE') {\n return <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />;\n }\n\n if (status === 'REVOKED') {\n return <Badge size=\"sub\" text=\"已撤銷\" variant=\"dot-inactive\" />;\n }\n\n if (status === 'EXPIRED') {\n return <Badge size=\"sub\" text=\"已過期\" variant=\"dot-warning\" />;\n }\n\n return <Badge size=\"sub\" text={status} variant=\"dot-info\" />;\n}\n\nfunction readDelegationStatusTabKey(activeKey: Key): DelegationStatusTabKey {\n if (\n activeKey === 'ACTIVE' ||\n activeKey === 'REVOKED' ||\n activeKey === 'EXPIRED'\n ) {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction readDelegationDateTimePickerValue(value: string): string | undefined {\n const date = value ? parseDelegationDateTimeValue(value) : null;\n\n return date\n ? `${formatDateParts(date)}T${padDatePart(date.getHours())}:${padDatePart(\n date.getMinutes(),\n )}`\n : undefined;\n}\n\nfunction formatDelegationDateTimePickerValue(\n value: string | undefined,\n): string {\n const date = value ? parseDelegationDateTimeValue(value) : null;\n\n return date ? date.toISOString() : '';\n}\n\nfunction isInvalidDelegationDateRange(startAt: string, endAt: string): boolean {\n if (!startAt || !endAt) {\n return false;\n }\n\n const startDate = parseDelegationDateTimeValue(startAt);\n const endDate = parseDelegationDateTimeValue(endAt);\n\n return !!startDate && !!endDate && endDate.getTime() <= startDate.getTime();\n}\n\nfunction parseDelegationDateTimeValue(value: string): Date | null {\n if (value.endsWith('Z') || /[+-]\\d{2}:\\d{2}$/.test(value)) {\n const parsedDate = new Date(value);\n\n return Number.isNaN(parsedDate.getTime()) ? null : parsedDate;\n }\n\n const [datePart = '', timePart = '00:00'] = value.split('T');\n const [year = 0, month = 1, day = 1] = datePart.split('-').map(Number);\n const [hour = 0, minute = 0] = timePart.split(':').map(Number);\n const parsedDate = new Date(year, month - 1, day, hour, minute);\n\n return Number.isNaN(parsedDate.getTime()) ? null : parsedDate;\n}\n\nfunction formatDateParts(date: Date): string {\n return `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(\n date.getDate(),\n )}`;\n}\n\nfunction padDatePart(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\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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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";require('../DelegationsView.css');const e=require("./app-navigation-DAC5gFbG.cjs"),t=require("./auth-provider-D2P-qWmY.cjs"),n=require("./format-date-time-BQyH5U8z.cjs"),r=require("./bpm-form-field-Bc6k4ZEO.cjs");let i=require("react"),a=require("@mezzanine-ui/react"),o=require("react/jsx-runtime"),s=require("@rytass/bpm-core-client/workflow"),c=require("@mezzanine-ui/icons"),l=require("@mezzanine-ui/react/ContentHeader");l=e.o(l,1);let u=require("@mezzanine-ui/core/form"),ee=require("@rytass/bpm-core-client/template");var d={delegationFilterArea:`bpm_delegationFilterArea_hAA4C`,delegationModalFields:`bpm_delegationModalFields_1aOVW`,memberNameWithTooltip:`bpm_memberNameWithTooltip_6Mojc`},f=u.FormFieldLayout.HORIZONTAL,te=[10,20,50],ne=[{key:`ALL`,label:`全部`},{key:`ACTIVE`,label:`啟用中`},{key:`REVOKED`,label:`已撤銷`},{key:`EXPIRED`,label:`已過期`}],p=[{id:`ALL_SCOPES`,name:`全部範圍`,scopeType:null},{id:`ALL`,name:`全部簽核`,scopeType:`ALL`},{id:`TEMPLATE_LIST`,name:`指定模板`,scopeType:`TEMPLATE_LIST`}],m=[{id:`ALL`,name:`全部簽核`},{id:`TEMPLATE_LIST`,name:`指定模板`}];function h({activeHref:f=`/delegations`}={}){let{member:h}=t.n(),_=h?.memberId??null,[v,b]=(0,i.useState)(null),[C,w]=(0,i.useState)(``),[T,D]=(0,i.useState)(null),[me,O]=(0,i.useState)(!0),[he,k]=(0,i.useState)(!1),[A,j]=(0,i.useState)([]),[ge,M]=(0,i.useState)(!1),[N,P]=(0,i.useState)(1),[F,_e]=(0,i.useState)(10),[I,ve]=(0,i.useState)(`ALL`),[ye,be]=(0,i.useState)(0),[L,xe]=(0,i.useState)([]),[R,z]=(0,i.useState)(!1),[B,Se]=(0,i.useState)(p[0]),[V,H]=(0,i.useState)([]),[Ce,U]=(0,i.useState)(m[0]),[W,G]=(0,i.useState)(``),[we,K]=(0,i.useState)(!1),[Te,q]=(0,i.useState)([]),J=(0,i.useCallback)(async()=>{if(!_){O(!1);return}O(!0),D(null);try{let[e,t]=await Promise.all([(0,s.listDelegationRulesPage)({includeInactive:!0,page:N,pageSize:F,principalMemberId:_,scopeType:B.scopeType,status:I===`ALL`?null:I}),(0,s.searchMembers)(``)]);xe(e.rules),be(e.totalCount),j(t.map(g))}catch(e){D(E(e))}finally{O(!1)}},[_,N,F,I,B]);(0,i.useEffect)(()=>{J()},[J]);let Y=(0,i.useMemo)(()=>new Map(A.map(e=>[e.id,e])),[A]),Ee=(0,i.useMemo)(()=>L.map(e=>({...e,agentEmail:Y.get(e.agentMemberId)?.email??null,agentName:Y.get(e.agentMemberId)?.displayName??e.agentMemberId,key:e.id,scopeLabel:le(e)})),[Y,L]),X=m.find(e=>e.id===Ce.id)??m[0],De=(0,i.useMemo)(()=>[{key:`agent`,render:e=>(0,o.jsx)(ie,{email:e.agentEmail,name:e.agentName}),title:`代理人`,width:220},{dataIndex:`scopeLabel`,key:`scope`,title:`代理範圍`,width:220},{key:`status`,render:e=>(0,o.jsx)(de,{status:e.status}),title:`狀態`,width:120},{key:`startAt`,render:e=>(0,o.jsx)(a.Typography,{component:`span`,variant:`body`,children:n.t(e.startAt)}),title:`開始時間`,width:220},{key:`endAt`,render:e=>(0,o.jsx)(a.Typography,{component:`span`,variant:`body`,children:e.endAt?n.t(e.endAt):`-`}),title:`結束時間`,width:220}],[]),Z=(0,i.useCallback)(async e=>{if(_){D(null);try{await(0,s.revokeDelegationRule)({id:e,revokedByMemberId:_}),await J()}catch(e){D(E(e))}}},[_,J]),Oe=(0,i.useMemo)(()=>({render:e=>e.status===`ACTIVE`?[{name:`撤銷`,onClick:()=>void Z(e.id)}]:[],variant:`destructive-secondary`,width:88}),[Z]);async function ke(e){k(!0);try{j((await(0,s.searchMembers)(e)).map(g))}catch(e){D(E(e))}finally{k(!1)}}async function Q(e,t=V){K(!0);try{q(y(t,se((await(0,ee.listApprovalTemplates)()).map(ae),e)))}catch(e){D(E(e))}finally{K(!1)}}function Ae(){b(null),w(``),H([]),U(m[0]),G(``),q([]),Q(``,[]),M(!0)}function $(){R||M(!1)}async function je(){if(_){if(!v){D(`請選擇代理人`);return}if(v.id===_){D(`代理人不可設定為自己`);return}if(X.id===`TEMPLATE_LIST`&&V.length<1){D(`請選擇至少一個簽核模板`);return}if(pe(W,C)){D(`結束時間必須晚於起始時間`);return}z(!0),D(null);try{await(0,s.createDelegationRule)({agentMemberId:v.id,createdByMemberId:_,endAt:C||null,principalMemberId:_,priority:100,requiresConfirmation:!1,scopeConditionCel:null,scopeTemplateIds:X.id===`TEMPLATE_LIST`?V.map(e=>e.id):[],scopeType:X.id,startAt:W||null}),M(!1),N===1?await J():P(1)}catch(e){D(E(e))}finally{z(!1)}}}return(0,o.jsxs)(a.Layout,{children:[(0,o.jsx)(e.t,{activeHref:f}),(0,o.jsxs)(a.Layout.Main,{children:[(0,o.jsx)(a.PageHeader,{children:(0,o.jsx)(l.default,{description:`設定自己的簽核代理,讓指定期間內的新待簽任務自動交由代理人處理。`,title:`我的代理`,children:(0,o.jsx)(a.Button,{icon:c.PlusIcon,iconType:`leading`,onClick:Ae,variant:`base-primary`,children:`建立代理`})})}),(0,o.jsx)(a.SectionGroup,{children:(0,o.jsxs)(a.Section,{filterArea:(0,o.jsx)(a.FilterArea,{className:d.delegationFilterArea,size:`sub`,children:(0,o.jsx)(a.FilterLine,{children:(0,o.jsx)(a.Filter,{span:2,children:(0,o.jsx)(a.FormField,{fullWidth:!0,layout:u.FormFieldLayout.VERTICAL,name:`scopeFilterType`,children:(0,o.jsx)(a.Select,{clearable:!1,fullWidth:!0,onChange:e=>{Se(ce(e)),P(1)},options:[...p],placeholder:`代理範圍`,size:`sub`,value:B})})})})}),tab:(0,o.jsx)(a.Tab,{activeKey:I,onChange:e=>{ve(fe(e)),P(1)},children:ne.map(e=>(0,o.jsx)(a.TabItem,{children:e.label},e.key))}),children:[T?(0,o.jsx)(a.Typography,{color:`text-error`,variant:`body`,children:T}):null,(0,o.jsx)(a.Table,{actions:Oe,columns:De,dataSource:Ee,fullWidth:!0,loading:me,pagination:{current:N,onChange:e=>{P(e)},onChangePageSize:e=>{P(1),_e(e)},pageSize:F,pageSizeLabel:`每頁筆數`,pageSizeOptions:te,renderResultSummary:(e,t,n)=>`顯示 ${e}-${t} 筆,共 ${n} 筆`,showPageSizeOptions:!0,total:ye}})]})}),(0,o.jsx)(a.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!v},confirmText:`建立代理`,loading:R,modalType:`standard`,onCancel:$,onClose:$,onConfirm:()=>void je(),open:ge,showModalFooter:!0,showModalHeader:!0,size:`regular`,supportingText:`代理生效後,後續建立的待簽任務會依範圍自動指派給代理人。`,title:`建立個人代理`,children:(0,o.jsxs)(`div`,{className:d.delegationModalFields,children:[(0,o.jsx)(re,{label:`代理人`,loading:he,name:`agentMemberId`,onChange:b,onSearch:ke,options:A,value:v}),(0,o.jsx)(r.t,{label:`代理範圍`,name:`scopeType`,required:!0,children:(0,o.jsx)(a.Select,{clearable:!1,fullWidth:!0,onChange:e=>U(ue(e)),options:[...m],placeholder:`選擇代理範圍`,value:X})}),X.id===`TEMPLATE_LIST`?(0,o.jsx)(r.t,{label:`簽核模板`,name:`scopeTemplateIds`,required:!0,children:(0,o.jsx)(a.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的模板`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:`scopeTemplateIds`,spellCheck:!1},loading:we,loadingText:`搜尋模板中...`,mode:`multiple`,onChange:e=>{let t=oe(e);H(t),q(e=>y(t,e))},onSearch:Q,onVisibilityChange:e=>{e&&Q(``)},options:[...Te],overflowStrategy:`wrap`,placeholder:`搜尋並選取簽核模板`,searchDebounceTime:300,value:[...V]})}):null,(0,o.jsx)(r.t,{label:`起始時間`,name:`startAt`,children:(0,o.jsx)(a.DateTimePicker,{formatDate:`YYYY-MM-DD`,formatTime:`HH:mm`,fullWidth:!0,hideSecond:!0,onChange:e=>G(S(e)),placeholderLeft:`留空立即生效`,placeholderRight:`選擇時間`,value:x(W)})}),(0,o.jsx)(r.t,{label:`結束時間`,name:`endAt`,children:(0,o.jsx)(a.DateTimePicker,{formatDate:`YYYY-MM-DD`,formatTime:`HH:mm`,fullWidth:!0,hideSecond:!0,onChange:e=>w(S(e)),placeholderLeft:`可留空`,placeholderRight:`選擇時間`,value:x(C)})})]})})]})]})}function re({label:e,loading:t,name:n,onChange:i,onSearch:s,options:c,value:l}){return(0,o.jsx)(r.t,{label:e,layout:f,name:n,required:!0,children:(0,o.jsx)(a.AutoComplete,{asyncData:!0,disabledOptionsFilter:!0,emptyText:`沒有符合的成員`,inputProps:{autoCapitalize:`none`,autoCorrect:`off`,name:n,spellCheck:!1},loading:t,loadingText:`搜尋成員中...`,mode:`single`,onChange:e=>i(_(e)),onSearch:s,onSearchTextChange:e=>i(v(e,c)),onVisibilityChange:e=>{e&&s(``)},options:[...c],placeholder:`搜尋姓名或信箱`,searchDebounceTime:300,value:l})})}function ie({email:e,name:t}){return e?(0,o.jsx)(a.Tooltip,{title:e,children:({onMouseEnter:e,onMouseLeave:n,ref:r})=>(0,o.jsx)(`span`,{className:d.memberNameWithTooltip,onMouseEnter:e,onMouseLeave:n,ref:r,children:t})}):(0,o.jsx)(`span`,{children:t})}function g(e){return{displayName:e.name,email:e.email,id:e.memberId,name:`${e.name} (${e.email})`}}function _(e){if(!D(e))return null;let t=e.displayName,n=e.email,r=e.id,i=e.name;return typeof r==`string`&&typeof i==`string`?{displayName:typeof t==`string`?t:i,email:typeof n==`string`?n:null,id:r,name:i}:null}function v(e,t){let n=e.trim().toLocaleLowerCase();if(!n)return null;let r=t.filter(e=>[e.id,e.name,e.email??``].some(e=>e.toLocaleLowerCase().includes(n)));return r.length===1?r[0]??null:null}function ae(e){return{id:e.id,name:e.name}}function oe(e){return e.flatMap(e=>{if(!D(e))return[];let t=e.id,n=e.name;return typeof t==`string`&&typeof n==`string`?[{id:t,name:n}]:[]})}function se(e,t){let n=t.trim().toLocaleLowerCase();return n?e.filter(e=>[e.id,e.name].some(e=>e.toLocaleLowerCase().includes(n))):e}function y(e,t){return[...e,...t].reduce((e,t)=>e.some(e=>e.id===t.id)?e:[...e,t],[])}function ce(e){if(!D(e))return p[0];let t=e.id;return p.find(e=>e.id===t)??p[0]}function le(e){return e.scopeType===`ALL`?`全部簽核`:e.scopeType===`TEMPLATE_LIST`?`指定模板:${e.scopeTemplateIds.length}`:e.scopeConditionCel?`條件:${e.scopeConditionCel}`:`條件式`}function ue(e){return!D(e)||!b(e.id)?m[0]:m.find(t=>t.id===e.id)??m[0]}function b(e){return e===`ALL`||e===`TEMPLATE_LIST`}function de({status:e}){return e===`ACTIVE`?(0,o.jsx)(a.Badge,{size:`sub`,text:`啟用中`,variant:`dot-success`}):e===`REVOKED`?(0,o.jsx)(a.Badge,{size:`sub`,text:`已撤銷`,variant:`dot-inactive`}):e===`EXPIRED`?(0,o.jsx)(a.Badge,{size:`sub`,text:`已過期`,variant:`dot-warning`}):(0,o.jsx)(a.Badge,{size:`sub`,text:e,variant:`dot-info`})}function fe(e){return e===`ACTIVE`||e===`REVOKED`||e===`EXPIRED`?e:`ALL`}function x(e){let t=e?C(e):null;return t?`${w(t)}T${T(t.getHours())}:${T(t.getMinutes())}`:void 0}function S(e){let t=e?C(e):null;return t?t.toISOString():``}function pe(e,t){if(!e||!t)return!1;let n=C(e),r=C(t);return!!n&&!!r&&r.getTime()<=n.getTime()}function C(e){if(e.endsWith(`Z`)||/[+-]\d{2}:\d{2}$/.test(e)){let t=new Date(e);return Number.isNaN(t.getTime())?null:t}let[t=``,n=`00:00`]=e.split(`T`),[r=0,i=1,a=1]=t.split(`-`).map(Number),[o=0,s=0]=n.split(`:`).map(Number),c=new Date(r,i-1,a,o,s);return Number.isNaN(c.getTime())?null:c}function w(e){return`${e.getFullYear()}-${T(e.getMonth()+1)}-${T(e.getDate())}`}function T(e){return String(e).padStart(2,`0`)}function E(e){return e instanceof Error?e.message:`發生未知錯誤`}function D(e){return typeof e==`object`&&!!e}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return h}});
|
|
2
|
+
//# sourceMappingURL=DelegationsView-pKeFV2LN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DelegationsView-pKeFV2LN.cjs","names":[],"sources":["../../src/views/delegations/delegations.module.scss","../../src/views/delegations/DelegationsView.tsx"],"sourcesContent":[".delegationFilterArea {\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\n.delegationModalFields {\n display: grid;\n gap: 12px;\n width: 100%;\n\n :global(.mzn-form-field--horizontal) {\n align-items: flex-start;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label-area) {\n flex: 0 0 112px;\n width: 112px;\n min-width: 112px;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__label) {\n flex-wrap: nowrap;\n white-space: nowrap;\n }\n\n :global(.mzn-form-field--horizontal .mzn-form-field__data-entry) {\n flex: 1 1 auto;\n align-items: stretch;\n min-width: 0;\n max-width: none;\n }\n\n :global(.mzn-form-field__control-field-slot--main) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-autocomplete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-picker),\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 :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.memberNameWithTooltip {\n cursor: help;\n text-decoration: underline dotted;\n text-underline-offset: 3px;\n}\n","'use client';\n\nimport {\n Key,\n ReactElement,\n RefCallback,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Badge,\n Button,\n DateTimePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Layout,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Tooltip,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { BPMFormField } from '../../components/bpm-form-field';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { AppNavigation } from '../../components/app-navigation';\nimport { useAuth } from '../../lib/auth-provider';\nimport {\n DelegationRuleRecord,\n DelegationRuleStatus,\n DelegationScopeType,\n MemberProfileRecord,\n createDelegationRule,\n listDelegationRulesPage,\n revokeDelegationRule,\n searchMembers,\n} from '@rytass/bpm-core-client/workflow';\nimport {\n ApprovalTemplateRecord,\n listApprovalTemplates,\n} from '@rytass/bpm-core-client/template';\nimport styles from './delegations.module.scss';\n\ntype DelegationStatusTabKey = 'ALL' | DelegationRuleStatus;\n\ntype MemberOption = Readonly<{\n displayName: string;\n email: string | null;\n id: string;\n name: string;\n}>;\n\ntype ScopeOption = Readonly<{\n id: DelegationScopeType;\n name: string;\n}>;\n\ntype ScopeFilterOption = Readonly<{\n id: 'ALL_SCOPES' | DelegationScopeType;\n name: string;\n scopeType: DelegationScopeType | null;\n}>;\n\ntype TemplateOption = Readonly<{\n id: string;\n name: string;\n}>;\n\ntype DelegationRuleRow = Readonly<\n Record<string, unknown> &\n DelegationRuleRecord & {\n agentEmail: string | null;\n agentName: string;\n key: string;\n scopeLabel: string;\n }\n>;\n\nconst DELEGATION_MODAL_FIELD_LAYOUT = FormFieldLayout.HORIZONTAL;\nconst DELEGATION_PAGE_SIZE_OPTIONS = [10, 20, 50];\nconst DELEGATION_STATUS_TABS: readonly {\n readonly key: DelegationStatusTabKey;\n readonly label: string;\n}[] = [\n { key: 'ALL', label: '全部' },\n { key: 'ACTIVE', label: '啟用中' },\n { key: 'REVOKED', label: '已撤銷' },\n { key: 'EXPIRED', label: '已過期' },\n];\nconst SCOPE_FILTER_OPTIONS: readonly ScopeFilterOption[] = [\n { id: 'ALL_SCOPES', name: '全部範圍', scopeType: null },\n { id: 'ALL', name: '全部簽核', scopeType: 'ALL' },\n { id: 'TEMPLATE_LIST', name: '指定模板', scopeType: 'TEMPLATE_LIST' },\n];\nconst SCOPE_OPTIONS: readonly ScopeOption[] = [\n { id: 'ALL', name: '全部簽核' },\n { id: 'TEMPLATE_LIST', name: '指定模板' },\n];\n\nexport interface DelegationsViewProps {\n readonly activeHref?: string;\n}\n\nexport function DelegationsView({\n activeHref = '/delegations',\n}: DelegationsViewProps = {}): ReactElement {\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [agentMember, setAgentMember] = useState<MemberOption | null>(null);\n const [endAt, setEndAt] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const [memberLoading, setMemberLoading] = useState(false);\n const [memberOptions, setMemberOptions] = useState<readonly MemberOption[]>(\n [],\n );\n const [modalOpen, setModalOpen] = useState(false);\n const [rulePage, setRulePage] = useState(1);\n const [rulePageSize, setRulePageSize] = useState(10);\n const [ruleStatus, setRuleStatus] = useState<DelegationStatusTabKey>('ALL');\n const [ruleTotalCount, setRuleTotalCount] = useState(0);\n const [rules, setRules] = useState<readonly DelegationRuleRecord[]>([]);\n const [saving, setSaving] = useState(false);\n const [scopeFilterType, setScopeFilterType] = useState<ScopeFilterOption>(\n SCOPE_FILTER_OPTIONS[0],\n );\n const [scopeTemplates, setScopeTemplates] = useState<\n readonly TemplateOption[]\n >([]);\n const [scopeType, setScopeType] = useState<ScopeOption>(SCOPE_OPTIONS[0]);\n const [startAt, setStartAt] = useState('');\n const [templateLoading, setTemplateLoading] = useState(false);\n const [templateOptions, setTemplateOptions] = useState<\n readonly TemplateOption[]\n >([]);\n\n const refreshRules = useCallback(async (): Promise<void> => {\n if (!currentMemberId) {\n setLoading(false);\n return;\n }\n\n setLoading(true);\n setError(null);\n\n try {\n const [rulePageResult, members] = await Promise.all([\n listDelegationRulesPage({\n includeInactive: true,\n page: rulePage,\n pageSize: rulePageSize,\n principalMemberId: currentMemberId,\n scopeType: scopeFilterType.scopeType,\n status: ruleStatus === 'ALL' ? null : ruleStatus,\n }),\n searchMembers(''),\n ]);\n\n setRules(rulePageResult.rules);\n setRuleTotalCount(rulePageResult.totalCount);\n setMemberOptions(members.map(readMemberOption));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [currentMemberId, rulePage, rulePageSize, ruleStatus, scopeFilterType]);\n\n useEffect((): void => {\n void refreshRules();\n }, [refreshRules]);\n\n const membersById = useMemo(\n (): ReadonlyMap<string, MemberOption> =>\n new Map(memberOptions.map((option) => [option.id, option])),\n [memberOptions],\n );\n const rows = useMemo(\n (): DelegationRuleRow[] =>\n rules.map((rule) => ({\n ...rule,\n agentEmail: membersById.get(rule.agentMemberId)?.email ?? null,\n agentName:\n membersById.get(rule.agentMemberId)?.displayName ??\n rule.agentMemberId,\n key: rule.id,\n scopeLabel: readScopeLabel(rule),\n })),\n [membersById, rules],\n );\n const selectedScopeType =\n SCOPE_OPTIONS.find((option) => option.id === scopeType.id) ??\n SCOPE_OPTIONS[0];\n const columns = useMemo(\n (): TableColumn<DelegationRuleRow>[] => [\n {\n key: 'agent',\n render: (record: DelegationRuleRow): ReactElement => (\n <MemberNameWithEmailTooltip\n email={record.agentEmail}\n name={record.agentName}\n />\n ),\n title: '代理人',\n width: 220,\n },\n { dataIndex: 'scopeLabel', key: 'scope', title: '代理範圍', width: 220 },\n {\n key: 'status',\n render: (record: DelegationRuleRow): ReactElement => (\n <DelegationStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'startAt',\n render: (record: DelegationRuleRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startAt)}\n </Typography>\n ),\n title: '開始時間',\n width: 220,\n },\n {\n key: 'endAt',\n render: (record: DelegationRuleRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.endAt ? formatDateTime(record.endAt) : '-'}\n </Typography>\n ),\n title: '結束時間',\n width: 220,\n },\n ],\n [],\n );\n const handleRevoke = useCallback(\n async (id: string): Promise<void> => {\n if (!currentMemberId) {\n return;\n }\n\n setError(null);\n\n try {\n await revokeDelegationRule({\n id,\n revokedByMemberId: currentMemberId,\n });\n await refreshRules();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n }\n },\n [currentMemberId, refreshRules],\n );\n const tableActions = useMemo(\n (): TableActions<DelegationRuleRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<DelegationRuleRow>['render']> =>\n record.status === 'ACTIVE'\n ? [\n {\n name: '撤銷',\n onClick: (): void => void handleRevoke(record.id),\n },\n ]\n : [],\n variant: 'destructive-secondary',\n width: 88,\n }),\n [handleRevoke],\n );\n\n async function handleSearchMembers(searchText: string): Promise<void> {\n setMemberLoading(true);\n\n try {\n setMemberOptions((await searchMembers(searchText)).map(readMemberOption));\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setMemberLoading(false);\n }\n }\n\n async function handleSearchTemplates(\n searchText: string,\n selectedOptions: readonly TemplateOption[] = scopeTemplates,\n ): Promise<void> {\n setTemplateLoading(true);\n\n try {\n const nextOptions = (await listApprovalTemplates()).map(\n readTemplateOption,\n );\n\n setTemplateOptions(\n mergeTemplateOptions(\n selectedOptions,\n filterTemplateOptions(nextOptions, searchText),\n ),\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setTemplateLoading(false);\n }\n }\n\n function openCreateModal(): void {\n setAgentMember(null);\n setEndAt('');\n setScopeTemplates([]);\n setScopeType(SCOPE_OPTIONS[0]);\n setStartAt('');\n setTemplateOptions([]);\n void handleSearchTemplates('', []);\n setModalOpen(true);\n }\n\n function closeCreateModal(): void {\n if (saving) {\n return;\n }\n\n setModalOpen(false);\n }\n\n async function handleCreate(): Promise<void> {\n if (!currentMemberId) {\n return;\n }\n\n if (!agentMember) {\n setError('請選擇代理人');\n return;\n }\n\n if (agentMember.id === currentMemberId) {\n setError('代理人不可設定為自己');\n return;\n }\n\n if (selectedScopeType.id === 'TEMPLATE_LIST' && scopeTemplates.length < 1) {\n setError('請選擇至少一個簽核模板');\n return;\n }\n\n if (isInvalidDelegationDateRange(startAt, endAt)) {\n setError('結束時間必須晚於起始時間');\n return;\n }\n\n setSaving(true);\n setError(null);\n\n try {\n await createDelegationRule({\n agentMemberId: agentMember.id,\n createdByMemberId: currentMemberId,\n endAt: endAt || null,\n principalMemberId: currentMemberId,\n priority: 100,\n requiresConfirmation: false,\n scopeConditionCel: null,\n scopeTemplateIds:\n selectedScopeType.id === 'TEMPLATE_LIST'\n ? scopeTemplates.map((template) => template.id)\n : [],\n scopeType: selectedScopeType.id,\n startAt: startAt || null,\n });\n setModalOpen(false);\n\n if (rulePage === 1) {\n await refreshRules();\n } else {\n setRulePage(1);\n }\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n return (\n <Layout>\n <AppNavigation activeHref={activeHref} />\n\n <Layout.Main>\n <PageHeader>\n <ContentHeader\n description=\"設定自己的簽核代理,讓指定期間內的新待簽任務自動交由代理人處理。\"\n title=\"我的代理\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={openCreateModal}\n variant=\"base-primary\"\n >\n 建立代理\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section\n filterArea={\n <FilterArea className={styles.delegationFilterArea} size=\"sub\">\n <FilterLine>\n <Filter span={2}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"scopeFilterType\"\n >\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void => {\n setScopeFilterType(readScopeFilterOption(option));\n setRulePage(1);\n }}\n options={[...SCOPE_FILTER_OPTIONS]}\n placeholder=\"代理範圍\"\n size=\"sub\"\n value={scopeFilterType}\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n tab={\n <Tab\n activeKey={ruleStatus}\n onChange={(activeKey): void => {\n setRuleStatus(readDelegationStatusTabKey(activeKey));\n setRulePage(1);\n }}\n >\n {DELEGATION_STATUS_TABS.map((statusTab) => (\n <TabItem key={statusTab.key}>{statusTab.label}</TabItem>\n ))}\n </Tab>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: rulePage,\n onChange: (page): void => {\n setRulePage(page);\n },\n onChangePageSize: (pageSize): void => {\n setRulePage(1);\n setRulePageSize(pageSize);\n },\n pageSize: rulePageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: DELEGATION_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: ruleTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{\n disabled: !agentMember,\n }}\n confirmText=\"建立代理\"\n loading={saving}\n modalType=\"standard\"\n onCancel={closeCreateModal}\n onClose={closeCreateModal}\n onConfirm={(): void => void handleCreate()}\n open={modalOpen}\n showModalFooter\n showModalHeader\n size=\"regular\"\n supportingText=\"代理生效後,後續建立的待簽任務會依範圍自動指派給代理人。\"\n title=\"建立個人代理\"\n >\n <div className={styles.delegationModalFields}>\n <MemberAutoCompleteField\n label=\"代理人\"\n loading={memberLoading}\n name=\"agentMemberId\"\n onChange={setAgentMember}\n onSearch={handleSearchMembers}\n options={memberOptions}\n value={agentMember}\n />\n <BPMFormField label=\"代理範圍\" name=\"scopeType\" required>\n <Select\n clearable={false}\n fullWidth\n onChange={(option): void =>\n setScopeType(readScopeOptionFromValue(option))\n }\n options={[...SCOPE_OPTIONS]}\n placeholder=\"選擇代理範圍\"\n value={selectedScopeType}\n />\n </BPMFormField>\n {selectedScopeType.id === 'TEMPLATE_LIST' ? (\n <BPMFormField label=\"簽核模板\" name=\"scopeTemplateIds\" required>\n <AutoComplete\n asyncData\n disabledOptionsFilter\n emptyText=\"沒有符合的模板\"\n inputProps={{\n autoCapitalize: 'none',\n autoCorrect: 'off',\n name: 'scopeTemplateIds',\n spellCheck: false,\n }}\n loading={templateLoading}\n loadingText=\"搜尋模板中...\"\n mode=\"multiple\"\n onChange={(nextTemplates): void => {\n const selectedTemplates =\n readTemplateOptionsFromValue(nextTemplates);\n\n setScopeTemplates(selectedTemplates);\n setTemplateOptions((currentOptions) =>\n mergeTemplateOptions(selectedTemplates, currentOptions),\n );\n }}\n onSearch={handleSearchTemplates}\n onVisibilityChange={(open): void => {\n if (open) {\n void handleSearchTemplates('');\n }\n }}\n options={[...templateOptions]}\n overflowStrategy=\"wrap\"\n placeholder=\"搜尋並選取簽核模板\"\n searchDebounceTime={300}\n value={[...scopeTemplates]}\n />\n </BPMFormField>\n ) : null}\n <BPMFormField label=\"起始時間\" name=\"startAt\">\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n fullWidth\n hideSecond\n onChange={(nextValue): void =>\n setStartAt(formatDelegationDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"留空立即生效\"\n placeholderRight=\"選擇時間\"\n value={readDelegationDateTimePickerValue(startAt)}\n />\n </BPMFormField>\n <BPMFormField label=\"結束時間\" name=\"endAt\">\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n fullWidth\n hideSecond\n onChange={(nextValue): void =>\n setEndAt(formatDelegationDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"可留空\"\n placeholderRight=\"選擇時間\"\n value={readDelegationDateTimePickerValue(endAt)}\n />\n </BPMFormField>\n </div>\n </Modal>\n </Layout.Main>\n </Layout>\n );\n}\n\nfunction MemberAutoCompleteField({\n label,\n loading,\n name,\n onChange,\n onSearch,\n options,\n value,\n}: {\n readonly label: string;\n readonly loading: boolean;\n readonly name: string;\n readonly onChange: (option: MemberOption | null) => void;\n readonly onSearch: (searchText: string) => Promise<void>;\n readonly options: readonly MemberOption[];\n readonly value: MemberOption | null;\n}): ReactElement {\n return (\n <BPMFormField\n label={label}\n layout={DELEGATION_MODAL_FIELD_LAYOUT}\n name={name}\n required\n >\n <AutoComplete\n asyncData\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={onSearch}\n onSearchTextChange={(searchText): void =>\n onChange(readUniqueMemberOption(searchText, options))\n }\n onVisibilityChange={(open): void => {\n if (open) {\n void onSearch('');\n }\n }}\n options={[...options]}\n placeholder=\"搜尋姓名或信箱\"\n searchDebounceTime={300}\n value={value}\n />\n </BPMFormField>\n );\n}\n\nfunction MemberNameWithEmailTooltip({\n email,\n name,\n}: {\n readonly email: string | null;\n readonly name: string;\n}): ReactElement {\n if (!email) {\n return <span>{name}</span>;\n }\n\n return (\n <Tooltip title={email}>\n {({ onMouseEnter, onMouseLeave, ref }): ReactElement => (\n <span\n className={styles.memberNameWithTooltip}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n ref={ref as RefCallback<HTMLSpanElement>}\n >\n {name}\n </span>\n )}\n </Tooltip>\n );\n}\n\nfunction readMemberOption(member: MemberProfileRecord): MemberOption {\n return {\n displayName: member.name,\n email: member.email,\n id: member.memberId,\n name: `${member.name} (${member.email})`,\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const displayName = value.displayName;\n const email = value.email;\n const id = value.id;\n const name = value.name;\n\n return typeof id === 'string' && typeof name === 'string'\n ? {\n displayName: typeof displayName === 'string' ? displayName : name,\n email: typeof email === 'string' ? email : null,\n id,\n name,\n }\n : null;\n}\n\nfunction readUniqueMemberOption(\n searchText: string,\n options: readonly MemberOption[],\n): MemberOption | null {\n const normalizedSearchText = searchText.trim().toLocaleLowerCase();\n\n if (!normalizedSearchText) {\n return null;\n }\n\n const matches = options.filter((option) =>\n [option.id, option.name, option.email ?? ''].some((value) =>\n value.toLocaleLowerCase().includes(normalizedSearchText),\n ),\n );\n\n return matches.length === 1 ? (matches[0] ?? null) : null;\n}\n\nfunction readTemplateOption(template: ApprovalTemplateRecord): TemplateOption {\n return {\n id: template.id,\n name: template.name,\n };\n}\n\nfunction readTemplateOptionsFromValue(\n value: readonly unknown[],\n): readonly TemplateOption[] {\n return value.flatMap((item): readonly TemplateOption[] => {\n if (!isRecord(item)) {\n return [];\n }\n\n const id = item.id;\n const name = item.name;\n\n return typeof id === 'string' && typeof name === 'string'\n ? [{ id, name }]\n : [];\n });\n}\n\nfunction filterTemplateOptions(\n options: readonly TemplateOption[],\n searchText: string,\n): readonly TemplateOption[] {\n const normalizedSearchText = searchText.trim().toLocaleLowerCase();\n\n if (!normalizedSearchText) {\n return options;\n }\n\n return options.filter((option) =>\n [option.id, option.name].some((value) =>\n value.toLocaleLowerCase().includes(normalizedSearchText),\n ),\n );\n}\n\nfunction mergeTemplateOptions(\n selectedOptions: readonly TemplateOption[],\n availableOptions: readonly TemplateOption[],\n): readonly TemplateOption[] {\n return [...selectedOptions, ...availableOptions].reduce<TemplateOption[]>(\n (options, option) =>\n options.some((currentOption) => currentOption.id === option.id)\n ? options\n : [...options, option],\n [],\n );\n}\n\nfunction readScopeFilterOption(value: unknown): ScopeFilterOption {\n if (!isRecord(value)) {\n return SCOPE_FILTER_OPTIONS[0];\n }\n\n const id = value.id;\n\n return (\n SCOPE_FILTER_OPTIONS.find((option) => option.id === id) ??\n SCOPE_FILTER_OPTIONS[0]\n );\n}\n\nfunction readScopeLabel(rule: DelegationRuleRecord): string {\n if (rule.scopeType === 'ALL') {\n return '全部簽核';\n }\n\n if (rule.scopeType === 'TEMPLATE_LIST') {\n return `指定模板:${rule.scopeTemplateIds.length}`;\n }\n\n return rule.scopeConditionCel ? `條件:${rule.scopeConditionCel}` : '條件式';\n}\n\nfunction readScopeOptionFromValue(value: unknown): ScopeOption {\n if (!isRecord(value) || !isSelectableDelegationScopeType(value.id)) {\n return SCOPE_OPTIONS[0];\n }\n\n return (\n SCOPE_OPTIONS.find((option) => option.id === value.id) ?? SCOPE_OPTIONS[0]\n );\n}\n\nfunction isSelectableDelegationScopeType(\n value: unknown,\n): value is ScopeOption['id'] {\n return value === 'ALL' || value === 'TEMPLATE_LIST';\n}\n\nfunction DelegationStatusBadge({\n status,\n}: {\n readonly status: DelegationRuleRecord['status'];\n}): ReactElement {\n if (status === 'ACTIVE') {\n return <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />;\n }\n\n if (status === 'REVOKED') {\n return <Badge size=\"sub\" text=\"已撤銷\" variant=\"dot-inactive\" />;\n }\n\n if (status === 'EXPIRED') {\n return <Badge size=\"sub\" text=\"已過期\" variant=\"dot-warning\" />;\n }\n\n return <Badge size=\"sub\" text={status} variant=\"dot-info\" />;\n}\n\nfunction readDelegationStatusTabKey(activeKey: Key): DelegationStatusTabKey {\n if (\n activeKey === 'ACTIVE' ||\n activeKey === 'REVOKED' ||\n activeKey === 'EXPIRED'\n ) {\n return activeKey;\n }\n\n return 'ALL';\n}\n\nfunction readDelegationDateTimePickerValue(value: string): string | undefined {\n const date = value ? parseDelegationDateTimeValue(value) : null;\n\n return date\n ? `${formatDateParts(date)}T${padDatePart(date.getHours())}:${padDatePart(\n date.getMinutes(),\n )}`\n : undefined;\n}\n\nfunction formatDelegationDateTimePickerValue(\n value: string | undefined,\n): string {\n const date = value ? parseDelegationDateTimeValue(value) : null;\n\n return date ? date.toISOString() : '';\n}\n\nfunction isInvalidDelegationDateRange(startAt: string, endAt: string): boolean {\n if (!startAt || !endAt) {\n return false;\n }\n\n const startDate = parseDelegationDateTimeValue(startAt);\n const endDate = parseDelegationDateTimeValue(endAt);\n\n return !!startDate && !!endDate && endDate.getTime() <= startDate.getTime();\n}\n\nfunction parseDelegationDateTimeValue(value: string): Date | null {\n if (value.endsWith('Z') || /[+-]\\d{2}:\\d{2}$/.test(value)) {\n const parsedDate = new Date(value);\n\n return Number.isNaN(parsedDate.getTime()) ? null : parsedDate;\n }\n\n const [datePart = '', timePart = '00:00'] = value.split('T');\n const [year = 0, month = 1, day = 1] = datePart.split('-').map(Number);\n const [hour = 0, minute = 0] = timePart.split(':').map(Number);\n const parsedDate = new Date(year, month - 1, day, hour, minute);\n\n return Number.isNaN(parsedDate.getTime()) ? null : parsedDate;\n}\n\nfunction formatDateParts(date: Date): string {\n return `${date.getFullYear()}-${padDatePart(date.getMonth() + 1)}-${padDatePart(\n date.getDate(),\n )}`;\n}\n\nfunction padDatePart(value: number): string {\n return String(value).padStart(2, '0');\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\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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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";const e=require("./app-navigation-DAC5gFbG.cjs"),t=require("./router-adapter-BybHrCNP.cjs"),n=require("./format-date-time-BQyH5U8z.cjs"),r=require("./bpm-form-field-Bc6k4ZEO.cjs"),i=require("./FormRendererView-BwVsH2eX.cjs"),a=require("./form-name-modal-uZCHbtRH.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@mezzanine-ui/icons"),u=require("@mezzanine-ui/react/ContentHeader");u=e.o(u,1);let d=require("@rytass/bpm-core-client/form"),f=require("@hello-pangea/dnd"),p=require("next/dynamic");p=e.o(p,1);let m=require("@codemirror/lang-json"),h=require("@codemirror/view");var g={alignItems:`center`,border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:4,color:`var(--mzn-color-text-neutral)`,display:`flex`,minHeight:160,padding:12,width:`100%`},_=[(0,m.json)(),h.EditorView.lineWrapping,h.EditorView.theme({"&":{border:`1px solid var(--mzn-color-border-neutral)`,borderRadius:`4px`,fontSize:`13px`,width:`100%`},"&.cm-focused":{outline:`1px solid var(--mzn-color-border-primary)`},".cm-content":{fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace`,minHeight:`100%`},".cm-editor":{width:`100%`},".cm-gutters":{borderRight:`1px solid var(--mzn-color-border-neutral)`},".cm-scroller":{fontFamily:`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace`}})],v=(0,p.default)(()=>import(`@uiw/react-codemirror`),{loading:()=>(0,c.jsx)(`div`,{style:g,children:`載入 JSON 編輯器`}),ssr:!1});function ee({disabled:e,height:t,name:n,onChange:r,placeholder:i,value:a}){return(0,c.jsx)(v,{"aria-label":n,basicSetup:{autocompletion:!0,bracketMatching:!0,closeBrackets:!0,defaultKeymap:!0,foldGutter:!0,highlightActiveLine:!0,highlightSelectionMatches:!0,lineNumbers:!0,syntaxHighlighting:!0},editable:!e,extensions:[..._],height:t,indentWithTab:!1,onChange:r,placeholder:i,readOnly:e,theme:`light`,value:a,width:`100%`})}var te=[{description:`單行文字、姓名、編號`,icon:l.AlignLeftIcon,label:`文字`,type:`text`},{description:`多行補充內容`,icon:l.FileIcon,label:`長文字`,type:`textarea`},{description:`金額、數量、分數`,icon:l.CurrencyDollarIcon,label:`數字`,type:`number`},{description:`金額與費用`,icon:l.CurrencyDollarIcon,label:`金額`,type:`money`},{description:`日期或到期日`,icon:l.CalendarIcon,label:`日期`,type:`date`},{description:`日期與時間`,icon:l.CalendarIcon,label:`日期時間`,type:`datetime`},{description:`是 / 否狀態`,icon:l.CheckedIcon,label:`開關`,type:`boolean`},{description:`固定選項擇一`,icon:l.ListIcon,label:`下拉選單`,type:`select`},{description:`固定選項單選`,icon:l.DotGridIcon,label:`單選`,type:`radio`},{description:`固定選項複選`,icon:l.CheckedOutlineIcon,label:`複選`,type:`checkbox`},{description:`附件或佐證資料`,icon:l.FileAttachmentIcon,label:`附件`,type:`file_upload`}],ne={alignItems:`start`,display:`flex`,flexWrap:`wrap`,gap:16},re={flex:`0.55 1 300px`,minWidth:0},ie={flex:`1.45 1 720px`,minWidth:620},y={display:`grid`,gap:12},ae={display:`flex`,flexWrap:`wrap`,gap:6},oe={flex:`0 0 auto`,whiteSpace:`nowrap`},se={display:`grid`,gap:8},ce={alignItems:`center`,cursor:`grab`,display:`flex`,gap:12,touchAction:`none`},le={display:`grid`,flex:`1 1 auto`,gap:2,minWidth:0},ue={alignItems:`center`,display:`flex`,flex:`0 0 auto`,gap:4},de={alignItems:`center`,display:`flex`,gap:6},fe={userSelect:`none`},pe={filter:`drop-shadow(0 8px 18px rgba(0, 0, 0, 0.12))`},me={alignItems:`center`,border:`1px dashed var(--mzn-color-border-neutral)`,borderRadius:6,display:`grid`,gap:12,minHeight:240,padding:32,textAlign:`center`},he={display:`flex`,gap:8,justifyContent:`center`},ge={display:`grid`,gap:14},_e={display:`grid`,columnGap:16,gridTemplateColumns:`repeat(auto-fit, minmax(280px, 1fr))`,rowGap:8},ve={gridColumn:`1 / -1`},ye={alignItems:`center`,display:`flex`,gap:8,gridColumn:`1 / -1`,justifyContent:`flex-end`},be={gridColumn:`1 / -1`},xe={alignItems:`start`,display:`block`,width:`100%`},Se={...xe,gridColumn:`1 / -1`},Ce={minWidth:0,width:`100%`},we={minWidth:`100%`,width:`100%`},Te={display:`grid`,gap:14},Ee={alignItems:`start`,display:`block`,width:`100%`},De={minWidth:0,width:`100%`},Oe={gridColumn:`2 / -1`},ke={display:`grid`,gap:10,width:`100%`},Ae={display:`grid`,gap:8,gridTemplateColumns:`repeat(auto-fit, minmax(160px, 1fr))`},je={display:`inline-flex`},Me={display:`grid`,gap:16},Ne={display:`grid`,gap:8},Pe={display:`flex`,justifyContent:`flex-end`},Fe={color:`var(--mzn-color-text-error)`,fontSize:`0.72em`,lineHeight:0,marginLeft:2,verticalAlign:`super`};function Ie(e){e&&(e.style.width=`100%`)}var b={fields:[],schemaVersion:1},x={layout:[],schemaVersion:1},Le=[{id:`unset`,name:`不預設`},{id:`true`,name:`是`},{id:`false`,name:`否`}],Re=[{id:`true`,name:`是`},{id:`false`,name:`否`}],ze=[{label:`顯示`,name:`fieldVisibleWhen`,supportingText:`符合條件時才顯示這個欄位。`,target:`visibleWhen`},{label:`必填`,name:`fieldRequiredWhen`,supportingText:`符合條件時才要求填寫這個欄位。`,target:`requiredWhen`},{label:`唯讀`,name:`fieldReadonlyWhen`,supportingText:`符合條件時不允許修改這個欄位。`,target:`readonlyWhen`}];function S({formId:p}){let m=t.r(),h=p,[g,_]=(0,o.useState)(null),[v,S]=(0,o.useState)(null),[T,D]=(0,o.useState)(b),[k,A]=(0,o.useState)(x),[Qe,j]=(0,o.useState)(w(b)),[$e,M]=(0,o.useState)(w(x)),[et,tt]=(0,o.useState)({}),[nt,N]=(0,o.useState)(null),[P,rt]=(0,o.useState)(`design`),[F,I]=(0,o.useState)(null),[it,L]=(0,o.useState)(null),[at,R]=(0,o.useState)(!1),[ot,st]=(0,o.useState)(E(b,x)),[ct,lt]=(0,o.useState)(!0),[ut,dt]=(0,o.useState)(!1),[z,B]=(0,o.useState)(!1);(0,o.useEffect)(()=>{W()},[h]),(0,o.useEffect)(()=>{T.fields.some(e=>e.fieldKey===F)||I(T.fields[0]?.fieldKey??null)},[T.fields,F]),(0,o.useEffect)(()=>{tt(e=>(0,d.buildFormRendererValues)(T.fields,e))},[T.fields]),(0,o.useEffect)(()=>{P!==`advanced`&&(j(w(T)),M(w(k)))},[P,T,k]);let V=(0,o.useMemo)(()=>T.fields.find(e=>e.fieldKey===F)??T.fields[0]??null,[T.fields,F]),ft=(0,o.useMemo)(()=>(g?.versions??[]).map(e=>({key:e.id,publishedAt:n.t(e.publishedAt),status:e.status,updatedAt:n.t(e.updatedAt),version:`v${e.version}`})),[g]),pt=(0,o.useMemo)(()=>[{dataIndex:`version`,key:`version`,title:`版本`,width:120},{key:`status`,render:e=>(0,c.jsx)(Ze,{status:e.status}),title:`狀態`,width:140},{dataIndex:`updatedAt`,key:`updatedAt`,title:`最後更新`,width:180},{dataIndex:`publishedAt`,key:`publishedAt`,title:`發布時間`,width:180}],[]),mt=(0,o.useMemo)(()=>E(T,k),[T,k]),H=mt.schemaJson!==ot.schemaJson||mt.uiSchemaJson!==ot.uiSchemaJson;(0,o.useEffect)(()=>{function e(e){H&&(e.preventDefault(),e.returnValue=``)}return window.addEventListener(`beforeunload`,e),()=>{window.removeEventListener(`beforeunload`,e)}},[H]);function ht(){H&&!window.confirm(`目前有尚未儲存的表單草稿,確定要離開嗎?`)||m.push(`/forms`)}let gt=(0,o.useMemo)(()=>Je(g?.versions??[],g?.definition.currentVersionId),[g?.definition.currentVersionId,g?.versions]),_t=v??gt??g?.versions[0]??null,U=!H&&_t?.status===`PUBLISHED`,vt=Ye({hasUnsavedChanges:H,latestPublishedVersion:gt,openedContentPublished:U,openedVersion:_t}),yt=z||!H&&U&&!v,bt=H?`保存並發布`:v?`發布草稿`:U?`已發布`:`發布版本`;async function W(){lt(!0),L(null);try{let e=await(0,d.readFormBuilder)(h),t=e.versions.find(e=>e.status===`DRAFT`)??null;_(e),S(t);let n=t?.schema??e.versions[0]?.schema??b,r=t?.uiSchema??e.versions[0]?.uiSchema??x;D(n),A(r),st(E(n,r)),j(w(n)),M(w(r)),I(t?.schema.fields[0]?.fieldKey??e.versions[0]?.schema.fields[0]?.fieldKey??null),N(null)}catch(e){L(O(e))}finally{lt(!1)}}async function xt(){let e=await(0,d.updateFormDefinitionDraft)((v??await(0,d.forkFormDefinition)(h)).id,T,k);return S(e),e}async function St(){B(!0),L(null);try{await xt(),await W()}catch(e){L(O(e))}finally{B(!1)}}async function Ct(){B(!0),L(null);try{await(0,d.publishFormDefinitionVersion)((await xt()).id),await W()}catch(e){L(O(e))}finally{B(!1)}}async function wt(e){if(!g)throw Error(`尚未載入表單資料`);dt(!0);try{let t=await(0,d.updateFormDefinition)(g.definition.id,e);_({...g,definition:t}),R(!1)}finally{dt(!1)}}function G(e){let t=(0,d.createFieldDefinition)(e,T.fields.length+1);D({...T,fields:[...T.fields,t]}),A({...k,layout:[...k.layout,{fieldKey:t.fieldKey,width:e===`textarea`||e===`file_upload`?`FULL`:`HALF`}]}),I(t.fieldKey),rt(`design`),N(null)}function Tt(e){let t=e;t===`advanced`&&P!==`advanced`&&(j(w(T)),M(w(k))),rt(t)}function Et(e){let t=T.fields.filter(t=>t.fieldKey!==e);D({...T,fields:t}),A({...k,layout:k.layout.filter(t=>t.fieldKey!==e)}),I(F===e?t[0]?.fieldKey??null:F),N(null)}function Dt(e){let t=e.destination;t&&e.source.index!==t.index&&(D(n=>({...n,fields:Xe(n.fields,e.source.index,t.index)})),A(n=>({...n,layout:Xe(n.layout,e.source.index,t.index)})),N(null))}function K(e){q(t=>({...t,...e}))}function q(e){if(!V)return;let t=V.fieldKey,n=e(V),r=n.fieldKey;D({...T,fields:T.fields.map(e=>e.fieldKey===t?n:e)}),A({...k,layout:k.layout.map(e=>e.fieldKey===t?{...e,fieldKey:r}:e)}),I(r),N(null)}function J(e){q(t=>Ue(t)?{...t,...e}:t)}function Y(e){q(t=>(0,d.isNumberFieldDefinition)(t)?{...t,...e}:t)}function Ot(e){q(t=>(0,d.isDateFieldDefinition)(t)?{...t,...e}:t)}function X(e){q(t=>(0,d.isSelectFieldDefinition)(t)?{...t,...e}:t)}function kt(e){q(t=>t.type===`boolean`?{...t,...e}:t)}function At(e){q(t=>t.type===`file_upload`?{...t,...e}:t)}function jt(e){tt(e)}function Mt(e,t){D(n=>({...n,fields:n.fields.map(n=>n.fieldKey===e?{...n,required:t}:n)})),N(null)}function Nt(e){j(e);try{D(JSON.parse(e)),N(null)}catch{N(`Form Schema JSON 格式不正確`)}}function Pt(e){M(e);try{A(JSON.parse(e)),N(null)}catch{N(`UI Schema JSON 格式不正確`)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsxs)(s.Layout,{children:[(0,c.jsx)(e.t,{activeHref:`/forms`}),(0,c.jsxs)(s.Layout.Main,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsxs)(u.default,{description:vt,onBackClick:ht,title:g?.definition.name??`表單設計器`,children:[(0,c.jsx)(s.Button,{"aria-label":`修改表單名稱`,disabled:ut||!g,icon:l.EditIcon,iconType:`icon-only`,onClick:()=>R(!0),variant:`base-ghost`,children:`修改表單名稱`}),(0,c.jsx)(s.Button,{"aria-label":`儲存草稿`,disabled:z||!H,icon:l.SaveIcon,iconType:`icon-only`,onClick:()=>void St(),variant:`base-secondary`,children:`儲存草稿`}),(0,c.jsx)(s.Button,{disabled:yt,icon:l.CheckedIcon,iconType:`leading`,onClick:()=>void Ct(),variant:`base-primary`,children:bt})]})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsx)(s.Section,{children:(0,c.jsxs)(`div`,{style:Me,children:[it?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:it}):null,(0,c.jsxs)(s.Tab,{activeKey:P,onChange:Tt,size:`sub`,children:[(0,c.jsx)(s.TabItem,{children:`設計`},`design`),(0,c.jsx)(s.TabItem,{children:`預覽`},`preview`),(0,c.jsx)(s.TabItem,{children:`版本`},`versions`),(0,c.jsx)(s.TabItem,{children:`進階`},`advanced`)]}),P===`design`?Ft():null,P===`preview`?en():null,P===`versions`?tn():null,P===`advanced`?nn():null]})})})]})]}),(0,c.jsx)(a.t,{confirmText:`儲存`,initialName:g?.definition.name??``,loading:ut,onClose:()=>R(!1),onSubmit:wt,open:at,title:`修改表單名稱`})]});function Ft(){return(0,c.jsxs)(`div`,{style:y,children:[(0,c.jsxs)(`div`,{style:se,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`label-primary`,children:`新增欄位`}),(0,c.jsx)(`div`,{style:ae,children:te.map(e=>(0,c.jsx)(s.Button,{disabled:z,icon:e.icon,iconType:`leading`,onClick:()=>G(e.type),size:`sub`,style:oe,type:`button`,variant:`base-secondary`,children:e.label},e.type))})]}),(0,c.jsxs)(`div`,{style:ne,children:[(0,c.jsxs)(`div`,{style:{...y,...re},children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`label-primary`,children:`表單畫布`}),T.fields.length>0?(0,c.jsx)(f.DragDropContext,{onDragEnd:Dt,children:(0,c.jsx)(f.Droppable,{droppableId:`form-builder-fields`,children:e=>(0,c.jsxs)(`div`,{...e.droppableProps,ref:e.innerRef,style:y,children:[T.fields.map((e,t)=>(0,c.jsx)(f.Draggable,{draggableId:e.fieldKey,index:t,isDragDisabled:z,children:(t,n)=>Qt(e,t,n.isDragging)},e.fieldKey)),e.placeholder]})})}):(0,c.jsxs)(`div`,{style:me,children:[(0,c.jsxs)(`div`,{style:y,children:[(0,c.jsx)(s.Typography,{component:`h3`,variant:`h3`,children:`尚未建立欄位`}),(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`從上方新增第一個欄位,或直接建立常用文字欄位開始設計。`})]}),(0,c.jsxs)(`div`,{style:he,children:[(0,c.jsx)(s.Button,{disabled:z,onClick:()=>G(`text`),variant:`base-primary`,children:`新增文字欄位`}),(0,c.jsx)(s.Button,{disabled:z,onClick:()=>G(`textarea`),variant:`base-secondary`,children:`新增長文字`})]})]})]}),(0,c.jsxs)(`div`,{style:{...y,...ie},children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`label-primary`,children:`欄位設定`}),V?It(V):(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`body`,children:`請先新增或選取欄位。`})]})]})]})}function It(e){return(0,c.jsxs)(`div`,{style:ge,children:[Lt(e),Rt(e)]})}function Lt(e){return(0,c.jsxs)(`div`,{style:_e,children:[(0,c.jsx)(`div`,{style:ye,children:(0,c.jsx)(s.Badge,{size:`main`,text:Be(e.type),variant:`text-info`})}),$(`標題`,`fieldLabel`,(0,c.jsx)(s.Input,{onChange:e=>K({label:e.target.value}),placeholder:`例如:申請金額`,value:e.label,variant:`base`}),z),$(`欄位 Key`,`fieldKey`,(0,c.jsx)(s.Input,{onChange:e=>K({fieldKey:e.target.value}),placeholder:`例如:amount`,value:e.fieldKey,variant:`base`}),z),$(`提示文字`,`fieldPlaceholder`,(0,c.jsx)(s.Input,{onChange:e=>K({placeholder:e.target.value||void 0}),placeholder:`例如:請輸入申請金額`,value:e.placeholder??``,variant:`base`}),z),zt(e)]})}function Rt(e){return(0,c.jsx)(s.Accordion,{defaultExpanded:Ve(e),size:`sub`,title:`進階設定`,children:(0,c.jsxs)(`div`,{style:_e,children:[(0,c.jsx)(s.Typography,{component:`h3`,style:ve,variant:`label-primary`,children:`條件規則`}),(0,c.jsx)(s.Typography,{color:`text-neutral`,style:be,variant:`body`,children:`只有需要根據其他欄位改變顯示、必填或唯讀狀態時才需要設定。`}),Kt(e)]})})}function zt(e){return Ue(e)?Bt(e):(0,d.isNumberFieldDefinition)(e)?Vt(e):(0,d.isDateFieldDefinition)(e)?Ht(e):(0,d.isSelectFieldDefinition)(e)?Ut(e):e.type===`boolean`?Wt(e):Gt(e)}function Bt(e){return(0,c.jsxs)(c.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,e.type===`textarea`?Yt({disabled:z,name:`fieldDefaultValue`,onChange:e=>J({defaultValue:e||void 0}),placeholder:`輸入此欄位的預設文字`,rows:3,value:C(e.defaultValue)}):(0,c.jsx)(s.Input,{onChange:e=>J({defaultValue:e.target.value||void 0}),placeholder:`輸入此欄位的預設文字`,value:C(e.defaultValue),variant:`base`}),z),$(`最小長度`,`fieldMinLength`,Q(e.minLength,e=>J({minLength:e}),`例如:2`,{min:0}),z),$(`最大長度`,`fieldMaxLength`,Q(e.maxLength,e=>J({maxLength:e}),`例如:100`,{min:1}),z)]})}function Vt(e){return(0,c.jsxs)(c.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,Q(typeof e.defaultValue==`number`?e.defaultValue:void 0,e=>Y({defaultValue:e}),e.type===`money`?`例如:1000`:`輸入預設數值`,{max:e.maximum,min:e.minimum}),z),$(`最小值`,`fieldMinimum`,Q(e.minimum,e=>Y({minimum:e}),`例如:0`),z),$(`最大值`,`fieldMaximum`,Q(e.maximum,e=>Y({maximum:e}),`例如:999999`),z)]})}function Ht(e){return $(`預設值`,`fieldDefaultValue`,Xt(e,C(e.defaultValue),e=>Ot({defaultValue:e})),z)}function Ut(e){let t=Array.isArray(e.defaultValue)?e.defaultValue:[],n=e.options.filter(e=>t.includes(e.value)).map(d.readFieldOptionAsSelectOption);return(0,c.jsxs)(c.Fragment,{children:[$(`預設值`,`fieldDefaultValue`,e.type===`checkbox`?(0,c.jsx)(s.Select,{clearable:!0,mode:`multiple`,onChange:e=>X({defaultValue:e.length?e.map(e=>e.id):void 0}),options:e.options.map(d.readFieldOptionAsSelectOption),placeholder:`選擇一或多個預設選項`,value:n}):(0,c.jsx)(s.Select,{clearable:!0,onChange:e=>X({defaultValue:e?.id||void 0}),options:e.options.map(d.readFieldOptionAsSelectOption),placeholder:`選擇預設選項`,value:typeof e.defaultValue==`string`?(0,d.readSelectOption)(e.options.map(d.readFieldOptionAsSelectOption),e.defaultValue):null}),z),$(`選項`,`fieldOptions`,Zt(e),z,!0)]})}function Wt(e){let t=typeof e.defaultValue==`boolean`?String(e.defaultValue):`unset`;return $(`預設值`,`fieldDefaultValue`,(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>kt({defaultValue:e?.id===`true`?!0:e?.id===`false`?!1:void 0}),options:[...Le],placeholder:`選擇預設狀態`,value:(0,d.readSelectOption)(Le,t)}),z)}function Gt(e){return(0,c.jsxs)(c.Fragment,{children:[$(`檔案數`,`fieldMaxFiles`,Q(e.maxFiles,e=>At({maxFiles:e}),`例如:1`,{min:1}),z),$(`MIME`,`fieldAcceptedMimeTypes`,Yt({disabled:z,name:`fieldAcceptedMimeTypes`,onChange:e=>At({acceptedMimeTypes:We(e)}),placeholder:`每行一個 MIME type,例如:application/pdf`,rows:3,value:Ge(e.acceptedMimeTypes)}),!1)]})}function Kt(e){let t=T.fields.filter(t=>t.fieldKey!==e.fieldKey);return t.length?(0,c.jsx)(c.Fragment,{children:ze.map(n=>qt(e,n,t))}):(0,c.jsx)(s.Typography,{color:`text-neutral`,style:be,variant:`body`,children:`目前沒有其他欄位可作為條件來源。新增更多欄位後即可設定條件規則。`})}function qt(e,t,n){let r=e[t.target],i=r?(0,d.parseConditionRule)(r):null,a=n.find(e=>e.fieldKey===i?.fieldKey),o=a??n[0],l=n.map(He),u=(0,d.readConditionOperatorOptions)(o),f=i&&u.some(e=>e.id===i.operator)?i.operator:(0,d.readDefaultConditionOperator)(o),p=i?.value??(0,d.readDefaultConditionValue)(o),m=!!r,h=m&&(!i||!a);return $(t.label,t.name,(0,c.jsxs)(`div`,{style:ke,children:[(0,c.jsx)(s.Toggle,{checked:m,disabled:z,label:m?`已啟用`:`不啟用`,onChange:e=>Z(t.target,e.target.checked?(0,d.buildConditionExpression)(o,(0,d.readDefaultConditionOperator)(o),(0,d.readDefaultConditionValue)(o)):void 0),size:`sub`,supportingText:t.supportingText}),m?h?(0,c.jsx)(s.Typography,{color:`text-warning`,variant:`body`,children:`這個規則不是目前 UI 支援的格式。重新選擇條件後會取代既有規則。`}):(0,c.jsxs)(`div`,{style:Ae,children:[(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>{let r=n.find(t=>t.fieldKey===e?.id)??o;Z(t.target,(0,d.buildConditionExpression)(r,(0,d.readDefaultConditionOperator)(r),(0,d.readDefaultConditionValue)(r)))},options:l,placeholder:`選擇欄位`,value:(0,d.readSelectOption)(l,o.fieldKey)}),(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>Z(t.target,(0,d.buildConditionExpression)(o,(0,d.readConditionOperatorOption)(e?.id)??f,p)),options:[...u],placeholder:`判斷方式`,value:(0,d.readSelectOption)(u,f)}),Jt(o,p,e=>Z(t.target,(0,d.buildConditionExpression)(o,f,e)))]}):null]}),z,!0)}function Z(e,t){K({[e]:t})}function Jt(e,t,n){if(e.type===`boolean`)return(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>n(e?.id??`true`),options:[...Re],placeholder:`比較值`,value:(0,d.readSelectOption)(Re,t===`false`?`false`:`true`)});if((0,d.isSelectFieldDefinition)(e)){let r=e.options.map(d.readFieldOptionAsSelectOption);return(0,c.jsx)(s.Select,{clearable:!1,onChange:e=>n(e?.id??r[0]?.id??``),options:r,placeholder:`比較值`,value:(0,d.readSelectOption)(r,t)})}return(0,d.isNumberFieldDefinition)(e)?Q((0,d.parseOptionalNumberInput)(t),e=>n(String(e??0)),`比較值`):(0,d.isDateFieldDefinition)(e)?Xt(e,t,e=>n(e??``)):(0,c.jsx)(s.Input,{onChange:e=>n(e.target.value),placeholder:`比較值`,value:t,variant:`base`})}function Yt({disabled:e,name:t,onChange:n,placeholder:r,rows:i,value:a}){return(0,c.jsx)(s.Textarea,{"aria-label":t,disabled:e,onChange:e=>n(e.target.value),placeholder:r,ref:Ie,resize:`vertical`,rows:i,style:we,value:a})}function Q(e,t,n,r={}){return(0,c.jsx)(s.Input,{max:r.max,min:r.min,onChange:e=>t((0,d.clampOptionalNumber)((0,d.parseOptionalNumberInput)(e.target.value),r)),placeholder:n,showSpinner:!0,step:r.step??1,value:typeof e==`number`?String(e):``,variant:`measure`})}function Xt(e,t,n){return e.type===`datetime`?(0,c.jsx)(s.DateTimePicker,{formatDate:`YYYY-MM-DD`,formatTime:`HH:mm`,hideSecond:!0,onChange:e=>n((0,d.formatDateTimePickerValue)(e)),placeholderLeft:`選擇日期`,placeholderRight:`選擇時間`,value:(0,d.readDatePickerValue)(t)}):(0,c.jsx)(s.DatePicker,{format:`YYYY-MM-DD`,onChange:e=>n((0,d.formatDatePickerValue)(e)),placeholder:`選擇日期`,value:(0,d.readDatePickerValue)(t)})}function Zt(e){return(0,c.jsxs)(`div`,{style:Ne,children:[(0,c.jsx)(s.Table,{actions:{render:t=>[{disabled:()=>z||e.options.length<=1,icon:l.TrashIcon,iconType:`icon-only`,name:`移除選項`,onClick:()=>X({options:e.options.filter((e,n)=>n!==t.index)}),variant:`destructive-ghost`}],width:56},columns:[{key:`label`,render:t=>(0,c.jsx)(s.Input,{onChange:n=>X({options:Ke(e.options,t.index,{label:n.target.value})}),placeholder:`例如:主管`,size:`sub`,value:t.label,variant:`base`}),title:`Label`},{key:`value`,render:t=>(0,c.jsx)(s.Input,{onChange:n=>X({options:Ke(e.options,t.index,{value:n.target.value})}),placeholder:`例如:manager`,size:`sub`,value:t.value,variant:`base`}),title:`Value`}],dataSource:e.options.map((t,n)=>({index:n,key:`${e.fieldKey}-${n}`,label:t.label,value:t.value})),showHeader:!0,size:`sub`}),(0,c.jsx)(`div`,{style:Pe,children:(0,c.jsx)(s.Button,{disabled:z,icon:l.PlusIcon,iconType:`leading`,onClick:()=>X({options:[...e.options,qe(e.options)]}),variant:`base-secondary`,children:`新增選項`})})]})}function Qt(e,t,n){return(0,c.jsx)(`div`,{...t.draggableProps,"data-form-builder-field-key":e.fieldKey,ref:t.innerRef,style:{...fe,...n?pe:null,...t.draggableProps.style},children:(0,c.jsx)(s.BaseCard,{children:$t(e,t,n)})})}function $(e,t,n,i,a=!1){return(0,c.jsx)(`div`,{style:a?Se:xe,children:(0,c.jsx)(`div`,{style:Ce,children:(0,c.jsx)(r.t,{disabled:i,label:e,name:t,children:n})})})}function $t(e,t,n){return(0,c.jsxs)(`div`,{...t.dragHandleProps??{},"aria-label":`拖曳排序欄位`,style:ce,title:`拖曳排序`,children:[(0,c.jsx)(`span`,{"aria-label":`拖曳排序`,role:`img`,style:je,title:`拖曳排序`,children:(0,c.jsx)(s.Icon,{icon:l.DotDragVerticalIcon,size:20})}),(0,c.jsxs)(`div`,{style:le,children:[(0,c.jsxs)(s.Typography,{component:`span`,ellipsis:!0,variant:`label-primary`,children:[e.label,e.required?(0,c.jsx)(`sup`,{"aria-label":`必填`,style:Fe,children:`*`}):null]}),(0,c.jsxs)(s.Typography,{color:`text-neutral`,component:`span`,ellipsis:!0,variant:`caption`,children:[Be(e.type),` ·`,e.required?` 必填`:` 選填`,` ·`,e.fieldKey]})]}),(0,c.jsxs)(`div`,{style:ue,children:[(0,c.jsx)(`div`,{style:de,children:(0,c.jsx)(s.Toggle,{checked:!!e.required,disabled:z||n,label:`必填`,onChange:t=>Mt(e.fieldKey,t.target.checked)})}),(0,c.jsx)(s.Button,{disabled:n,icon:l.EditIcon,iconType:`icon-only`,onClick:()=>I(e.fieldKey),variant:e.fieldKey===V?.fieldKey?`base-primary`:`base-ghost`,children:`編輯欄位`}),(0,c.jsx)(s.Button,{disabled:z||n,icon:l.TrashIcon,iconType:`icon-only`,onClick:()=>Et(e.fieldKey),variant:`destructive-ghost`,children:`移除欄位`})]})]})}function en(){return(0,c.jsxs)(`div`,{style:y,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`填寫預覽`}),(0,c.jsx)(i.t,{onChange:jt,schema:T,uiSchema:k,value:et})]})}function tn(){return(0,c.jsxs)(`div`,{style:y,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`版本紀錄`}),(0,c.jsx)(s.Table,{columns:pt,dataSource:ft,loading:ct})]})}function nn(){return(0,c.jsxs)(`div`,{style:y,children:[(0,c.jsx)(s.Typography,{component:`h2`,variant:`h3`,children:`Schema`}),(0,c.jsxs)(`div`,{style:Te,children:[rn(`Form Schema`,`schemaJson`,(0,c.jsx)(ee,{disabled:z,height:`360px`,name:`schemaJson`,onChange:Nt,placeholder:`輸入 Form Schema JSON`,value:Qe})),rn(`UI Schema`,`uiSchemaJson`,(0,c.jsx)(ee,{disabled:z,height:`240px`,name:`uiSchemaJson`,onChange:Pt,placeholder:`輸入 UI Schema JSON`,value:$e})),nt?(0,c.jsx)(s.Typography,{color:`text-error`,style:Oe,variant:`body`,children:nt}):null]})]})}function rn(e,t,n){return(0,c.jsx)(`div`,{style:Ee,children:(0,c.jsx)(`div`,{style:De,children:(0,c.jsx)(r.t,{disabled:z,label:e,name:t,children:n})})})}}function Be(e){return te.find(t=>t.type===e)?.label??e}function Ve(e){return!!(e.visibleWhen||e.requiredWhen||e.readonlyWhen)}function He(e){return{id:e.fieldKey,name:e.label}}function Ue(e){return e.type===`text`||e.type===`textarea`}function C(e){return typeof e==`string`?e:``}function We(e){let t=e.split(/[\n,]/u).map(e=>e.trim()).filter(Boolean);return t.length?t:void 0}function Ge(e){return e?.join(`
|
|
2
|
+
`)??``}function w(e){return JSON.stringify(e,null,2)}function Ke(e,t,n){return e.map((e,r)=>r===t?{...e,...n}:e)}function qe(e){let t=e.length+1;return{label:`選項 ${t}`,value:T(e,t)}}function T(e,t){let n=`option_${t}`;return e.some(e=>e.value===n)?T(e,t+1):n}function E(e,t){return{schemaJson:w(e),uiSchemaJson:w(t)}}function Je(e,t){return(t?e.find(e=>e.id===t):null)??e.find(e=>e.status===`PUBLISHED`)??null}function Ye({hasUnsavedChanges:e,latestPublishedVersion:t,openedContentPublished:r,openedVersion:i}){return`${e?`有未儲存修改`:`沒有未儲存修改`} · ${D({hasUnsavedChanges:e,openedContentPublished:r,openedVersion:i})} · ${t?`目前發布 v${t.version}:${n.t(t.publishedAt)}`:`目前沒有已發布版本`}`}function D({hasUnsavedChanges:e,openedContentPublished:t,openedVersion:n}){return e?n?`修改尚未發布,來源 v${n.version}`:`修改尚未發布`:t&&n?`當前內容已發布 v${n.version}`:n?`當前內容尚未發布 v${n.version}`:`當前內容尚未發布`}function Xe(e,t,n){let r=e[t];if(!r||t===n)return[...e];let i=e.filter((e,n)=>n!==t);return[...i.slice(0,n),r,...i.slice(n)]}function Ze({status:e}){return e===`PUBLISHED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已發布`,variant:`dot-success`}):e===`ARCHIVED`?(0,c.jsx)(s.Badge,{size:`sub`,text:`已封存`,variant:`dot-inactive`}):(0,c.jsx)(s.Badge,{size:`sub`,text:`草稿`,variant:`dot-warning`})}function O(e){return e instanceof Error?e.message:`發生未知錯誤`}Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return S}});
|
|
3
|
+
//# sourceMappingURL=FormBuilderView-BKtyW55e.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormBuilderView-BKtyW55e.cjs","names":[],"sources":["../../src/views/forms/builder/json-code-editor.tsx","../../src/views/forms/builder/FormBuilderView.tsx"],"sourcesContent":["'use client';\n\nimport { CSSProperties, ReactElement } from 'react';\nimport dynamic from 'next/dynamic';\nimport { json } from '@codemirror/lang-json';\nimport { EditorView } from '@codemirror/view';\nimport type { Extension, ReactCodeMirrorProps } from '@uiw/react-codemirror';\n\nconst EDITOR_FALLBACK_STYLE: CSSProperties = {\n alignItems: 'center',\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: 4,\n color: 'var(--mzn-color-text-neutral)',\n display: 'flex',\n minHeight: 160,\n padding: 12,\n width: '100%',\n};\n\nconst JSON_EDITOR_EXTENSIONS: readonly Extension[] = [\n json(),\n EditorView.lineWrapping,\n EditorView.theme({\n '&': {\n border: '1px solid var(--mzn-color-border-neutral)',\n borderRadius: '4px',\n fontSize: '13px',\n width: '100%',\n },\n '&.cm-focused': {\n outline: '1px solid var(--mzn-color-border-primary)',\n },\n '.cm-content': {\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace',\n minHeight: '100%',\n },\n '.cm-editor': {\n width: '100%',\n },\n '.cm-gutters': {\n borderRight: '1px solid var(--mzn-color-border-neutral)',\n },\n '.cm-scroller': {\n fontFamily:\n 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", monospace',\n },\n }),\n];\n\nconst CodeMirror = dynamic<ReactCodeMirrorProps>(\n () => import('@uiw/react-codemirror'),\n {\n loading: (): ReactElement => (\n <div style={EDITOR_FALLBACK_STYLE}>載入 JSON 編輯器</div>\n ),\n ssr: false,\n },\n);\n\ninterface JsonCodeEditorProps {\n readonly disabled: boolean;\n readonly height: string;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly value: string;\n}\n\nexport function JsonCodeEditor({\n disabled,\n height,\n name,\n onChange,\n placeholder,\n value,\n}: JsonCodeEditorProps): ReactElement {\n return (\n <CodeMirror\n aria-label={name}\n basicSetup={{\n autocompletion: true,\n bracketMatching: true,\n closeBrackets: true,\n defaultKeymap: true,\n foldGutter: true,\n highlightActiveLine: true,\n highlightSelectionMatches: true,\n lineNumbers: true,\n syntaxHighlighting: true,\n }}\n editable={!disabled}\n extensions={[...JSON_EDITOR_EXTENSIONS]}\n height={height}\n indentWithTab={false}\n onChange={onChange}\n placeholder={placeholder}\n readOnly={disabled}\n theme=\"light\"\n value={value}\n width=\"100%\"\n />\n );\n}\n","'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n Key,\n ReactElement,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n DragDropContext,\n Draggable,\n DraggableProvided,\n Droppable,\n DropResult,\n} from '@hello-pangea/dnd';\nimport {\n Accordion,\n BaseCard,\n Badge,\n Button,\n DatePicker,\n DateTimePicker,\n Icon,\n Input,\n Layout,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Tab,\n TabItem,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport {\n AlignLeftIcon,\n CalendarIcon,\n CheckedOutlineIcon,\n CheckedIcon,\n CurrencyDollarIcon,\n DotDragVerticalIcon,\n DotGridIcon,\n EditIcon,\n FileAttachmentIcon,\n FileIcon,\n ListIcon,\n PlusIcon,\n SaveIcon,\n TrashIcon,\n} from '@mezzanine-ui/icons';\nimport type { IconDefinition } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n BooleanFieldDefinition,\n DateFieldDefinition,\n FileUploadFieldDefinition,\n FormDefinitionSchema,\n FormFieldDefinition,\n FormFieldOption,\n FormUiSchema,\n NumberFieldDefinition,\n SelectFieldDefinition,\n TextFieldDefinition,\n} from '@rytass/bpm-core-shared/form';\nimport { formatDateTime } from '../../../lib/format-date-time';\nimport { AppNavigation } from '../../../components/app-navigation';\nimport {\n createFieldDefinition,\n FormBuilderRecord,\n FormDefinitionVersionRecord,\n forkFormDefinition,\n publishFormDefinitionVersion,\n readFormBuilder,\n updateFormDefinition,\n updateFormDefinitionDraft,\n} from '@rytass/bpm-core-client/form';\nimport {\n buildConditionExpression,\n buildFormRendererValues,\n clampOptionalNumber,\n formatDatePickerValue,\n formatDateTimePickerValue,\n FormRendererValues,\n isDateFieldDefinition,\n isNumberFieldDefinition,\n isSelectFieldDefinition,\n parseConditionRule,\n parseOptionalNumberInput,\n readConditionOperatorOption,\n readConditionOperatorOptions,\n readDatePickerValue,\n readDefaultConditionOperator,\n readDefaultConditionValue,\n readFieldOptionAsSelectOption,\n readSelectOption,\n} from '@rytass/bpm-core-client/form';\nimport { useRouterAdapter } from '../../../lib/router-adapter';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { FormRenderer } from '../renderer/FormRendererView';\nimport { FormNameModal } from '../form-name-modal';\nimport { JsonCodeEditor } from './json-code-editor';\n\ntype FieldType = FormFieldDefinition['type'];\ntype BuilderTabKey = 'design' | 'preview' | 'versions' | 'advanced';\ntype FieldOptionRow = Readonly<\n Record<string, unknown> & {\n index: number;\n key: string;\n label: string;\n value: string;\n }\n>;\n\ntype VersionRow = Readonly<\n Record<string, unknown> & {\n key: string;\n publishedAt: string;\n status: FormDefinitionVersionRecord['status'];\n updatedAt: string;\n version: string;\n }\n>;\n\ntype BuilderSnapshot = Readonly<{\n schemaJson: string;\n uiSchemaJson: string;\n}>;\n\ntype FieldTypeOption = Readonly<{\n description: string;\n icon: IconDefinition;\n label: string;\n type: FieldType;\n}>;\n\ntype ConditionRuleTarget = 'readonlyWhen' | 'requiredWhen' | 'visibleWhen';\n\ntype ConditionRuleConfig = Readonly<{\n label: string;\n name: string;\n supportingText: string;\n target: ConditionRuleTarget;\n}>;\n\nconst FIELD_TYPE_OPTIONS: readonly FieldTypeOption[] = [\n {\n description: '單行文字、姓名、編號',\n icon: AlignLeftIcon,\n label: '文字',\n type: 'text',\n },\n {\n description: '多行補充內容',\n icon: FileIcon,\n label: '長文字',\n type: 'textarea',\n },\n {\n description: '金額、數量、分數',\n icon: CurrencyDollarIcon,\n label: '數字',\n type: 'number',\n },\n {\n description: '金額與費用',\n icon: CurrencyDollarIcon,\n label: '金額',\n type: 'money',\n },\n {\n description: '日期或到期日',\n icon: CalendarIcon,\n label: '日期',\n type: 'date',\n },\n {\n description: '日期與時間',\n icon: CalendarIcon,\n label: '日期時間',\n type: 'datetime',\n },\n {\n description: '是 / 否狀態',\n icon: CheckedIcon,\n label: '開關',\n type: 'boolean',\n },\n {\n description: '固定選項擇一',\n icon: ListIcon,\n label: '下拉選單',\n type: 'select',\n },\n {\n description: '固定選項單選',\n icon: DotGridIcon,\n label: '單選',\n type: 'radio',\n },\n {\n description: '固定選項複選',\n icon: CheckedOutlineIcon,\n label: '複選',\n type: 'checkbox',\n },\n {\n description: '附件或佐證資料',\n icon: FileAttachmentIcon,\n label: '附件',\n type: 'file_upload',\n },\n];\n\nconst WORKSPACE_GRID_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'flex',\n flexWrap: 'wrap',\n gap: 16,\n};\n\nconst CANVAS_COLUMN_STYLE: CSSProperties = {\n flex: '0.55 1 300px',\n minWidth: 0,\n};\n\nconst SETTINGS_COLUMN_STYLE: CSSProperties = {\n flex: '1.45 1 720px',\n minWidth: 620,\n};\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 12,\n};\n\nconst FIELD_LIBRARY_STYLE: CSSProperties = {\n display: 'flex',\n flexWrap: 'wrap',\n gap: 6,\n};\n\nconst FIELD_LIBRARY_BUTTON_STYLE: CSSProperties = {\n flex: '0 0 auto',\n whiteSpace: 'nowrap',\n};\n\nconst FIELD_LIBRARY_HEADER_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n};\n\nconst FIELD_BLOCK_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n cursor: 'grab',\n display: 'flex',\n gap: 12,\n touchAction: 'none',\n};\n\nconst FIELD_BLOCK_TEXT_STYLE: CSSProperties = {\n display: 'grid',\n flex: '1 1 auto',\n gap: 2,\n minWidth: 0,\n};\n\nconst FIELD_BLOCK_ACTIONS_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n flex: '0 0 auto',\n gap: 4,\n};\n\nconst FIELD_BLOCK_REQUIRED_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n gap: 6,\n};\n\nconst FIELD_BLOCK_STYLE: CSSProperties = {\n userSelect: 'none',\n};\n\nconst FIELD_BLOCK_DRAGGING_STYLE: CSSProperties = {\n filter: 'drop-shadow(0 8px 18px rgba(0, 0, 0, 0.12))',\n};\n\nconst EMPTY_CANVAS_STYLE: CSSProperties = {\n alignItems: 'center',\n border: '1px dashed var(--mzn-color-border-neutral)',\n borderRadius: 6,\n display: 'grid',\n gap: 12,\n minHeight: 240,\n padding: 32,\n textAlign: 'center',\n};\n\nconst EMPTY_CANVAS_ACTIONS_STYLE: CSSProperties = {\n display: 'flex',\n gap: 8,\n justifyContent: 'center',\n};\n\nconst FIELD_SETTINGS_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 14,\n};\n\nconst FIELD_SETTINGS_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n columnGap: 16,\n gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',\n rowGap: 8,\n};\n\nconst FIELD_SETTINGS_SECTION_TITLE_STYLE: CSSProperties = {\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_BADGE_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'flex',\n gap: 8,\n gridColumn: '1 / -1',\n justifyContent: 'flex-end',\n};\n\nconst FIELD_SETTINGS_HINT_STYLE: CSSProperties = {\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_ROW_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'block',\n width: '100%',\n};\n\nconst FIELD_SETTINGS_ROW_WIDE_STYLE: CSSProperties = {\n ...FIELD_SETTINGS_ROW_STYLE,\n gridColumn: '1 / -1',\n};\n\nconst FIELD_SETTINGS_VALUE_STYLE: CSSProperties = {\n minWidth: 0,\n width: '100%',\n};\n\nconst FIELD_SETTINGS_TEXTAREA_STYLE: CSSProperties = {\n minWidth: '100%',\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_FORM_STYLE: CSSProperties = {\n display: 'grid',\n gap: 14,\n};\n\nconst ADVANCED_SCHEMA_ROW_STYLE: CSSProperties = {\n alignItems: 'start',\n display: 'block',\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_VALUE_STYLE: CSSProperties = {\n minWidth: 0,\n width: '100%',\n};\n\nconst ADVANCED_SCHEMA_MESSAGE_STYLE: CSSProperties = {\n gridColumn: '2 / -1',\n};\n\nconst CONDITION_RULE_CONTROL_STYLE: CSSProperties = {\n display: 'grid',\n gap: 10,\n width: '100%',\n};\n\nconst CONDITION_RULE_GRID_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))',\n};\n\nconst DRAG_HANDLE_STYLE: CSSProperties = {\n display: 'inline-flex',\n};\n\nconst WORKBENCH_STYLE: CSSProperties = {\n display: 'grid',\n gap: 16,\n};\n\nconst COMPACT_STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 8,\n};\n\nconst OPTION_ACTIONS_STYLE: CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-end',\n};\n\nconst REQUIRED_ASTERISK_STYLE: CSSProperties = {\n color: 'var(--mzn-color-text-error)',\n fontSize: '0.72em',\n lineHeight: 0,\n marginLeft: 2,\n verticalAlign: 'super',\n};\n\nfunction applyFullWidthTextareaHost(element: HTMLDivElement | null): void {\n if (!element) {\n return;\n }\n\n element.style.width = '100%';\n}\n\nconst EMPTY_SCHEMA: FormDefinitionSchema = {\n fields: [],\n schemaVersion: 1,\n};\n\nconst EMPTY_UI_SCHEMA: FormUiSchema = {\n layout: [],\n schemaVersion: 1,\n};\n\nconst BOOLEAN_DEFAULT_OPTIONS: readonly {\n readonly id: string;\n readonly name: string;\n}[] = [\n { id: 'unset', name: '不預設' },\n { id: 'true', name: '是' },\n { id: 'false', name: '否' },\n];\n\nconst BOOLEAN_CONDITION_VALUE_OPTIONS: readonly {\n readonly id: string;\n readonly name: string;\n}[] = [\n { id: 'true', name: '是' },\n { id: 'false', name: '否' },\n];\n\nconst CONDITION_RULE_CONFIGS: readonly ConditionRuleConfig[] = [\n {\n label: '顯示',\n name: 'fieldVisibleWhen',\n supportingText: '符合條件時才顯示這個欄位。',\n target: 'visibleWhen',\n },\n {\n label: '必填',\n name: 'fieldRequiredWhen',\n supportingText: '符合條件時才要求填寫這個欄位。',\n target: 'requiredWhen',\n },\n {\n label: '唯讀',\n name: 'fieldReadonlyWhen',\n supportingText: '符合條件時不允許修改這個欄位。',\n target: 'readonlyWhen',\n },\n];\n\nexport interface FormBuilderViewProps {\n /**\n * The id of the form definition being edited. Routed via the host's\n * dynamic segment (e.g. `[id]` in Next.js).\n */\n readonly formId: string;\n}\n\nexport function FormBuilderView({ formId }: FormBuilderViewProps): ReactElement {\n const router = useRouterAdapter();\n const formDefinitionId = formId;\n const [record, setRecord] = useState<FormBuilderRecord | null>(null);\n const [draft, setDraft] = useState<FormDefinitionVersionRecord | null>(null);\n const [schema, setSchema] = useState<FormDefinitionSchema>(EMPTY_SCHEMA);\n const [uiSchema, setUiSchema] = useState<FormUiSchema>(EMPTY_UI_SCHEMA);\n const [schemaJsonText, setSchemaJsonText] = useState(\n stringifyJson(EMPTY_SCHEMA),\n );\n const [uiSchemaJsonText, setUiSchemaJsonText] = useState(\n stringifyJson(EMPTY_UI_SCHEMA),\n );\n const [previewValues, setPreviewValues] = useState<FormRendererValues>({});\n const [advancedSchemaMessage, setAdvancedSchemaMessage] = useState<\n string | null\n >(null);\n const [activeTab, setActiveTab] = useState<BuilderTabKey>('design');\n const [selectedFieldKey, setSelectedFieldKey] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [renameModalOpen, setRenameModalOpen] = useState(false);\n const [loadedSnapshot, setLoadedSnapshot] = useState<BuilderSnapshot>(\n readBuilderSnapshot(EMPTY_SCHEMA, EMPTY_UI_SCHEMA),\n );\n const [loading, setLoading] = useState(true);\n const [renaming, setRenaming] = useState(false);\n const [saving, setSaving] = useState(false);\n\n useEffect((): void => {\n void refreshBuilder();\n }, [formDefinitionId]);\n\n useEffect((): void => {\n const hasSelectedField = schema.fields.some(\n (field) => field.fieldKey === selectedFieldKey,\n );\n\n if (hasSelectedField) {\n return;\n }\n\n setSelectedFieldKey(schema.fields[0]?.fieldKey ?? null);\n }, [schema.fields, selectedFieldKey]);\n\n useEffect((): void => {\n setPreviewValues((currentValues) =>\n buildFormRendererValues(schema.fields, currentValues),\n );\n }, [schema.fields]);\n\n useEffect((): void => {\n if (activeTab === 'advanced') {\n return;\n }\n\n setSchemaJsonText(stringifyJson(schema));\n setUiSchemaJsonText(stringifyJson(uiSchema));\n }, [activeTab, schema, uiSchema]);\n\n const selectedField = useMemo(\n (): FormFieldDefinition | null =>\n schema.fields.find((field) => field.fieldKey === selectedFieldKey) ??\n schema.fields[0] ??\n null,\n [schema.fields, selectedFieldKey],\n );\n const versionRows = useMemo(\n (): VersionRow[] =>\n (record?.versions ?? []).map((version) => ({\n key: version.id,\n publishedAt: formatDateTime(version.publishedAt),\n status: version.status,\n updatedAt: formatDateTime(version.updatedAt),\n version: `v${version.version}`,\n })),\n [record],\n );\n const versionColumns = useMemo(\n (): TableColumn<VersionRow>[] => [\n { dataIndex: 'version', key: 'version', title: '版本', width: 120 },\n {\n key: 'status',\n render: (record: VersionRow): ReactElement => (\n <FormVersionStatusBadge status={record.status} />\n ),\n title: '狀態',\n width: 140,\n },\n {\n dataIndex: 'updatedAt',\n key: 'updatedAt',\n title: '最後更新',\n width: 180,\n },\n {\n dataIndex: 'publishedAt',\n key: 'publishedAt',\n title: '發布時間',\n width: 180,\n },\n ],\n [],\n );\n const currentSnapshot = useMemo(\n (): BuilderSnapshot => readBuilderSnapshot(schema, uiSchema),\n [schema, uiSchema],\n );\n const hasUnsavedChanges =\n currentSnapshot.schemaJson !== loadedSnapshot.schemaJson ||\n currentSnapshot.uiSchemaJson !== loadedSnapshot.uiSchemaJson;\n\n useEffect((): (() => void) => {\n function handleBeforeUnload(event: BeforeUnloadEvent): void {\n if (!hasUnsavedChanges) {\n return;\n }\n\n event.preventDefault();\n event.returnValue = '';\n }\n\n window.addEventListener('beforeunload', handleBeforeUnload);\n\n return (): void => {\n window.removeEventListener('beforeunload', handleBeforeUnload);\n };\n }, [hasUnsavedChanges]);\n\n function handleBackToForms(): void {\n if (\n hasUnsavedChanges &&\n !window.confirm('目前有尚未儲存的表單草稿,確定要離開嗎?')\n ) {\n return;\n }\n\n router.push('/forms');\n }\n const latestPublishedVersion = useMemo(\n (): FormDefinitionVersionRecord | null =>\n readPublishedVersion(\n record?.versions ?? [],\n record?.definition.currentVersionId,\n ),\n [record?.definition.currentVersionId, record?.versions],\n );\n const openedVersion =\n draft ?? latestPublishedVersion ?? record?.versions[0] ?? null;\n const openedContentPublished =\n !hasUnsavedChanges && openedVersion?.status === 'PUBLISHED';\n const headerDescription = readHeaderDescription({\n hasUnsavedChanges,\n latestPublishedVersion,\n openedContentPublished,\n openedVersion,\n });\n const publishDisabled =\n saving || (!hasUnsavedChanges && openedContentPublished && !draft);\n const publishButtonText = hasUnsavedChanges\n ? '保存並發布'\n : draft\n ? '發布草稿'\n : openedContentPublished\n ? '已發布'\n : '發布版本';\n\n async function refreshBuilder(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n const nextRecord = await readFormBuilder(formDefinitionId);\n const nextDraft =\n nextRecord.versions.find((version) => version.status === 'DRAFT') ??\n null;\n\n setRecord(nextRecord);\n setDraft(nextDraft);\n const nextSchema =\n nextDraft?.schema ?? nextRecord.versions[0]?.schema ?? EMPTY_SCHEMA;\n const nextUiSchema =\n nextDraft?.uiSchema ??\n nextRecord.versions[0]?.uiSchema ??\n EMPTY_UI_SCHEMA;\n\n setSchema(nextSchema);\n setUiSchema(nextUiSchema);\n setLoadedSnapshot(readBuilderSnapshot(nextSchema, nextUiSchema));\n setSchemaJsonText(stringifyJson(nextSchema));\n setUiSchemaJsonText(stringifyJson(nextUiSchema));\n setSelectedFieldKey(\n nextDraft?.schema.fields[0]?.fieldKey ??\n nextRecord.versions[0]?.schema.fields[0]?.fieldKey ??\n null,\n );\n setAdvancedSchemaMessage(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n async function saveCurrentDraft(): Promise<FormDefinitionVersionRecord> {\n const targetDraft = draft ?? (await forkFormDefinition(formDefinitionId));\n const nextDraft = await updateFormDefinitionDraft(\n targetDraft.id,\n schema,\n uiSchema,\n );\n\n setDraft(nextDraft);\n\n return nextDraft;\n }\n\n async function handleSaveDraft(): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n await saveCurrentDraft();\n await refreshBuilder();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n async function handlePublish(): Promise<void> {\n setSaving(true);\n setError(null);\n\n try {\n const savedDraft = await saveCurrentDraft();\n await publishFormDefinitionVersion(savedDraft.id);\n await refreshBuilder();\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setSaving(false);\n }\n }\n\n async function handleRenameForm(name: string): Promise<void> {\n if (!record) {\n throw new Error('尚未載入表單資料');\n }\n\n setRenaming(true);\n\n try {\n const updatedDefinition = await updateFormDefinition(\n record.definition.id,\n name,\n );\n\n setRecord({\n ...record,\n definition: updatedDefinition,\n });\n setRenameModalOpen(false);\n } finally {\n setRenaming(false);\n }\n }\n\n function handleAddField(type: FieldType): void {\n const nextIndex = schema.fields.length + 1;\n const field = createFieldDefinition(type, nextIndex);\n\n setSchema({\n ...schema,\n fields: [...schema.fields, field],\n });\n setUiSchema({\n ...uiSchema,\n layout: [\n ...uiSchema.layout,\n {\n fieldKey: field.fieldKey,\n width:\n type === 'textarea' || type === 'file_upload' ? 'FULL' : 'HALF',\n },\n ],\n });\n setSelectedFieldKey(field.fieldKey);\n setActiveTab('design');\n setAdvancedSchemaMessage(null);\n }\n\n function handleTabChange(activeKey: Key): void {\n const nextTab = activeKey as BuilderTabKey;\n\n if (nextTab === 'advanced' && activeTab !== 'advanced') {\n setSchemaJsonText(stringifyJson(schema));\n setUiSchemaJsonText(stringifyJson(uiSchema));\n }\n\n setActiveTab(nextTab);\n }\n\n function handleRemoveField(fieldKey: string): void {\n const remainingFields = schema.fields.filter(\n (field) => field.fieldKey !== fieldKey,\n );\n\n setSchema({\n ...schema,\n fields: remainingFields,\n });\n setUiSchema({\n ...uiSchema,\n layout: uiSchema.layout.filter((item) => item.fieldKey !== fieldKey),\n });\n setSelectedFieldKey(\n selectedFieldKey === fieldKey\n ? (remainingFields[0]?.fieldKey ?? null)\n : selectedFieldKey,\n );\n setAdvancedSchemaMessage(null);\n }\n\n function handleFieldDragEnd(result: DropResult): void {\n const destination = result.destination;\n\n if (!destination) {\n return;\n }\n\n if (result.source.index === destination.index) {\n return;\n }\n\n setSchema((currentSchema) => ({\n ...currentSchema,\n fields: moveItemByIndex(\n currentSchema.fields,\n result.source.index,\n destination.index,\n ),\n }));\n setUiSchema((currentUiSchema) => ({\n ...currentUiSchema,\n layout: moveItemByIndex(\n currentUiSchema.layout,\n result.source.index,\n destination.index,\n ),\n }));\n setAdvancedSchemaMessage(null);\n }\n\n function updateSelectedField(\n patch: Partial<\n Pick<\n FormFieldDefinition,\n | 'defaultValue'\n | 'fieldKey'\n | 'label'\n | 'placeholder'\n | 'readonlyWhen'\n | 'required'\n | 'requiredWhen'\n | 'visibleWhen'\n >\n >,\n ): void {\n updateSelectedFieldWith(\n (field) => ({ ...field, ...patch }) as FormFieldDefinition,\n );\n }\n\n function updateSelectedFieldWith(\n updater: (field: FormFieldDefinition) => FormFieldDefinition,\n ): void {\n if (!selectedField) {\n return;\n }\n\n const previousFieldKey = selectedField.fieldKey;\n const nextField = updater(selectedField);\n const nextFieldKey = nextField.fieldKey;\n\n setSchema({\n ...schema,\n fields: schema.fields.map(\n (field): FormFieldDefinition =>\n field.fieldKey === previousFieldKey ? nextField : field,\n ),\n });\n setUiSchema({\n ...uiSchema,\n layout: uiSchema.layout.map((item) =>\n item.fieldKey === previousFieldKey\n ? { ...item, fieldKey: nextFieldKey }\n : item,\n ),\n });\n setSelectedFieldKey(nextFieldKey);\n setAdvancedSchemaMessage(null);\n }\n\n function updateSelectedTextField(\n patch: Partial<\n Pick<TextFieldDefinition, 'defaultValue' | 'maxLength' | 'minLength'>\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n isTextFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedNumberField(\n patch: Partial<\n Pick<NumberFieldDefinition, 'defaultValue' | 'maximum' | 'minimum'>\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n isNumberFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedDateField(\n patch: Partial<Pick<DateFieldDefinition, 'defaultValue'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n isDateFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedSelectField(\n patch: Partial<Pick<SelectFieldDefinition, 'defaultValue' | 'options'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n isSelectFieldDefinition(field) ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedBooleanField(\n patch: Partial<Pick<BooleanFieldDefinition, 'defaultValue'>>,\n ): void {\n updateSelectedFieldWith((field) =>\n field.type === 'boolean' ? { ...field, ...patch } : field,\n );\n }\n\n function updateSelectedFileUploadField(\n patch: Partial<\n Pick<\n FileUploadFieldDefinition,\n 'acceptedMimeTypes' | 'defaultValue' | 'maxFiles'\n >\n >,\n ): void {\n updateSelectedFieldWith((field) =>\n field.type === 'file_upload' ? { ...field, ...patch } : field,\n );\n }\n\n function updatePreviewValues(values: FormRendererValues): void {\n setPreviewValues(values);\n }\n\n function updateFieldRequired(fieldKey: string, required: boolean): void {\n setSchema((currentSchema) => ({\n ...currentSchema,\n fields: currentSchema.fields.map(\n (field): FormFieldDefinition =>\n field.fieldKey === fieldKey\n ? ({ ...field, required } as FormFieldDefinition)\n : field,\n ),\n }));\n setAdvancedSchemaMessage(null);\n }\n\n function updateSchemaJson(value: string): void {\n setSchemaJsonText(value);\n\n try {\n setSchema(JSON.parse(value) as FormDefinitionSchema);\n setAdvancedSchemaMessage(null);\n } catch {\n setAdvancedSchemaMessage('Form Schema JSON 格式不正確');\n }\n }\n\n function updateUiSchemaJson(value: string): void {\n setUiSchemaJsonText(value);\n\n try {\n setUiSchema(JSON.parse(value) as FormUiSchema);\n setAdvancedSchemaMessage(null);\n } catch {\n setAdvancedSchemaMessage('UI Schema JSON 格式不正確');\n }\n }\n\n return (\n <>\n <Layout>\n <AppNavigation activeHref=\"/forms\" />\n\n <Layout.Main>\n <PageHeader>\n <ContentHeader\n description={headerDescription}\n onBackClick={handleBackToForms}\n title={record?.definition.name ?? '表單設計器'}\n >\n <Button\n aria-label=\"修改表單名稱\"\n disabled={renaming || !record}\n icon={EditIcon}\n iconType=\"icon-only\"\n onClick={(): void => setRenameModalOpen(true)}\n variant=\"base-ghost\"\n >\n 修改表單名稱\n </Button>\n <Button\n aria-label=\"儲存草稿\"\n disabled={saving || !hasUnsavedChanges}\n icon={SaveIcon}\n iconType=\"icon-only\"\n onClick={(): void => void handleSaveDraft()}\n variant=\"base-secondary\"\n >\n 儲存草稿\n </Button>\n <Button\n disabled={publishDisabled}\n icon={CheckedIcon}\n iconType=\"leading\"\n onClick={(): void => void handlePublish()}\n variant=\"base-primary\"\n >\n {publishButtonText}\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={WORKBENCH_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab\n activeKey={activeTab}\n onChange={handleTabChange}\n size=\"sub\"\n >\n <TabItem key=\"design\">設計</TabItem>\n <TabItem key=\"preview\">預覽</TabItem>\n <TabItem key=\"versions\">版本</TabItem>\n <TabItem key=\"advanced\">進階</TabItem>\n </Tab>\n\n {activeTab === 'design' ? renderDesignTab() : null}\n {activeTab === 'preview' ? renderPreviewTab() : null}\n {activeTab === 'versions' ? renderVersionsTab() : null}\n {activeTab === 'advanced' ? renderAdvancedTab() : null}\n </div>\n </Section>\n </SectionGroup>\n </Layout.Main>\n </Layout>\n\n <FormNameModal\n confirmText=\"儲存\"\n initialName={record?.definition.name ?? ''}\n loading={renaming}\n onClose={(): void => setRenameModalOpen(false)}\n onSubmit={handleRenameForm}\n open={renameModalOpen}\n title=\"修改表單名稱\"\n />\n </>\n );\n\n function renderDesignTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <div style={FIELD_LIBRARY_HEADER_STYLE}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 新增欄位\n </Typography>\n <div style={FIELD_LIBRARY_STYLE}>\n {FIELD_TYPE_OPTIONS.map((option) => (\n <Button\n disabled={saving}\n icon={option.icon}\n iconType=\"leading\"\n key={option.type}\n onClick={(): void => handleAddField(option.type)}\n size=\"sub\"\n style={FIELD_LIBRARY_BUTTON_STYLE}\n type=\"button\"\n variant=\"base-secondary\"\n >\n {option.label}\n </Button>\n ))}\n </div>\n </div>\n\n <div style={WORKSPACE_GRID_STYLE}>\n <div style={{ ...STACK_STYLE, ...CANVAS_COLUMN_STYLE }}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 表單畫布\n </Typography>\n {schema.fields.length > 0 ? (\n <DragDropContext onDragEnd={handleFieldDragEnd}>\n <Droppable droppableId=\"form-builder-fields\">\n {(droppableProvided): ReactElement => (\n <div\n {...droppableProvided.droppableProps}\n ref={droppableProvided.innerRef}\n style={STACK_STYLE}\n >\n {schema.fields.map((field, index) => (\n <Draggable\n draggableId={field.fieldKey}\n index={index}\n isDragDisabled={saving}\n key={field.fieldKey}\n >\n {(draggableProvided, snapshot): ReactElement =>\n renderFieldBlock(\n field,\n draggableProvided,\n snapshot.isDragging,\n )\n }\n </Draggable>\n ))}\n {droppableProvided.placeholder}\n </div>\n )}\n </Droppable>\n </DragDropContext>\n ) : (\n <div style={EMPTY_CANVAS_STYLE}>\n <div style={STACK_STYLE}>\n <Typography component=\"h3\" variant=\"h3\">\n 尚未建立欄位\n </Typography>\n <Typography color=\"text-neutral\" variant=\"body\">\n 從上方新增第一個欄位,或直接建立常用文字欄位開始設計。\n </Typography>\n </div>\n <div style={EMPTY_CANVAS_ACTIONS_STYLE}>\n <Button\n disabled={saving}\n onClick={(): void => handleAddField('text')}\n variant=\"base-primary\"\n >\n 新增文字欄位\n </Button>\n <Button\n disabled={saving}\n onClick={(): void => handleAddField('textarea')}\n variant=\"base-secondary\"\n >\n 新增長文字\n </Button>\n </div>\n </div>\n )}\n </div>\n\n <div style={{ ...STACK_STYLE, ...SETTINGS_COLUMN_STYLE }}>\n <Typography component=\"h2\" variant=\"label-primary\">\n 欄位設定\n </Typography>\n {selectedField ? (\n renderFieldSettings(selectedField)\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 請先新增或選取欄位。\n </Typography>\n )}\n </div>\n </div>\n </div>\n );\n }\n\n function renderFieldSettings(field: FormFieldDefinition): ReactElement {\n return (\n <div style={FIELD_SETTINGS_FORM_STYLE}>\n {renderMainFieldSettings(field)}\n {renderAdvancedFieldSettings(field)}\n </div>\n );\n }\n\n function renderMainFieldSettings(field: FormFieldDefinition): ReactElement {\n return (\n <div style={FIELD_SETTINGS_SECTION_STYLE}>\n <div style={FIELD_SETTINGS_BADGE_ROW_STYLE}>\n <Badge\n size=\"main\"\n text={readFieldTypeLabel(field.type)}\n variant=\"text-info\"\n />\n </div>\n {renderSettingsFormRow(\n '標題',\n 'fieldLabel',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({ label: event.target.value })\n }\n placeholder=\"例如:申請金額\"\n value={field.label}\n variant=\"base\"\n />,\n saving,\n )}\n {renderSettingsFormRow(\n '欄位 Key',\n 'fieldKey',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({ fieldKey: event.target.value })\n }\n placeholder=\"例如:amount\"\n value={field.fieldKey}\n variant=\"base\"\n />,\n saving,\n )}\n {renderSettingsFormRow(\n '提示文字',\n 'fieldPlaceholder',\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedField({\n placeholder: event.target.value || undefined,\n })\n }\n placeholder=\"例如:請輸入申請金額\"\n value={field.placeholder ?? ''}\n variant=\"base\"\n />,\n saving,\n )}\n {renderTypeSpecificSettings(field)}\n </div>\n );\n }\n\n function renderAdvancedFieldSettings(\n field: FormFieldDefinition,\n ): ReactElement {\n return (\n <Accordion\n defaultExpanded={hasConditionRules(field)}\n size=\"sub\"\n title=\"進階設定\"\n >\n <div style={FIELD_SETTINGS_SECTION_STYLE}>\n <Typography\n component=\"h3\"\n style={FIELD_SETTINGS_SECTION_TITLE_STYLE}\n variant=\"label-primary\"\n >\n 條件規則\n </Typography>\n <Typography\n color=\"text-neutral\"\n style={FIELD_SETTINGS_HINT_STYLE}\n variant=\"body\"\n >\n 只有需要根據其他欄位改變顯示、必填或唯讀狀態時才需要設定。\n </Typography>\n {renderConditionSettings(field)}\n </div>\n </Accordion>\n );\n }\n\n function renderTypeSpecificSettings(\n field: FormFieldDefinition,\n ): ReactElement {\n if (isTextFieldDefinition(field)) {\n return renderTextFieldSettings(field);\n }\n\n if (isNumberFieldDefinition(field)) {\n return renderNumberFieldSettings(field);\n }\n\n if (isDateFieldDefinition(field)) {\n return renderDateFieldSettings(field);\n }\n\n if (isSelectFieldDefinition(field)) {\n return renderSelectFieldSettings(field);\n }\n\n if (field.type === 'boolean') {\n return renderBooleanFieldSettings(field);\n }\n\n return renderFileUploadFieldSettings(field);\n }\n\n function renderTextFieldSettings(field: TextFieldDefinition): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n field.type === 'textarea' ? (\n renderSettingsTextarea({\n disabled: saving,\n name: 'fieldDefaultValue',\n onChange: (value): void =>\n updateSelectedTextField({ defaultValue: value || undefined }),\n placeholder: '輸入此欄位的預設文字',\n rows: 3,\n value: readStringDefaultValue(field.defaultValue),\n })\n ) : (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedTextField({\n defaultValue: event.target.value || undefined,\n })\n }\n placeholder=\"輸入此欄位的預設文字\"\n value={readStringDefaultValue(field.defaultValue)}\n variant=\"base\"\n />\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最小長度',\n 'fieldMinLength',\n renderNumberInput(\n field.minLength,\n (value): void => updateSelectedTextField({ minLength: value }),\n '例如:2',\n { min: 0 },\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最大長度',\n 'fieldMaxLength',\n renderNumberInput(\n field.maxLength,\n (value): void => updateSelectedTextField({ maxLength: value }),\n '例如:100',\n { min: 1 },\n ),\n saving,\n )}\n </>\n );\n }\n\n function renderNumberFieldSettings(\n field: NumberFieldDefinition,\n ): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n renderNumberInput(\n typeof field.defaultValue === 'number'\n ? field.defaultValue\n : undefined,\n (value): void => updateSelectedNumberField({ defaultValue: value }),\n field.type === 'money' ? '例如:1000' : '輸入預設數值',\n { max: field.maximum, min: field.minimum },\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最小值',\n 'fieldMinimum',\n renderNumberInput(\n field.minimum,\n (value): void => updateSelectedNumberField({ minimum: value }),\n '例如:0',\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '最大值',\n 'fieldMaximum',\n renderNumberInput(\n field.maximum,\n (value): void => updateSelectedNumberField({ maximum: value }),\n '例如:999999',\n ),\n saving,\n )}\n </>\n );\n }\n\n function renderDateFieldSettings(field: DateFieldDefinition): ReactElement {\n return renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n renderDateValuePicker(\n field,\n readStringDefaultValue(field.defaultValue),\n (value): void => updateSelectedDateField({ defaultValue: value }),\n ),\n saving,\n );\n }\n\n function renderSelectFieldSettings(\n field: SelectFieldDefinition,\n ): ReactElement {\n const defaultValues = Array.isArray(field.defaultValue)\n ? field.defaultValue\n : [];\n const selectedValues = field.options\n .filter((option) => defaultValues.includes(option.value))\n .map(readFieldOptionAsSelectOption);\n\n return (\n <>\n {renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n field.type === 'checkbox' ? (\n <Select\n clearable\n mode=\"multiple\"\n onChange={(options): void =>\n updateSelectedSelectField({\n defaultValue: options.length\n ? options.map((option) => option.id)\n : undefined,\n })\n }\n options={field.options.map(readFieldOptionAsSelectOption)}\n placeholder=\"選擇一或多個預設選項\"\n value={selectedValues}\n />\n ) : (\n <Select\n clearable\n onChange={(option): void =>\n updateSelectedSelectField({\n defaultValue: option?.id || undefined,\n })\n }\n options={field.options.map(readFieldOptionAsSelectOption)}\n placeholder=\"選擇預設選項\"\n value={\n typeof field.defaultValue === 'string'\n ? readSelectOption(\n field.options.map(readFieldOptionAsSelectOption),\n field.defaultValue,\n )\n : null\n }\n />\n ),\n saving,\n )}\n {renderSettingsFormRow(\n '選項',\n 'fieldOptions',\n renderFieldOptionsTable(field),\n saving,\n true,\n )}\n </>\n );\n }\n\n function renderBooleanFieldSettings(\n field: BooleanFieldDefinition,\n ): ReactElement {\n const defaultValue =\n typeof field.defaultValue === 'boolean'\n ? String(field.defaultValue)\n : 'unset';\n\n return renderSettingsFormRow(\n '預設值',\n 'fieldDefaultValue',\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedBooleanField({\n defaultValue:\n option?.id === 'true'\n ? true\n : option?.id === 'false'\n ? false\n : undefined,\n })\n }\n options={[...BOOLEAN_DEFAULT_OPTIONS]}\n placeholder=\"選擇預設狀態\"\n value={readSelectOption(BOOLEAN_DEFAULT_OPTIONS, defaultValue)}\n />,\n saving,\n );\n }\n\n function renderFileUploadFieldSettings(\n field: FileUploadFieldDefinition,\n ): ReactElement {\n return (\n <>\n {renderSettingsFormRow(\n '檔案數',\n 'fieldMaxFiles',\n renderNumberInput(\n field.maxFiles,\n (value): void => updateSelectedFileUploadField({ maxFiles: value }),\n '例如:1',\n { min: 1 },\n ),\n saving,\n )}\n {renderSettingsFormRow(\n 'MIME',\n 'fieldAcceptedMimeTypes',\n renderSettingsTextarea({\n disabled: saving,\n name: 'fieldAcceptedMimeTypes',\n onChange: (value): void =>\n updateSelectedFileUploadField({\n acceptedMimeTypes: parseStringList(value),\n }),\n placeholder: '每行一個 MIME type,例如:application/pdf',\n rows: 3,\n value: readStringListInput(field.acceptedMimeTypes),\n }),\n false,\n )}\n </>\n );\n }\n\n function renderConditionSettings(field: FormFieldDefinition): ReactElement {\n const conditionFieldOptions = schema.fields.filter(\n (schemaField) => schemaField.fieldKey !== field.fieldKey,\n );\n\n if (!conditionFieldOptions.length) {\n return (\n <Typography\n color=\"text-neutral\"\n style={FIELD_SETTINGS_HINT_STYLE}\n variant=\"body\"\n >\n 目前沒有其他欄位可作為條件來源。新增更多欄位後即可設定條件規則。\n </Typography>\n );\n }\n\n return (\n <>\n {CONDITION_RULE_CONFIGS.map((config) =>\n renderConditionRule(field, config, conditionFieldOptions),\n )}\n </>\n );\n }\n\n function renderConditionRule(\n field: FormFieldDefinition,\n config: ConditionRuleConfig,\n conditionFieldOptions: readonly FormFieldDefinition[],\n ): ReactElement {\n const expression = field[config.target];\n const parsedRule = expression ? parseConditionRule(expression) : null;\n const parsedConditionField = conditionFieldOptions.find(\n (conditionField) => conditionField.fieldKey === parsedRule?.fieldKey,\n );\n const selectedConditionField =\n parsedConditionField ?? conditionFieldOptions[0];\n const conditionFieldSelectOptions = conditionFieldOptions.map(\n readFieldAsConditionSelectOption,\n );\n const conditionOperatorOptions = readConditionOperatorOptions(\n selectedConditionField,\n );\n const selectedOperator =\n parsedRule &&\n conditionOperatorOptions.some(\n (option) => option.id === parsedRule.operator,\n )\n ? parsedRule.operator\n : readDefaultConditionOperator(selectedConditionField);\n const selectedValue =\n parsedRule?.value ?? readDefaultConditionValue(selectedConditionField);\n const enabled = Boolean(expression);\n const unsupportedRule = enabled && (!parsedRule || !parsedConditionField);\n\n return renderSettingsFormRow(\n config.label,\n config.name,\n <div style={CONDITION_RULE_CONTROL_STYLE}>\n <Toggle\n checked={enabled}\n disabled={saving}\n label={enabled ? '已啟用' : '不啟用'}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedConditionRule(\n config.target,\n event.target.checked\n ? buildConditionExpression(\n selectedConditionField,\n readDefaultConditionOperator(selectedConditionField),\n readDefaultConditionValue(selectedConditionField),\n )\n : undefined,\n )\n }\n size=\"sub\"\n supportingText={config.supportingText}\n />\n {enabled ? (\n unsupportedRule ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 這個規則不是目前 UI 支援的格式。重新選擇條件後會取代既有規則。\n </Typography>\n ) : (\n <div style={CONDITION_RULE_GRID_STYLE}>\n <Select\n clearable={false}\n onChange={(option): void => {\n const nextField =\n conditionFieldOptions.find(\n (conditionField) =>\n conditionField.fieldKey === option?.id,\n ) ?? selectedConditionField;\n\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n nextField,\n readDefaultConditionOperator(nextField),\n readDefaultConditionValue(nextField),\n ),\n );\n }}\n options={conditionFieldSelectOptions}\n placeholder=\"選擇欄位\"\n value={readSelectOption(\n conditionFieldSelectOptions,\n selectedConditionField.fieldKey,\n )}\n />\n <Select\n clearable={false}\n onChange={(option): void =>\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n selectedConditionField,\n readConditionOperatorOption(option?.id) ??\n selectedOperator,\n selectedValue,\n ),\n )\n }\n options={[...conditionOperatorOptions]}\n placeholder=\"判斷方式\"\n value={readSelectOption(\n conditionOperatorOptions,\n selectedOperator,\n )}\n />\n {renderConditionValueControl(\n selectedConditionField,\n selectedValue,\n (nextValue): void =>\n updateSelectedConditionRule(\n config.target,\n buildConditionExpression(\n selectedConditionField,\n selectedOperator,\n nextValue,\n ),\n ),\n )}\n </div>\n )\n ) : null}\n </div>,\n saving,\n true,\n );\n }\n\n function updateSelectedConditionRule(\n target: ConditionRuleTarget,\n expression: string | undefined,\n ): void {\n updateSelectedField({ [target]: expression });\n }\n\n function renderConditionValueControl(\n conditionField: FormFieldDefinition,\n value: string,\n onChange: (value: string) => void,\n ): ReactElement {\n if (conditionField.type === 'boolean') {\n return (\n <Select\n clearable={false}\n onChange={(option): void => onChange(option?.id ?? 'true')}\n options={[...BOOLEAN_CONDITION_VALUE_OPTIONS]}\n placeholder=\"比較值\"\n value={readSelectOption(\n BOOLEAN_CONDITION_VALUE_OPTIONS,\n value === 'false' ? 'false' : 'true',\n )}\n />\n );\n }\n\n if (isSelectFieldDefinition(conditionField)) {\n const options = conditionField.options.map(readFieldOptionAsSelectOption);\n\n return (\n <Select\n clearable={false}\n onChange={(option): void =>\n onChange(option?.id ?? options[0]?.id ?? '')\n }\n options={options}\n placeholder=\"比較值\"\n value={readSelectOption(options, value)}\n />\n );\n }\n\n if (isNumberFieldDefinition(conditionField)) {\n return renderNumberInput(\n parseOptionalNumberInput(value),\n (nextValue): void => onChange(String(nextValue ?? 0)),\n '比較值',\n );\n }\n\n if (isDateFieldDefinition(conditionField)) {\n return renderDateValuePicker(conditionField, value, (nextValue): void =>\n onChange(nextValue ?? ''),\n );\n }\n\n return (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(event.target.value)\n }\n placeholder=\"比較值\"\n value={value}\n variant=\"base\"\n />\n );\n }\n\n function renderSettingsTextarea({\n disabled,\n name,\n onChange,\n placeholder,\n rows,\n value,\n }: {\n readonly disabled: boolean;\n readonly name: string;\n readonly onChange: (value: string) => void;\n readonly placeholder: string;\n readonly rows: number;\n readonly value: string;\n }): ReactElement {\n return (\n <Textarea\n aria-label={name}\n disabled={disabled}\n onChange={(event: ChangeEvent<HTMLTextAreaElement>): void =>\n onChange(event.target.value)\n }\n placeholder={placeholder}\n ref={applyFullWidthTextareaHost}\n resize=\"vertical\"\n rows={rows}\n style={FIELD_SETTINGS_TEXTAREA_STYLE}\n value={value}\n />\n );\n }\n\n function renderNumberInput(\n value: number | undefined,\n onChange: (value: number | undefined) => void,\n placeholder: string,\n options: {\n readonly max?: number;\n readonly min?: number;\n readonly step?: number;\n } = {},\n ): ReactElement {\n return (\n <Input\n max={options.max}\n min={options.min}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n onChange(\n clampOptionalNumber(\n parseOptionalNumberInput(event.target.value),\n options,\n ),\n )\n }\n placeholder={placeholder}\n showSpinner\n step={options.step ?? 1}\n value={typeof value === 'number' ? String(value) : ''}\n variant=\"measure\"\n />\n );\n }\n\n function renderDateValuePicker(\n field: DateFieldDefinition,\n value: string,\n onChange: (value: string | undefined) => void,\n ): ReactElement {\n if (field.type === 'datetime') {\n return (\n <DateTimePicker\n formatDate=\"YYYY-MM-DD\"\n formatTime=\"HH:mm\"\n hideSecond\n onChange={(nextValue): void =>\n onChange(formatDateTimePickerValue(nextValue))\n }\n placeholderLeft=\"選擇日期\"\n placeholderRight=\"選擇時間\"\n value={readDatePickerValue(value)}\n />\n );\n }\n\n return (\n <DatePicker\n format=\"YYYY-MM-DD\"\n onChange={(nextValue): void =>\n onChange(formatDatePickerValue(nextValue))\n }\n placeholder=\"選擇日期\"\n value={readDatePickerValue(value)}\n />\n );\n }\n\n function renderFieldOptionsTable(field: SelectFieldDefinition): ReactElement {\n const optionRows: FieldOptionRow[] = field.options.map((option, index) => ({\n index,\n key: `${field.fieldKey}-${index}`,\n label: option.label,\n value: option.value,\n }));\n const optionColumns: TableColumn<FieldOptionRow>[] = [\n {\n key: 'label',\n render: (row): ReactElement => (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedSelectField({\n options: updateFieldOption(field.options, row.index, {\n label: event.target.value,\n }),\n })\n }\n placeholder=\"例如:主管\"\n size=\"sub\"\n value={row.label}\n variant=\"base\"\n />\n ),\n title: 'Label',\n },\n {\n key: 'value',\n render: (row): ReactElement => (\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateSelectedSelectField({\n options: updateFieldOption(field.options, row.index, {\n value: event.target.value,\n }),\n })\n }\n placeholder=\"例如:manager\"\n size=\"sub\"\n value={row.value}\n variant=\"base\"\n />\n ),\n title: 'Value',\n },\n ];\n const optionActions: TableActions<FieldOptionRow> = {\n render: (row): ReturnType<TableActions<FieldOptionRow>['render']> => [\n {\n disabled: (): boolean => saving || field.options.length <= 1,\n icon: TrashIcon,\n iconType: 'icon-only',\n name: '移除選項',\n onClick: (): void =>\n updateSelectedSelectField({\n options: field.options.filter((_, index) => index !== row.index),\n }),\n variant: 'destructive-ghost',\n },\n ],\n width: 56,\n };\n\n return (\n <div style={COMPACT_STACK_STYLE}>\n <Table\n actions={optionActions}\n columns={optionColumns}\n dataSource={optionRows}\n showHeader\n size=\"sub\"\n />\n <div style={OPTION_ACTIONS_STYLE}>\n <Button\n disabled={saving}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n updateSelectedSelectField({\n options: [\n ...field.options,\n createNextFieldOption(field.options),\n ],\n })\n }\n variant=\"base-secondary\"\n >\n 新增選項\n </Button>\n </div>\n </div>\n );\n }\n\n function renderFieldBlock(\n field: FormFieldDefinition,\n draggableProvided: DraggableProvided,\n isDragging: boolean,\n ): ReactElement {\n return (\n <div\n {...draggableProvided.draggableProps}\n data-form-builder-field-key={field.fieldKey}\n ref={draggableProvided.innerRef}\n style={{\n ...FIELD_BLOCK_STYLE,\n ...(isDragging ? FIELD_BLOCK_DRAGGING_STYLE : null),\n ...draggableProvided.draggableProps.style,\n }}\n >\n <BaseCard>\n {renderFieldBlockContent(field, draggableProvided, isDragging)}\n </BaseCard>\n </div>\n );\n }\n\n function renderSettingsFormRow(\n label: string,\n name: string,\n control: ReactElement,\n disabled: boolean,\n wide = false,\n ): ReactElement {\n return (\n <div\n style={wide ? FIELD_SETTINGS_ROW_WIDE_STYLE : FIELD_SETTINGS_ROW_STYLE}\n >\n <div style={FIELD_SETTINGS_VALUE_STYLE}>\n <BPMFormField disabled={disabled} label={label} name={name}>\n {control}\n </BPMFormField>\n </div>\n </div>\n );\n }\n\n function renderFieldBlockContent(\n field: FormFieldDefinition,\n draggableProvided: DraggableProvided,\n isDragging: boolean,\n ): ReactElement {\n return (\n <div\n {...(draggableProvided.dragHandleProps ?? {})}\n aria-label=\"拖曳排序欄位\"\n style={FIELD_BLOCK_ROW_STYLE}\n title=\"拖曳排序\"\n >\n <span\n aria-label=\"拖曳排序\"\n role=\"img\"\n style={DRAG_HANDLE_STYLE}\n title=\"拖曳排序\"\n >\n <Icon icon={DotDragVerticalIcon} size={20} />\n </span>\n <div style={FIELD_BLOCK_TEXT_STYLE}>\n <Typography component=\"span\" ellipsis variant=\"label-primary\">\n {field.label}\n {field.required ? (\n <sup aria-label=\"必填\" style={REQUIRED_ASTERISK_STYLE}>\n *\n </sup>\n ) : null}\n </Typography>\n <Typography\n color=\"text-neutral\"\n component=\"span\"\n ellipsis\n variant=\"caption\"\n >\n {readFieldTypeLabel(field.type)} ·\n {field.required ? ' 必填' : ' 選填'} ·{field.fieldKey}\n </Typography>\n </div>\n <div style={FIELD_BLOCK_ACTIONS_STYLE}>\n <div style={FIELD_BLOCK_REQUIRED_STYLE}>\n <Toggle\n checked={Boolean(field.required)}\n disabled={saving || isDragging}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateFieldRequired(field.fieldKey, event.target.checked)\n }\n />\n </div>\n <Button\n disabled={isDragging}\n icon={EditIcon}\n iconType=\"icon-only\"\n onClick={(): void => setSelectedFieldKey(field.fieldKey)}\n variant={\n field.fieldKey === selectedField?.fieldKey\n ? 'base-primary'\n : 'base-ghost'\n }\n >\n 編輯欄位\n </Button>\n <Button\n disabled={saving || isDragging}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void => handleRemoveField(field.fieldKey)}\n variant=\"destructive-ghost\"\n >\n 移除欄位\n </Button>\n </div>\n </div>\n );\n }\n\n function renderPreviewTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 填寫預覽\n </Typography>\n <FormRenderer\n onChange={updatePreviewValues}\n schema={schema}\n uiSchema={uiSchema}\n value={previewValues}\n />\n </div>\n );\n }\n\n function renderVersionsTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n 版本紀錄\n </Typography>\n <Table\n columns={versionColumns}\n dataSource={versionRows}\n loading={loading}\n />\n </div>\n );\n }\n\n function renderAdvancedTab(): ReactElement {\n return (\n <div style={STACK_STYLE}>\n <Typography component=\"h2\" variant=\"h3\">\n Schema\n </Typography>\n <div style={ADVANCED_SCHEMA_FORM_STYLE}>\n {renderAdvancedSchemaRow(\n 'Form Schema',\n 'schemaJson',\n <JsonCodeEditor\n disabled={saving}\n height=\"360px\"\n name=\"schemaJson\"\n onChange={updateSchemaJson}\n placeholder=\"輸入 Form Schema JSON\"\n value={schemaJsonText}\n />,\n )}\n {renderAdvancedSchemaRow(\n 'UI Schema',\n 'uiSchemaJson',\n <JsonCodeEditor\n disabled={saving}\n height=\"240px\"\n name=\"uiSchemaJson\"\n onChange={updateUiSchemaJson}\n placeholder=\"輸入 UI Schema JSON\"\n value={uiSchemaJsonText}\n />,\n )}\n {advancedSchemaMessage ? (\n <Typography\n color=\"text-error\"\n style={ADVANCED_SCHEMA_MESSAGE_STYLE}\n variant=\"body\"\n >\n {advancedSchemaMessage}\n </Typography>\n ) : null}\n </div>\n </div>\n );\n }\n\n function renderAdvancedSchemaRow(\n label: string,\n name: string,\n control: ReactElement,\n ): ReactElement {\n return (\n <div style={ADVANCED_SCHEMA_ROW_STYLE}>\n <div style={ADVANCED_SCHEMA_VALUE_STYLE}>\n <BPMFormField disabled={saving} label={label} name={name}>\n {control}\n </BPMFormField>\n </div>\n </div>\n );\n }\n}\n\nfunction readFieldTypeLabel(type: FieldType): string {\n return (\n FIELD_TYPE_OPTIONS.find((option) => option.type === type)?.label ?? type\n );\n}\n\nfunction hasConditionRules(field: FormFieldDefinition): boolean {\n return Boolean(field.visibleWhen || field.requiredWhen || field.readonlyWhen);\n}\n\nfunction readFieldAsConditionSelectOption(field: FormFieldDefinition): {\n readonly id: string;\n readonly name: string;\n} {\n return {\n id: field.fieldKey,\n name: field.label,\n };\n}\n\nfunction isTextFieldDefinition(\n field: FormFieldDefinition,\n): field is TextFieldDefinition {\n return field.type === 'text' || field.type === 'textarea';\n}\n\nfunction readStringDefaultValue(\n value: FormFieldDefinition['defaultValue'],\n): string {\n return typeof value === 'string' ? value : '';\n}\n\nfunction parseStringList(value: string): readonly string[] | undefined {\n const values = value\n .split(/[\\n,]/u)\n .map((item) => item.trim())\n .filter(Boolean);\n\n return values.length ? values : undefined;\n}\n\nfunction readStringListInput(value: readonly string[] | undefined): string {\n return value?.join('\\n') ?? '';\n}\n\nfunction stringifyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\nfunction updateFieldOption(\n options: readonly FormFieldOption[],\n targetIndex: number,\n patch: Partial<FormFieldOption>,\n): readonly FormFieldOption[] {\n return options.map((option, index) =>\n index === targetIndex ? { ...option, ...patch } : option,\n );\n}\n\nfunction createNextFieldOption(\n options: readonly FormFieldOption[],\n): FormFieldOption {\n const nextIndex = options.length + 1;\n\n return {\n label: `選項 ${nextIndex}`,\n value: readNextOptionValue(options, nextIndex),\n };\n}\n\nfunction readNextOptionValue(\n options: readonly FormFieldOption[],\n index: number,\n): string {\n const value = `option_${index}`;\n\n return options.some((option) => option.value === value)\n ? readNextOptionValue(options, index + 1)\n : value;\n}\n\nfunction readBuilderSnapshot(\n schema: FormDefinitionSchema,\n uiSchema: FormUiSchema,\n): BuilderSnapshot {\n return {\n schemaJson: stringifyJson(schema),\n uiSchemaJson: stringifyJson(uiSchema),\n };\n}\n\nfunction readPublishedVersion(\n versions: readonly FormDefinitionVersionRecord[],\n currentVersionId: string | null | undefined,\n): FormDefinitionVersionRecord | null {\n return (\n (currentVersionId\n ? versions.find((version) => version.id === currentVersionId)\n : null) ??\n versions.find((version) => version.status === 'PUBLISHED') ??\n null\n );\n}\n\nfunction readHeaderDescription({\n hasUnsavedChanges,\n latestPublishedVersion,\n openedContentPublished,\n openedVersion,\n}: {\n readonly hasUnsavedChanges: boolean;\n readonly latestPublishedVersion: FormDefinitionVersionRecord | null;\n readonly openedContentPublished: boolean;\n readonly openedVersion: FormDefinitionVersionRecord | null;\n}): string {\n const editState = hasUnsavedChanges ? '有未儲存修改' : '沒有未儲存修改';\n const openedState = readOpenedVersionState({\n hasUnsavedChanges,\n openedContentPublished,\n openedVersion,\n });\n const publishedState = latestPublishedVersion\n ? `目前發布 v${latestPublishedVersion.version}:${formatDateTime(\n latestPublishedVersion.publishedAt,\n )}`\n : '目前沒有已發布版本';\n\n return `${editState} · ${openedState} · ${publishedState}`;\n}\n\nfunction readOpenedVersionState({\n hasUnsavedChanges,\n openedContentPublished,\n openedVersion,\n}: {\n readonly hasUnsavedChanges: boolean;\n readonly openedContentPublished: boolean;\n readonly openedVersion: FormDefinitionVersionRecord | null;\n}): string {\n if (hasUnsavedChanges) {\n return openedVersion\n ? `修改尚未發布,來源 v${openedVersion.version}`\n : '修改尚未發布';\n }\n\n if (openedContentPublished && openedVersion) {\n return `當前內容已發布 v${openedVersion.version}`;\n }\n\n if (openedVersion) {\n return `當前內容尚未發布 v${openedVersion.version}`;\n }\n\n return '當前內容尚未發布';\n}\n\nfunction moveItemByIndex<TItem>(\n items: readonly TItem[],\n sourceIndex: number,\n destinationIndex: number,\n): TItem[] {\n const sourceItem = items[sourceIndex];\n\n if (!sourceItem || sourceIndex === destinationIndex) {\n return [...items];\n }\n\n const remainingItems = items.filter((_, index) => index !== sourceIndex);\n\n return [\n ...remainingItems.slice(0, destinationIndex),\n sourceItem,\n ...remainingItems.slice(destinationIndex),\n ];\n}\n\nfunction FormVersionStatusBadge({\n status,\n}: {\n readonly status: FormDefinitionVersionRecord['status'];\n}): ReactElement {\n if (status === 'PUBLISHED') {\n return <Badge size=\"sub\" text=\"已發布\" variant=\"dot-success\" />;\n }\n\n if (status === 'ARCHIVED') {\n return <Badge size=\"sub\" text=\"已封存\" variant=\"dot-inactive\" />;\n }\n\n return <Badge size=\"sub\" text=\"草稿\" variant=\"dot-warning\" />;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"moBAQA,IAAM,EAAuC,CAC3C,WAAY,SACZ,OAAQ,4CACR,aAAc,EACd,MAAO,gCACP,QAAS,OACT,UAAW,IACX,QAAS,GACT,MAAO,MACT,EAEM,EAA+C,YAC9C,EACL,EAAA,WAAW,aACX,EAAA,WAAW,MAAM,CACf,IAAK,CACH,OAAQ,4CACR,aAAc,MACd,SAAU,OACV,MAAO,MACT,EACA,eAAgB,CACd,QAAS,2CACX,EACA,cAAe,CACb,WACE,sFACF,UAAW,MACb,EACA,aAAc,CACZ,MAAO,MACT,EACA,cAAe,CACb,YAAa,2CACf,EACA,eAAgB,CACd,WACE,qFACJ,CACF,CAAC,CACH,EAEM,GAAA,EAAA,EAAA,aACE,OAAO,yBACb,CACE,aACE,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,WAAuB,aAAgB,CAAA,EAErD,IAAK,EACP,CACF,EAWA,SAAgB,GAAe,CAC7B,WACA,SACA,OACA,WACA,cACA,SACoC,CACpC,OACE,EAAA,EAAA,KAAC,EAAD,CACE,aAAY,EACZ,WAAY,CACV,eAAgB,GAChB,gBAAiB,GACjB,cAAe,GACf,cAAe,GACf,WAAY,GACZ,oBAAqB,GACrB,0BAA2B,GAC3B,YAAa,GACb,mBAAoB,EACtB,EACA,SAAU,CAAC,EACX,WAAY,CAAC,GAAG,CAAsB,EAC9B,SACR,cAAe,GACL,WACG,cACb,SAAU,EACV,MAAM,QACC,QACP,MAAM,MACP,CAAA,CAEL,CC+CA,IAAM,GAAiD,CACrD,CACE,YAAa,aACb,KAAM,EAAA,cACN,MAAO,KACP,KAAM,MACR,EACA,CACE,YAAa,SACb,KAAM,EAAA,SACN,MAAO,MACP,KAAM,UACR,EACA,CACE,YAAa,WACb,KAAM,EAAA,mBACN,MAAO,KACP,KAAM,QACR,EACA,CACE,YAAa,QACb,KAAM,EAAA,mBACN,MAAO,KACP,KAAM,OACR,EACA,CACE,YAAa,SACb,KAAM,EAAA,aACN,MAAO,KACP,KAAM,MACR,EACA,CACE,YAAa,QACb,KAAM,EAAA,aACN,MAAO,OACP,KAAM,UACR,EACA,CACE,YAAa,UACb,KAAM,EAAA,YACN,MAAO,KACP,KAAM,SACR,EACA,CACE,YAAa,SACb,KAAM,EAAA,SACN,MAAO,OACP,KAAM,QACR,EACA,CACE,YAAa,SACb,KAAM,EAAA,YACN,MAAO,KACP,KAAM,OACR,EACA,CACE,YAAa,SACb,KAAM,EAAA,mBACN,MAAO,KACP,KAAM,UACR,EACA,CACE,YAAa,UACb,KAAM,EAAA,mBACN,MAAO,KACP,KAAM,aACR,CACF,EAEM,GAAsC,CAC1C,WAAY,QACZ,QAAS,OACT,SAAU,OACV,IAAK,EACP,EAEM,GAAqC,CACzC,KAAM,eACN,SAAU,CACZ,EAEM,GAAuC,CAC3C,KAAM,eACN,SAAU,GACZ,EAEM,EAA6B,CACjC,QAAS,OACT,IAAK,EACP,EAEM,GAAqC,CACzC,QAAS,OACT,SAAU,OACV,IAAK,CACP,EAEM,GAA4C,CAChD,KAAM,WACN,WAAY,QACd,EAEM,GAA4C,CAChD,QAAS,OACT,IAAK,CACP,EAEM,GAAuC,CAC3C,WAAY,SACZ,OAAQ,OACR,QAAS,OACT,IAAK,GACL,YAAa,MACf,EAEM,GAAwC,CAC5C,QAAS,OACT,KAAM,WACN,IAAK,EACL,SAAU,CACZ,EAEM,GAA2C,CAC/C,WAAY,SACZ,QAAS,OACT,KAAM,WACN,IAAK,CACP,EAEM,GAA4C,CAChD,WAAY,SACZ,QAAS,OACT,IAAK,CACP,EAEM,GAAmC,CACvC,WAAY,MACd,EAEM,GAA4C,CAChD,OAAQ,6CACV,EAEM,GAAoC,CACxC,WAAY,SACZ,OAAQ,6CACR,aAAc,EACd,QAAS,OACT,IAAK,GACL,UAAW,IACX,QAAS,GACT,UAAW,QACb,EAEM,GAA4C,CAChD,QAAS,OACT,IAAK,EACL,eAAgB,QAClB,EAEM,GAA2C,CAC/C,QAAS,OACT,IAAK,EACP,EAEM,GAA8C,CAClD,QAAS,OACT,UAAW,GACX,oBAAqB,uCACrB,OAAQ,CACV,EAEM,GAAoD,CACxD,WAAY,QACd,EAEM,GAAgD,CACpD,WAAY,SACZ,QAAS,OACT,IAAK,EACL,WAAY,SACZ,eAAgB,UAClB,EAEM,GAA2C,CAC/C,WAAY,QACd,EAEM,GAA0C,CAC9C,WAAY,QACZ,QAAS,QACT,MAAO,MACT,EAEM,GAA+C,CACnD,GAAG,GACH,WAAY,QACd,EAEM,GAA4C,CAChD,SAAU,EACV,MAAO,MACT,EAEM,GAA+C,CACnD,SAAU,OACV,MAAO,MACT,EAEM,GAA4C,CAChD,QAAS,OACT,IAAK,EACP,EAEM,GAA2C,CAC/C,WAAY,QACZ,QAAS,QACT,MAAO,MACT,EAEM,GAA6C,CACjD,SAAU,EACV,MAAO,MACT,EAEM,GAA+C,CACnD,WAAY,QACd,EAEM,GAA8C,CAClD,QAAS,OACT,IAAK,GACL,MAAO,MACT,EAEM,GAA2C,CAC/C,QAAS,OACT,IAAK,EACL,oBAAqB,sCACvB,EAEM,GAAmC,CACvC,QAAS,aACX,EAEM,GAAiC,CACrC,QAAS,OACT,IAAK,EACP,EAEM,GAAqC,CACzC,QAAS,OACT,IAAK,CACP,EAEM,GAAsC,CAC1C,QAAS,OACT,eAAgB,UAClB,EAEM,GAAyC,CAC7C,MAAO,8BACP,SAAU,SACV,WAAY,EACZ,WAAY,EACZ,cAAe,OACjB,EAEA,SAAS,GAA2B,EAAsC,CACnE,IAIL,EAAQ,MAAM,MAAQ,OACxB,CAEA,IAAM,EAAqC,CACzC,OAAQ,CAAC,EACT,cAAe,CACjB,EAEM,EAAgC,CACpC,OAAQ,CAAC,EACT,cAAe,CACjB,EAEM,GAGA,CACJ,CAAE,GAAI,QAAS,KAAM,KAAM,EAC3B,CAAE,GAAI,OAAQ,KAAM,GAAI,EACxB,CAAE,GAAI,QAAS,KAAM,GAAI,CAC3B,EAEM,GAGA,CACJ,CAAE,GAAI,OAAQ,KAAM,GAAI,EACxB,CAAE,GAAI,QAAS,KAAM,GAAI,CAC3B,EAEM,GAAyD,CAC7D,CACE,MAAO,KACP,KAAM,mBACN,eAAgB,gBAChB,OAAQ,aACV,EACA,CACE,MAAO,KACP,KAAM,oBACN,eAAgB,kBAChB,OAAQ,cACV,EACA,CACE,MAAO,KACP,KAAM,oBACN,eAAgB,kBAChB,OAAQ,cACV,CACF,EAUA,SAAgB,EAAgB,CAAE,UAA8C,CAC9E,IAAM,EAAS,EAAA,EAAiB,EAC1B,EAAmB,EACnB,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAgD,IAAI,EAC7D,CAAC,EAAO,IAAA,EAAA,EAAA,UAAyD,IAAI,EACrE,CAAC,EAAQ,IAAA,EAAA,EAAA,UAA4C,CAAY,EACjE,CAAC,EAAU,IAAA,EAAA,EAAA,UAAsC,CAAe,EAChE,CAAC,GAAgB,IAAA,EAAA,EAAA,UACrB,EAAc,CAAY,CAC5B,EACM,CAAC,GAAkB,IAAA,EAAA,EAAA,UACvB,EAAc,CAAe,CAC/B,EACM,CAAC,GAAe,KAAA,EAAA,EAAA,UAAiD,CAAC,CAAC,EACnE,CAAC,GAAuB,IAAA,EAAA,EAAA,UAE5B,IAAI,EACA,CAAC,EAAW,KAAA,EAAA,EAAA,UAAwC,QAAQ,EAC5D,CAAC,EAAkB,IAAA,EAAA,EAAA,UAA+C,IAAI,EACtE,CAAC,GAAO,IAAA,EAAA,EAAA,UAAoC,IAAI,EAChD,CAAC,GAAiB,IAAA,EAAA,EAAA,UAA+B,EAAK,EACtD,CAAC,GAAgB,KAAA,EAAA,EAAA,UACrB,EAAoB,EAAc,CAAe,CACnD,EACM,CAAC,GAAS,KAAA,EAAA,EAAA,UAAuB,EAAI,EACrC,CAAC,GAAU,KAAA,EAAA,EAAA,UAAwB,EAAK,EACxC,CAAC,EAAQ,IAAA,EAAA,EAAA,UAAsB,EAAK,GAE1C,EAAA,EAAA,eAAsB,CACpB,EAAoB,CACtB,EAAG,CAAC,CAAgB,CAAC,GAErB,EAAA,EAAA,eAAsB,CACK,EAAO,OAAO,KACpC,GAAU,EAAM,WAAa,CAG5B,GAIJ,EAAoB,EAAO,OAAO,IAAI,UAAY,IAAI,CACxD,EAAG,CAAC,EAAO,OAAQ,CAAgB,CAAC,GAEpC,EAAA,EAAA,eAAsB,CACpB,GAAkB,IAAA,EAAA,EAAA,yBACQ,EAAO,OAAQ,CAAa,CACtD,CACF,EAAG,CAAC,EAAO,MAAM,CAAC,GAElB,EAAA,EAAA,eAAsB,CAChB,IAAc,aAIlB,EAAkB,EAAc,CAAM,CAAC,EACvC,EAAoB,EAAc,CAAQ,CAAC,EAC7C,EAAG,CAAC,EAAW,EAAQ,CAAQ,CAAC,EAEhC,IAAM,GAAA,EAAA,EAAA,aAEF,EAAO,OAAO,KAAM,GAAU,EAAM,WAAa,CAAgB,GACjE,EAAO,OAAO,IACd,KACF,CAAC,EAAO,OAAQ,CAAgB,CAClC,EACM,IAAA,EAAA,EAAA,cAED,GAAQ,UAAY,CAAC,GAAG,IAAK,IAAa,CACzC,IAAK,EAAQ,GACb,YAAa,EAAA,EAAe,EAAQ,WAAW,EAC/C,OAAQ,EAAQ,OAChB,UAAW,EAAA,EAAe,EAAQ,SAAS,EAC3C,QAAS,IAAI,EAAQ,SACvB,EAAE,EACJ,CAAC,CAAM,CACT,EACM,IAAA,EAAA,EAAA,aAC6B,CAC/B,CAAE,UAAW,UAAW,IAAK,UAAW,MAAO,KAAM,MAAO,GAAI,EAChE,CACE,IAAK,SACL,OAAS,IACP,EAAA,EAAA,KAAC,GAAD,CAAwB,OAAQ,EAAO,MAAS,CAAA,EAElD,MAAO,KACP,MAAO,GACT,EACA,CACE,UAAW,YACX,IAAK,YACL,MAAO,OACP,MAAO,GACT,EACA,CACE,UAAW,cACX,IAAK,cACL,MAAO,OACP,MAAO,GACT,CACF,EACA,CAAC,CACH,EACM,IAAA,EAAA,EAAA,aACmB,EAAoB,EAAQ,CAAQ,EAC3D,CAAC,EAAQ,CAAQ,CACnB,EACM,EACJ,GAAgB,aAAe,GAAe,YAC9C,GAAgB,eAAiB,GAAe,cAElD,EAAA,EAAA,eAA8B,CAC5B,SAAS,EAAmB,EAAgC,CACrD,IAIL,EAAM,eAAe,EACrB,EAAM,YAAc,GACtB,CAIA,OAFA,OAAO,iBAAiB,eAAgB,CAAkB,MAEvC,CACjB,OAAO,oBAAoB,eAAgB,CAAkB,CAC/D,CACF,EAAG,CAAC,CAAiB,CAAC,EAEtB,SAAS,IAA0B,CAE/B,GACA,CAAC,OAAO,QAAQ,sBAAsB,GAKxC,EAAO,KAAK,QAAQ,CACtB,CACA,IAAM,IAAA,EAAA,EAAA,aAEF,GACE,GAAQ,UAAY,CAAC,EACrB,GAAQ,WAAW,gBACrB,EACF,CAAC,GAAQ,WAAW,iBAAkB,GAAQ,QAAQ,CACxD,EACM,GACJ,GAAS,IAA0B,GAAQ,SAAS,IAAM,KACtD,EACJ,CAAC,GAAqB,IAAe,SAAW,YAC5C,GAAoB,GAAsB,CAC9C,oBACA,0BACA,yBACA,gBACF,CAAC,EACK,GACJ,GAAW,CAAC,GAAqB,GAA0B,CAAC,EACxD,GAAoB,EACtB,QACA,EACE,OACA,EACE,MACA,OAER,eAAe,GAAgC,CAC7C,GAAW,EAAI,EACf,EAAS,IAAI,EAEb,GAAI,CACF,IAAM,EAAa,MAAA,EAAA,EAAA,iBAAsB,CAAgB,EACnD,EACJ,EAAW,SAAS,KAAM,GAAY,EAAQ,SAAW,OAAO,GAChE,KAEF,EAAU,CAAU,EACpB,EAAS,CAAS,EAClB,IAAM,EACJ,GAAW,QAAU,EAAW,SAAS,IAAI,QAAU,EACnD,EACJ,GAAW,UACX,EAAW,SAAS,IAAI,UACxB,EAEF,EAAU,CAAU,EACpB,EAAY,CAAY,EACxB,GAAkB,EAAoB,EAAY,CAAY,CAAC,EAC/D,EAAkB,EAAc,CAAU,CAAC,EAC3C,EAAoB,EAAc,CAAY,CAAC,EAC/C,EACE,GAAW,OAAO,OAAO,IAAI,UAC3B,EAAW,SAAS,IAAI,OAAO,OAAO,IAAI,UAC1C,IACJ,EACA,EAAyB,IAAI,CAC/B,OAAS,EAAuB,CAC9B,EAAS,EAAiB,CAAY,CAAC,CACzC,QAAU,CACR,GAAW,EAAK,CAClB,CACF,CAEA,eAAe,IAAyD,CAEtE,IAAM,EAAY,MAAA,EAAA,EAAA,4BADE,GAAU,MAAA,EAAA,EAAA,oBAAyB,CAAgB,GAEzD,GACZ,EACA,CACF,EAIA,OAFA,EAAS,CAAS,EAEX,CACT,CAEA,eAAe,IAAiC,CAC9C,EAAU,EAAI,EACd,EAAS,IAAI,EAEb,GAAI,CACF,MAAM,GAAiB,EACvB,MAAM,EAAe,CACvB,OAAS,EAAuB,CAC9B,EAAS,EAAiB,CAAY,CAAC,CACzC,QAAU,CACR,EAAU,EAAK,CACjB,CACF,CAEA,eAAe,IAA+B,CAC5C,EAAU,EAAI,EACd,EAAS,IAAI,EAEb,GAAI,CAEF,MAAA,EAAA,EAAA,+BAAmC,MADV,GAAiB,GACI,EAAE,EAChD,MAAM,EAAe,CACvB,OAAS,EAAuB,CAC9B,EAAS,EAAiB,CAAY,CAAC,CACzC,QAAU,CACR,EAAU,EAAK,CACjB,CACF,CAEA,eAAe,GAAiB,EAA6B,CAC3D,GAAI,CAAC,EACH,MAAU,MAAM,UAAU,EAG5B,GAAY,EAAI,EAEhB,GAAI,CACF,IAAM,EAAoB,MAAA,EAAA,EAAA,sBACxB,EAAO,WAAW,GAClB,CACF,EAEA,EAAU,CACR,GAAG,EACH,WAAY,CACd,CAAC,EACD,EAAmB,EAAK,CAC1B,QAAU,CACR,GAAY,EAAK,CACnB,CACF,CAEA,SAAS,EAAe,EAAuB,CAE7C,IAAM,GAAA,EAAA,EAAA,uBAA8B,EADlB,EAAO,OAAO,OAAS,CACU,EAEnD,EAAU,CACR,GAAG,EACH,OAAQ,CAAC,GAAG,EAAO,OAAQ,CAAK,CAClC,CAAC,EACD,EAAY,CACV,GAAG,EACH,OAAQ,CACN,GAAG,EAAS,OACZ,CACE,SAAU,EAAM,SAChB,MACE,IAAS,YAAc,IAAS,cAAgB,OAAS,MAC7D,CACF,CACF,CAAC,EACD,EAAoB,EAAM,QAAQ,EAClC,GAAa,QAAQ,EACrB,EAAyB,IAAI,CAC/B,CAEA,SAAS,GAAgB,EAAsB,CAC7C,IAAM,EAAU,EAEZ,IAAY,YAAc,IAAc,aAC1C,EAAkB,EAAc,CAAM,CAAC,EACvC,EAAoB,EAAc,CAAQ,CAAC,GAG7C,GAAa,CAAO,CACtB,CAEA,SAAS,GAAkB,EAAwB,CACjD,IAAM,EAAkB,EAAO,OAAO,OACnC,GAAU,EAAM,WAAa,CAChC,EAEA,EAAU,CACR,GAAG,EACH,OAAQ,CACV,CAAC,EACD,EAAY,CACV,GAAG,EACH,OAAQ,EAAS,OAAO,OAAQ,GAAS,EAAK,WAAa,CAAQ,CACrE,CAAC,EACD,EACE,IAAqB,EAChB,EAAgB,IAAI,UAAY,KACjC,CACN,EACA,EAAyB,IAAI,CAC/B,CAEA,SAAS,GAAmB,EAA0B,CACpD,IAAM,EAAc,EAAO,YAEtB,GAID,EAAO,OAAO,QAAU,EAAY,QAIxC,EAAW,IAAmB,CAC5B,GAAG,EACH,OAAQ,GACN,EAAc,OACd,EAAO,OAAO,MACd,EAAY,KACd,CACF,EAAE,EACF,EAAa,IAAqB,CAChC,GAAG,EACH,OAAQ,GACN,EAAgB,OAChB,EAAO,OAAO,MACd,EAAY,KACd,CACF,EAAE,EACF,EAAyB,IAAI,EAC/B,CAEA,SAAS,EACP,EAaM,CACN,EACG,IAAW,CAAE,GAAG,EAAO,GAAG,CAAM,EACnC,CACF,CAEA,SAAS,EACP,EACM,CACN,GAAI,CAAC,EACH,OAGF,IAAM,EAAmB,EAAc,SACjC,EAAY,EAAQ,CAAa,EACjC,EAAe,EAAU,SAE/B,EAAU,CACR,GAAG,EACH,OAAQ,EAAO,OAAO,IACnB,GACC,EAAM,WAAa,EAAmB,EAAY,CACtD,CACF,CAAC,EACD,EAAY,CACV,GAAG,EACH,OAAQ,EAAS,OAAO,IAAK,GAC3B,EAAK,WAAa,EACd,CAAE,GAAG,EAAM,SAAU,CAAa,EAClC,CACN,CACF,CAAC,EACD,EAAoB,CAAY,EAChC,EAAyB,IAAI,CAC/B,CAEA,SAAS,EACP,EAGM,CACN,EAAyB,GACvB,GAAsB,CAAK,EAAI,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAC1D,CACF,CAEA,SAAS,EACP,EAGM,CACN,EAAyB,IAAA,EAAA,EAAA,yBACC,CAAK,EAAI,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAC5D,CACF,CAEA,SAAS,GACP,EACM,CACN,EAAyB,IAAA,EAAA,EAAA,uBACD,CAAK,EAAI,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAC1D,CACF,CAEA,SAAS,EACP,EACM,CACN,EAAyB,IAAA,EAAA,EAAA,yBACC,CAAK,EAAI,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAC5D,CACF,CAEA,SAAS,GACP,EACM,CACN,EAAyB,GACvB,EAAM,OAAS,UAAY,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CACtD,CACF,CAEA,SAAS,GACP,EAMM,CACN,EAAyB,GACvB,EAAM,OAAS,cAAgB,CAAE,GAAG,EAAO,GAAG,CAAM,EAAI,CAC1D,CACF,CAEA,SAAS,GAAoB,EAAkC,CAC7D,GAAiB,CAAM,CACzB,CAEA,SAAS,GAAoB,EAAkB,EAAyB,CACtE,EAAW,IAAmB,CAC5B,GAAG,EACH,OAAQ,EAAc,OAAO,IAC1B,GACC,EAAM,WAAa,EACd,CAAE,GAAG,EAAO,UAAS,EACtB,CACR,CACF,EAAE,EACF,EAAyB,IAAI,CAC/B,CAEA,SAAS,GAAiB,EAAqB,CAC7C,EAAkB,CAAK,EAEvB,GAAI,CACF,EAAU,KAAK,MAAM,CAAK,CAAyB,EACnD,EAAyB,IAAI,CAC/B,MAAQ,CACN,EAAyB,wBAAwB,CACnD,CACF,CAEA,SAAS,GAAmB,EAAqB,CAC/C,EAAoB,CAAK,EAEzB,GAAI,CACF,EAAY,KAAK,MAAM,CAAK,CAAiB,EAC7C,EAAyB,IAAI,CAC/B,MAAQ,CACN,EAAyB,sBAAsB,CACjD,CACF,CAEA,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,MAAC,EAAA,OAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,EAAD,CAAe,WAAW,QAAU,CAAA,GAEpC,EAAA,EAAA,MAAC,EAAA,OAAO,KAAR,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAA,UACE,EAAA,EAAA,MAAC,EAAA,QAAD,CACE,YAAa,GACb,YAAa,GACb,MAAO,GAAQ,WAAW,MAAQ,iBAHpC,EAKE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,aAAW,SACX,SAAU,IAAY,CAAC,EACvB,KAAM,EAAA,SACN,SAAS,YACT,YAAqB,EAAmB,EAAI,EAC5C,QAAQ,sBACT,QAEO,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,aAAW,OACX,SAAU,GAAU,CAAC,EACrB,KAAM,EAAA,SACN,SAAS,YACT,YAAqB,KAAK,GAAgB,EAC1C,QAAQ,0BACT,MAEO,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,GACV,KAAM,EAAA,YACN,SAAS,UACT,YAAqB,KAAK,GAAc,EACxC,QAAQ,wBAEP,EACK,CAAA,CACK,GACL,CAAA,GAEZ,EAAA,EAAA,KAAC,EAAA,aAAD,CAAA,UACE,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,UACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,CACG,IACC,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,aAAa,QAAQ,gBACpC,EACS,CAAA,EACV,MACJ,EAAA,EAAA,MAAC,EAAA,IAAD,CACE,UAAW,EACX,SAAU,GACV,KAAK,eAHP,EAKE,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAsB,IAAW,EAApB,QAAoB,GACjC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAuB,IAAW,EAArB,SAAqB,GAClC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAwB,IAAW,EAAtB,UAAsB,GACnC,EAAA,EAAA,KAAC,EAAA,QAAD,CAAA,SAAwB,IAAW,EAAtB,UAAsB,CAChC,IAEJ,IAAc,SAAW,GAAgB,EAAI,KAC7C,IAAc,UAAY,GAAiB,EAAI,KAC/C,IAAc,WAAa,GAAkB,EAAI,KACjD,IAAc,WAAa,GAAkB,EAAI,IAC/C,GACE,CAAA,CACG,CAAA,CACH,CAAA,CAAA,CACP,CAAA,CAAA,GAER,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,YAAY,KACZ,YAAa,GAAQ,WAAW,MAAQ,GACxC,QAAS,GACT,YAAqB,EAAmB,EAAK,EAC7C,SAAU,GACV,KAAM,GACN,MAAM,QACP,CAAA,CACD,CAAA,CAAA,EAGJ,SAAS,IAAgC,CACvC,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,WAAZ,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,yBAAgB,MAEvC,CAAA,GACZ,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,YACT,GAAmB,IAAK,IACvB,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,KAAM,EAAO,KACb,SAAS,UAET,YAAqB,EAAe,EAAO,IAAI,EAC/C,KAAK,MACL,MAAO,GACP,KAAK,SACL,QAAQ,0BAEP,EAAO,KACF,EARD,EAAO,IAQN,CACT,CACE,CAAA,CACF,KAEL,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,GAAG,EAAa,GAAG,EAAoB,WAArD,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,yBAAgB,MAEvC,CAAA,EACX,EAAO,OAAO,OAAS,GACtB,EAAA,EAAA,KAAC,EAAA,gBAAD,CAAiB,UAAW,aAC1B,EAAA,EAAA,KAAC,EAAA,UAAD,CAAW,YAAY,+BACnB,IACA,EAAA,EAAA,MAAC,MAAD,CACE,GAAI,EAAkB,eACtB,IAAK,EAAkB,SACvB,MAAO,WAHT,CAKG,EAAO,OAAO,KAAK,EAAO,KACzB,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,YAAa,EAAM,SACZ,QACP,eAAgB,YAGd,EAAmB,IACnB,GACE,EACA,EACA,EAAS,UACX,CAEO,EATJ,EAAM,QASF,CACZ,EACA,EAAkB,WAChB,GAEE,CAAA,CACI,CAAA,GAEjB,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,WAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,cAAK,QAE5B,CAAA,GACZ,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,gBAAO,6BAEpC,CAAA,CACT,KACL,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,YAAqB,EAAe,MAAM,EAC1C,QAAQ,wBACT,QAEO,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,YAAqB,EAAe,UAAU,EAC9C,QAAQ,0BACT,OAEO,CAAA,CACL,GACF,GAEJ,KAEL,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,CAAE,GAAG,EAAa,GAAG,EAAsB,WAAvD,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,yBAAgB,MAEvC,CAAA,EACX,EACC,GAAoB,CAAa,GAEjC,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,gBAAO,YAEpC,CAAA,CAEX,GACF,GACF,GAET,CAEA,SAAS,GAAoB,EAA0C,CACrE,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,CACG,GAAwB,CAAK,EAC7B,GAA4B,CAAK,CAC/B,GAET,CAEA,SAAS,GAAwB,EAA0C,CACzE,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,KAAK,OACL,KAAM,GAAmB,EAAM,IAAI,EACnC,QAAQ,WACT,CAAA,CACE,CAAA,EACJ,EACC,KACA,cACA,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAAoB,CAAE,MAAO,EAAM,OAAO,KAAM,CAAC,EAEnD,YAAY,UACZ,MAAO,EAAM,MACb,QAAQ,MACT,CAAA,EACD,CACF,EACC,EACC,SACA,YACA,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAAoB,CAAE,SAAU,EAAM,OAAO,KAAM,CAAC,EAEtD,YAAY,YACZ,MAAO,EAAM,SACb,QAAQ,MACT,CAAA,EACD,CACF,EACC,EACC,OACA,oBACA,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAAoB,CAClB,YAAa,EAAM,OAAO,OAAS,IAAA,EACrC,CAAC,EAEH,YAAY,aACZ,MAAO,EAAM,aAAe,GAC5B,QAAQ,MACT,CAAA,EACD,CACF,EACC,GAA2B,CAAK,CAC9B,GAET,CAEA,SAAS,GACP,EACc,CACd,OACE,EAAA,EAAA,KAAC,EAAA,UAAD,CACE,gBAAiB,GAAkB,CAAK,EACxC,KAAK,MACL,MAAM,iBAEN,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,UAAU,KACV,MAAO,GACP,QAAQ,yBACT,MAEW,CAAA,GACZ,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,MAAM,eACN,MAAO,GACP,QAAQ,gBACT,+BAEW,CAAA,EACX,GAAwB,CAAK,CAC3B,GACI,CAAA,CAEf,CAEA,SAAS,GACP,EACc,CAqBd,OApBI,GAAsB,CAAK,EACtB,GAAwB,CAAK,GAGtC,EAAA,EAAA,yBAA4B,CAAK,EACxB,GAA0B,CAAK,GAGxC,EAAA,EAAA,uBAA0B,CAAK,EACtB,GAAwB,CAAK,GAGtC,EAAA,EAAA,yBAA4B,CAAK,EACxB,GAA0B,CAAK,EAGpC,EAAM,OAAS,UACV,GAA2B,CAAK,EAGlC,GAA8B,CAAK,CAC5C,CAEA,SAAS,GAAwB,EAA0C,CACzE,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,EACC,MACA,oBACA,EAAM,OAAS,WACb,GAAuB,CACrB,SAAU,EACV,KAAM,oBACN,SAAW,GACT,EAAwB,CAAE,aAAc,GAAS,IAAA,EAAU,CAAC,EAC9D,YAAa,aACb,KAAM,EACN,MAAO,EAAuB,EAAM,YAAY,CAClD,CAAC,GAED,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAAwB,CACtB,aAAc,EAAM,OAAO,OAAS,IAAA,EACtC,CAAC,EAEH,YAAY,aACZ,MAAO,EAAuB,EAAM,YAAY,EAChD,QAAQ,MACT,CAAA,EAEH,CACF,EACC,EACC,OACA,iBACA,EACE,EAAM,UACL,GAAgB,EAAwB,CAAE,UAAW,CAAM,CAAC,EAC7D,OACA,CAAE,IAAK,CAAE,CACX,EACA,CACF,EACC,EACC,OACA,iBACA,EACE,EAAM,UACL,GAAgB,EAAwB,CAAE,UAAW,CAAM,CAAC,EAC7D,SACA,CAAE,IAAK,CAAE,CACX,EACA,CACF,CACA,CAAA,CAAA,CAEN,CAEA,SAAS,GACP,EACc,CACd,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,EACC,MACA,oBACA,EACE,OAAO,EAAM,cAAiB,SAC1B,EAAM,aACN,IAAA,GACH,GAAgB,EAA0B,CAAE,aAAc,CAAM,CAAC,EAClE,EAAM,OAAS,QAAU,UAAY,SACrC,CAAE,IAAK,EAAM,QAAS,IAAK,EAAM,OAAQ,CAC3C,EACA,CACF,EACC,EACC,MACA,eACA,EACE,EAAM,QACL,GAAgB,EAA0B,CAAE,QAAS,CAAM,CAAC,EAC7D,MACF,EACA,CACF,EACC,EACC,MACA,eACA,EACE,EAAM,QACL,GAAgB,EAA0B,CAAE,QAAS,CAAM,CAAC,EAC7D,WACF,EACA,CACF,CACA,CAAA,CAAA,CAEN,CAEA,SAAS,GAAwB,EAA0C,CACzE,OAAO,EACL,MACA,oBACA,GACE,EACA,EAAuB,EAAM,YAAY,EACxC,GAAgB,GAAwB,CAAE,aAAc,CAAM,CAAC,CAClE,EACA,CACF,CACF,CAEA,SAAS,GACP,EACc,CACd,IAAM,EAAgB,MAAM,QAAQ,EAAM,YAAY,EAClD,EAAM,aACN,CAAC,EACC,EAAiB,EAAM,QAC1B,OAAQ,GAAW,EAAc,SAAS,EAAO,KAAK,CAAC,EACvD,IAAI,EAAA,6BAA6B,EAEpC,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,EACC,MACA,oBACA,EAAM,OAAS,YACb,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAA,GACA,KAAK,WACL,SAAW,GACT,EAA0B,CACxB,aAAc,EAAQ,OAClB,EAAQ,IAAK,GAAW,EAAO,EAAE,EACjC,IAAA,EACN,CAAC,EAEH,QAAS,EAAM,QAAQ,IAAI,EAAA,6BAA6B,EACxD,YAAY,aACZ,MAAO,CACR,CAAA,GAED,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAA,GACA,SAAW,GACT,EAA0B,CACxB,aAAc,GAAQ,IAAM,IAAA,EAC9B,CAAC,EAEH,QAAS,EAAM,QAAQ,IAAI,EAAA,6BAA6B,EACxD,YAAY,SACZ,MACE,OAAO,EAAM,cAAiB,UAAA,EAAA,EAAA,kBAExB,EAAM,QAAQ,IAAI,EAAA,6BAA6B,EAC/C,EAAM,YACR,EACA,IAEP,CAAA,EAEH,CACF,EACC,EACC,KACA,eACA,GAAwB,CAAK,EAC7B,EACA,EACF,CACA,CAAA,CAAA,CAEN,CAEA,SAAS,GACP,EACc,CACd,IAAM,EACJ,OAAO,EAAM,cAAiB,UAC1B,OAAO,EAAM,YAAY,EACzB,QAEN,OAAO,EACL,MACA,qBACA,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,SAAW,GACT,GAA2B,CACzB,aACE,GAAQ,KAAO,OACX,GACA,GAAQ,KAAO,QACb,GACA,IAAA,EACV,CAAC,EAEH,QAAS,CAAC,GAAG,EAAuB,EACpC,YAAY,SACZ,OAAA,EAAA,EAAA,kBAAwB,GAAyB,CAAY,CAC9D,CAAA,EACD,CACF,CACF,CAEA,SAAS,GACP,EACc,CACd,OACE,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,CACG,EACC,MACA,gBACA,EACE,EAAM,SACL,GAAgB,GAA8B,CAAE,SAAU,CAAM,CAAC,EAClE,OACA,CAAE,IAAK,CAAE,CACX,EACA,CACF,EACC,EACC,OACA,yBACA,GAAuB,CACrB,SAAU,EACV,KAAM,yBACN,SAAW,GACT,GAA8B,CAC5B,kBAAmB,GAAgB,CAAK,CAC1C,CAAC,EACH,YAAa,oCACb,KAAM,EACN,MAAO,GAAoB,EAAM,iBAAiB,CACpD,CAAC,EACD,EACF,CACA,CAAA,CAAA,CAEN,CAEA,SAAS,GAAwB,EAA0C,CACzE,IAAM,EAAwB,EAAO,OAAO,OACzC,GAAgB,EAAY,WAAa,EAAM,QAClD,EAcA,OAZK,EAAsB,QAazB,EAAA,EAAA,KAAA,EAAA,SAAA,CAAA,SACG,GAAuB,IAAK,GAC3B,GAAoB,EAAO,EAAQ,CAAqB,CAC1D,CACA,CAAA,GAfA,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,MAAM,eACN,MAAO,GACP,QAAQ,gBACT,kCAEW,CAAA,CAWlB,CAEA,SAAS,GACP,EACA,EACA,EACc,CACd,IAAM,EAAa,EAAM,EAAO,QAC1B,EAAa,GAAA,EAAA,EAAA,oBAAgC,CAAU,EAAI,KAC3D,EAAuB,EAAsB,KAChD,GAAmB,EAAe,WAAa,GAAY,QAC9D,EACM,EACJ,GAAwB,EAAsB,GAC1C,EAA8B,EAAsB,IACxD,EACF,EACM,GAAA,EAAA,EAAA,8BACJ,CACF,EACM,EACJ,GACA,EAAyB,KACtB,GAAW,EAAO,KAAO,EAAW,QACvC,EACI,EAAW,UAAA,EAAA,EAAA,8BACkB,CAAsB,EACnD,EACJ,GAAY,QAAA,EAAA,EAAA,2BAAmC,CAAsB,EACjE,EAAU,EAAQ,EAClB,EAAkB,IAAY,CAAC,GAAc,CAAC,GAEpD,OAAO,EACL,EAAO,MACP,EAAO,MACP,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,QAAS,EACT,SAAU,EACV,MAAO,EAAU,MAAQ,MACzB,SAAW,GACT,EACE,EAAO,OACP,EAAM,OAAO,SAAA,EAAA,EAAA,0BAEP,GAAA,EAAA,EAAA,8BAC6B,CAAsB,GAAA,EAAA,EAAA,2BACzB,CAAsB,CAClD,EACA,IAAA,EACN,EAEF,KAAK,MACL,eAAgB,EAAO,cACxB,CAAA,EACA,EACC,GACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,MAAM,eAAe,QAAQ,gBAAO,mCAEpC,CAAA,GAEZ,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,SAAW,GAAiB,CAC1B,IAAM,EACJ,EAAsB,KACnB,GACC,EAAe,WAAa,GAAQ,EACxC,GAAK,EAEP,EACE,EAAO,QAAA,EAAA,EAAA,0BAEL,GAAA,EAAA,EAAA,8BAC6B,CAAS,GAAA,EAAA,EAAA,2BACZ,CAAS,CACrC,CACF,CACF,EACA,QAAS,EACT,YAAY,OACZ,OAAA,EAAA,EAAA,kBACE,EACA,EAAuB,QACzB,CACD,CAAA,GACD,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,SAAW,GACT,EACE,EAAO,QAAA,EAAA,EAAA,0BAEL,GAAA,EAAA,EAAA,6BAC4B,GAAQ,EAAE,GACpC,EACF,CACF,CACF,EAEF,QAAS,CAAC,GAAG,CAAwB,EACrC,YAAY,OACZ,OAAA,EAAA,EAAA,kBACE,EACA,CACF,CACD,CAAA,EACA,GACC,EACA,EACC,GACC,EACE,EAAO,QAAA,EAAA,EAAA,0BAEL,EACA,EACA,CACF,CACF,CACJ,CACG,IAEL,IACD,IACL,EACA,EACF,CACF,CAEA,SAAS,EACP,EACA,EACM,CACN,EAAoB,EAAG,GAAS,CAAW,CAAC,CAC9C,CAEA,SAAS,GACP,EACA,EACA,EACc,CACd,GAAI,EAAe,OAAS,UAC1B,OACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,SAAW,GAAiB,EAAS,GAAQ,IAAM,MAAM,EACzD,QAAS,CAAC,GAAG,EAA+B,EAC5C,YAAY,MACZ,OAAA,EAAA,EAAA,kBACE,GACA,IAAU,QAAU,QAAU,MAChC,CACD,CAAA,EAIL,IAAA,EAAA,EAAA,yBAA4B,CAAc,EAAG,CAC3C,IAAM,EAAU,EAAe,QAAQ,IAAI,EAAA,6BAA6B,EAExE,OACE,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,UAAW,GACX,SAAW,GACT,EAAS,GAAQ,IAAM,EAAQ,IAAI,IAAM,EAAE,EAEpC,UACT,YAAY,MACZ,OAAA,EAAA,EAAA,kBAAwB,EAAS,CAAK,CACvC,CAAA,CAEL,CAgBA,OAdA,EAAA,EAAA,yBAA4B,CAAc,EACjC,GAAA,EAAA,EAAA,0BACoB,CAAK,EAC7B,GAAoB,EAAS,OAAO,GAAa,CAAC,CAAC,EACpD,KACF,GAGF,EAAA,EAAA,uBAA0B,CAAc,EAC/B,GAAsB,EAAgB,EAAQ,GACnD,EAAS,GAAa,EAAE,CAC1B,GAIA,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAAS,EAAM,OAAO,KAAK,EAE7B,YAAY,MACL,QACP,QAAQ,MACT,CAAA,CAEL,CAEA,SAAS,GAAuB,CAC9B,WACA,OACA,WACA,cACA,OACA,SAQe,CACf,OACE,EAAA,EAAA,KAAC,EAAA,SAAD,CACE,aAAY,EACF,WACV,SAAW,GACT,EAAS,EAAM,OAAO,KAAK,EAEhB,cACb,IAAK,GACL,OAAO,WACD,OACN,MAAO,GACA,OACR,CAAA,CAEL,CAEA,SAAS,EACP,EACA,EACA,EACA,EAII,CAAC,EACS,CACd,OACE,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,IAAK,EAAQ,IACb,IAAK,EAAQ,IACb,SAAW,GACT,GAAA,EAAA,EAAA,sBAAA,EAAA,EAAA,0BAE6B,EAAM,OAAO,KAAK,EAC3C,CACF,CACF,EAEW,cACb,YAAA,GACA,KAAM,EAAQ,MAAQ,EACtB,MAAO,OAAO,GAAU,SAAW,OAAO,CAAK,EAAI,GACnD,QAAQ,SACT,CAAA,CAEL,CAEA,SAAS,GACP,EACA,EACA,EACc,CAiBd,OAhBI,EAAM,OAAS,YAEf,EAAA,EAAA,KAAC,EAAA,eAAD,CACE,WAAW,aACX,WAAW,QACX,WAAA,GACA,SAAW,GACT,GAAA,EAAA,EAAA,2BAAmC,CAAS,CAAC,EAE/C,gBAAgB,OAChB,iBAAiB,OACjB,OAAA,EAAA,EAAA,qBAA2B,CAAK,CACjC,CAAA,GAKH,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,OAAO,aACP,SAAW,GACT,GAAA,EAAA,EAAA,uBAA+B,CAAS,CAAC,EAE3C,YAAY,OACZ,OAAA,EAAA,EAAA,qBAA2B,CAAK,CACjC,CAAA,CAEL,CAEA,SAAS,GAAwB,EAA4C,CAgE3E,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,QAAS,CAnBb,OAAS,GAA4D,CACnE,CACE,aAAyB,GAAU,EAAM,QAAQ,QAAU,EAC3D,KAAM,EAAA,UACN,SAAU,YACV,KAAM,OACN,YACE,EAA0B,CACxB,QAAS,EAAM,QAAQ,QAAQ,EAAG,IAAU,IAAU,EAAI,KAAK,CACjE,CAAC,EACH,QAAS,mBACX,CACF,EACA,MAAO,EAMM,EACT,QAAS,CA5Db,CACE,IAAK,QACL,OAAS,IACP,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAA0B,CACxB,QAAS,GAAkB,EAAM,QAAS,EAAI,MAAO,CACnD,MAAO,EAAM,OAAO,KACtB,CAAC,CACH,CAAC,EAEH,YAAY,QACZ,KAAK,MACL,MAAO,EAAI,MACX,QAAQ,MACT,CAAA,EAEH,MAAO,OACT,EACA,CACE,IAAK,QACL,OAAS,IACP,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,SAAW,GACT,EAA0B,CACxB,QAAS,GAAkB,EAAM,QAAS,EAAI,MAAO,CACnD,MAAO,EAAM,OAAO,KACtB,CAAC,CACH,CAAC,EAEH,YAAY,aACZ,KAAK,MACL,MAAO,EAAI,MACX,QAAQ,MACT,CAAA,EAEH,MAAO,OACT,CAuBa,EACT,WApE+B,EAAM,QAAQ,KAAK,EAAQ,KAAW,CACzE,QACA,IAAK,GAAG,EAAM,SAAS,GAAG,IAC1B,MAAO,EAAO,MACd,MAAO,EAAO,KAChB,EA+DkB,EACZ,WAAA,GACA,KAAK,KACN,CAAA,GACD,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,KAAM,EAAA,SACN,SAAS,UACT,YACE,EAA0B,CACxB,QAAS,CACP,GAAG,EAAM,QACT,GAAsB,EAAM,OAAO,CACrC,CACF,CAAC,EAEH,QAAQ,0BACT,MAEO,CAAA,CACL,CAAA,CACF,GAET,CAEA,SAAS,GACP,EACA,EACA,EACc,CACd,OACE,EAAA,EAAA,KAAC,MAAD,CACE,GAAI,EAAkB,eACtB,8BAA6B,EAAM,SACnC,IAAK,EAAkB,SACvB,MAAO,CACL,GAAG,GACH,GAAI,EAAa,GAA6B,KAC9C,GAAG,EAAkB,eAAe,KACtC,YAEA,EAAA,EAAA,KAAC,EAAA,SAAD,CAAA,SACG,GAAwB,EAAO,EAAmB,CAAU,CACrD,CAAA,CACP,CAAA,CAET,CAEA,SAAS,EACP,EACA,EACA,EACA,EACA,EAAO,GACO,CACd,OACE,EAAA,EAAA,KAAC,MAAD,CACE,MAAO,EAAO,GAAgC,aAE9C,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,EAAA,EAAD,CAAwB,WAAiB,QAAa,gBACnD,CACW,CAAA,CACX,CAAA,CACF,CAAA,CAET,CAEA,SAAS,GACP,EACA,EACA,EACc,CACd,OACE,EAAA,EAAA,MAAC,MAAD,CACE,GAAK,EAAkB,iBAAmB,CAAC,EAC3C,aAAW,SACX,MAAO,GACP,MAAM,gBAJR,EAME,EAAA,EAAA,KAAC,OAAD,CACE,aAAW,OACX,KAAK,MACL,MAAO,GACP,MAAM,iBAEN,EAAA,EAAA,KAAC,EAAA,KAAD,CAAM,KAAM,EAAA,oBAAqB,KAAM,EAAK,CAAA,CACxC,CAAA,GACN,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,MAAC,EAAA,WAAD,CAAY,UAAU,OAAO,SAAA,GAAS,QAAQ,yBAA9C,CACG,EAAM,MACN,EAAM,UACL,EAAA,EAAA,KAAC,MAAD,CAAK,aAAW,KAAK,MAAO,YAAyB,GAEhD,CAAA,EACH,IACM,KACZ,EAAA,EAAA,MAAC,EAAA,WAAD,CACE,MAAM,eACN,UAAU,OACV,SAAA,GACA,QAAQ,mBAJV,CAMG,GAAmB,EAAM,IAAI,EAAE,KAC/B,EAAM,SAAW,MAAQ,MAAM,KAAG,EAAM,QAC/B,GACT,KACL,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,QAAS,EAAQ,EAAM,SACvB,SAAU,GAAU,EACpB,MAAM,KACN,SAAW,GACT,GAAoB,EAAM,SAAU,EAAM,OAAO,OAAO,CAE3D,CAAA,CACE,CAAA,GACL,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,EACV,KAAM,EAAA,SACN,SAAS,YACT,YAAqB,EAAoB,EAAM,QAAQ,EACvD,QACE,EAAM,WAAa,GAAe,SAC9B,eACA,sBAEP,MAEO,CAAA,GACR,EAAA,EAAA,KAAC,EAAA,OAAD,CACE,SAAU,GAAU,EACpB,KAAM,EAAA,UACN,SAAS,YACT,YAAqB,GAAkB,EAAM,QAAQ,EACrD,QAAQ,6BACT,MAEO,CAAA,CACL,GACF,GAET,CAEA,SAAS,IAAiC,CACxC,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,WAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,cAAK,MAE5B,CAAA,GACZ,EAAA,EAAA,KAAC,EAAA,EAAD,CACE,SAAU,GACF,SACE,WACV,MAAO,EACR,CAAA,CACE,GAET,CAEA,SAAS,IAAkC,CACzC,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,WAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,cAAK,MAE5B,CAAA,GACZ,EAAA,EAAA,KAAC,EAAA,MAAD,CACE,QAAS,GACT,WAAY,GACH,UACV,CAAA,CACE,GAET,CAEA,SAAS,IAAkC,CACzC,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,WAAZ,EACE,EAAA,EAAA,KAAC,EAAA,WAAD,CAAY,UAAU,KAAK,QAAQ,cAAK,QAE5B,CAAA,GACZ,EAAA,EAAA,MAAC,MAAD,CAAK,MAAO,YAAZ,CACG,GACC,cACA,cACA,EAAA,EAAA,KAAC,GAAD,CACE,SAAU,EACV,OAAO,QACP,KAAK,aACL,SAAU,GACV,YAAY,sBACZ,MAAO,EACR,CAAA,CACH,EACC,GACC,YACA,gBACA,EAAA,EAAA,KAAC,GAAD,CACE,SAAU,EACV,OAAO,QACP,KAAK,eACL,SAAU,GACV,YAAY,oBACZ,MAAO,EACR,CAAA,CACH,EACC,IACC,EAAA,EAAA,KAAC,EAAA,WAAD,CACE,MAAM,aACN,MAAO,GACP,QAAQ,gBAEP,EACS,CAAA,EACV,IACD,GACF,GAET,CAEA,SAAS,GACP,EACA,EACA,EACc,CACd,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,MAAD,CAAK,MAAO,aACV,EAAA,EAAA,KAAC,EAAA,EAAD,CAAc,SAAU,EAAe,QAAa,gBACjD,CACW,CAAA,CACX,CAAA,CACF,CAAA,CAET,CACF,CAEA,SAAS,GAAmB,EAAyB,CACnD,OACE,GAAmB,KAAM,GAAW,EAAO,OAAS,CAAI,GAAG,OAAS,CAExE,CAEA,SAAS,GAAkB,EAAqC,CAC9D,MAAO,GAAQ,EAAM,aAAe,EAAM,cAAgB,EAAM,aAClE,CAEA,SAAS,GAAiC,EAGxC,CACA,MAAO,CACL,GAAI,EAAM,SACV,KAAM,EAAM,KACd,CACF,CAEA,SAAS,GACP,EAC8B,CAC9B,OAAO,EAAM,OAAS,QAAU,EAAM,OAAS,UACjD,CAEA,SAAS,EACP,EACQ,CACR,OAAO,OAAO,GAAU,SAAW,EAAQ,EAC7C,CAEA,SAAS,GAAgB,EAA8C,CACrE,IAAM,EAAS,EACZ,MAAM,QAAQ,EACd,IAAK,GAAS,EAAK,KAAK,CAAC,EACzB,OAAO,OAAO,EAEjB,OAAO,EAAO,OAAS,EAAS,IAAA,EAClC,CAEA,SAAS,GAAoB,EAA8C,CACzE,OAAO,GAAO,KAAK;CAAI,GAAK,EAC9B,CAEA,SAAS,EAAc,EAAwB,CAC7C,OAAO,KAAK,UAAU,EAAO,KAAM,CAAC,CACtC,CAEA,SAAS,GACP,EACA,EACA,EAC4B,CAC5B,OAAO,EAAQ,KAAK,EAAQ,IAC1B,IAAU,EAAc,CAAE,GAAG,EAAQ,GAAG,CAAM,EAAI,CACpD,CACF,CAEA,SAAS,GACP,EACiB,CACjB,IAAM,EAAY,EAAQ,OAAS,EAEnC,MAAO,CACL,MAAO,MAAM,IACb,MAAO,EAAoB,EAAS,CAAS,CAC/C,CACF,CAEA,SAAS,EACP,EACA,EACQ,CACR,IAAM,EAAQ,UAAU,IAExB,OAAO,EAAQ,KAAM,GAAW,EAAO,QAAU,CAAK,EAClD,EAAoB,EAAS,EAAQ,CAAC,EACtC,CACN,CAEA,SAAS,EACP,EACA,EACiB,CACjB,MAAO,CACL,WAAY,EAAc,CAAM,EAChC,aAAc,EAAc,CAAQ,CACtC,CACF,CAEA,SAAS,GACP,EACA,EACoC,CACpC,OACG,EACG,EAAS,KAAM,GAAY,EAAQ,KAAO,CAAgB,EAC1D,OACJ,EAAS,KAAM,GAAY,EAAQ,SAAW,WAAW,GACzD,IAEJ,CAEA,SAAS,GAAsB,CAC7B,oBACA,yBACA,yBACA,iBAMS,CAaT,MAAO,GAZW,EAAoB,SAAW,UAY7B,KAXA,EAAuB,CACzC,oBACA,yBACA,eACF,CAOyB,EAAY,KANd,EACnB,SAAS,EAAuB,QAAQ,GAAG,EAAA,EACzC,EAAuB,WACzB,IACA,aAGN,CAEA,SAAS,EAAuB,CAC9B,oBACA,yBACA,iBAKS,CAeT,OAdI,EACK,EACH,cAAc,EAAc,UAC5B,SAGF,GAA0B,EACrB,YAAY,EAAc,UAG/B,EACK,aAAa,EAAc,UAG7B,UACT,CAEA,SAAS,GACP,EACA,EACA,EACS,CACT,IAAM,EAAa,EAAM,GAEzB,GAAI,CAAC,GAAc,IAAgB,EACjC,MAAO,CAAC,GAAG,CAAK,EAGlB,IAAM,EAAiB,EAAM,QAAQ,EAAG,IAAU,IAAU,CAAW,EAEvE,MAAO,CACL,GAAG,EAAe,MAAM,EAAG,CAAgB,EAC3C,EACA,GAAG,EAAe,MAAM,CAAgB,CAC1C,CACF,CAEA,SAAS,GAAuB,CAC9B,UAGe,CASf,OARI,IAAW,aACN,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,aAAe,CAAA,EAGzD,IAAW,YACN,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,KAAK,MAAM,KAAK,MAAM,QAAQ,cAAgB,CAAA,GAGvD,EAAA,EAAA,KAAC,EAAA,MAAD,CAAO,KAAK,MAAM,KAAK,KAAK,QAAQ,aAAe,CAAA,CAC5D,CAEA,SAAS,EAAiB,EAAwB,CAChD,OAAO,aAAiB,MAAQ,EAAM,QAAU,QAClD"}
|