@rytass/bpm-core-react 0.20.1 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/README.md +1 -1
- package/dist/approval-instance-list-page.css +1 -1
- package/dist/chunks/{FormBuilderView-CFRiw04B.js → FormBuilderView-6KdApi-D.js} +667 -584
- package/dist/chunks/FormBuilderView-6KdApi-D.js.map +1 -0
- package/dist/chunks/FormBuilderView-CGKkuVFi.cjs +4 -0
- package/dist/chunks/FormBuilderView-CGKkuVFi.cjs.map +1 -0
- package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs → FormRendererView-B-xycC9S.cjs} +3 -3
- package/dist/chunks/{FormRendererView-lYSaR8CQ.cjs.map → FormRendererView-B-xycC9S.cjs.map} +1 -1
- package/dist/chunks/{FormRendererView-GfbVWEGa.js → FormRendererView-BcQKUi1A.js} +238 -238
- package/dist/chunks/{FormRendererView-GfbVWEGa.js.map → FormRendererView-BcQKUi1A.js.map} +1 -1
- package/dist/chunks/approval-instance-list-page-BI5fIXc-.js +724 -0
- package/dist/chunks/approval-instance-list-page-BI5fIXc-.js.map +1 -0
- package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs +2 -0
- package/dist/chunks/approval-instance-list-page-Cv5I1YPX.cjs.map +1 -0
- package/dist/chunks/{categories-DQUtVEiV.cjs → categories-CyyqG6wG.cjs} +2 -2
- package/dist/chunks/{categories-DQUtVEiV.cjs.map → categories-CyyqG6wG.cjs.map} +1 -1
- package/dist/chunks/{categories-BAdxjNSA.js → categories-f7E-RJEc.js} +9 -9
- package/dist/chunks/{categories-BAdxjNSA.js.map → categories-f7E-RJEc.js.map} +1 -1
- package/dist/chunks/{compose-egQlRjuZ.js → compose-DFuLPmOA.js} +5 -5
- package/dist/chunks/{compose-egQlRjuZ.js.map → compose-DFuLPmOA.js.map} +1 -1
- package/dist/chunks/compose-DK3ocWwG.cjs +2 -0
- package/dist/chunks/compose-DK3ocWwG.cjs.map +1 -0
- package/dist/chunks/{delegations-CVmtpkRn.cjs → delegations-ClRCwD1I.cjs} +2 -2
- package/dist/chunks/{delegations-CVmtpkRn.cjs.map → delegations-ClRCwD1I.cjs.map} +1 -1
- package/dist/chunks/{delegations-9-yvWWws.js → delegations-CqND-Qtz.js} +5 -5
- package/dist/chunks/{delegations-9-yvWWws.js.map → delegations-CqND-Qtz.js.map} +1 -1
- package/dist/chunks/{delegations-CrfjsH94.cjs → delegations-D43VDSz1.cjs} +2 -2
- package/dist/chunks/{delegations-CrfjsH94.cjs.map → delegations-D43VDSz1.cjs.map} +1 -1
- package/dist/chunks/{delegations-CxnNvTCc.js → delegations-zisffLwk.js} +5 -5
- package/dist/chunks/{delegations-CxnNvTCc.js.map → delegations-zisffLwk.js.map} +1 -1
- package/dist/chunks/designer-CAUWEKJ4.cjs +69 -0
- package/dist/chunks/designer-CAUWEKJ4.cjs.map +1 -0
- package/dist/chunks/{designer-CZDlQ9Nf.js → designer-CCy5EbOe.js} +2380 -1786
- package/dist/chunks/designer-CCy5EbOe.js.map +1 -0
- package/dist/chunks/detail-C5KrUC7s.cjs +5 -0
- package/dist/chunks/detail-C5KrUC7s.cjs.map +1 -0
- package/dist/chunks/{detail-ByZV1XaI.js → detail-Dnc4PPWO.js} +804 -777
- package/dist/chunks/detail-Dnc4PPWO.js.map +1 -0
- package/dist/chunks/instance-error-message-BEM4O_Kj.js +208 -0
- package/dist/chunks/instance-error-message-BEM4O_Kj.js.map +1 -0
- package/dist/chunks/instance-error-message-BpCLCOjp.cjs +2 -0
- package/dist/chunks/instance-error-message-BpCLCOjp.cjs.map +1 -0
- package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs +2 -0
- package/dist/chunks/organization-time-zone-provider-B7CXQril.cjs.map +1 -0
- package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js +42 -0
- package/dist/chunks/organization-time-zone-provider-DNL8yo4-.js.map +1 -0
- package/dist/chunks/{providers-BbCs23sk.js → providers-CQWekD7_.js} +197 -196
- package/dist/chunks/providers-CQWekD7_.js.map +1 -0
- package/dist/chunks/providers-VUOh6i0i.cjs +2 -0
- package/dist/chunks/providers-VUOh6i0i.cjs.map +1 -0
- package/dist/components/approval-instance-field-filter-controls.d.cts +12 -0
- package/dist/components/approval-instance-field-filter-controls.d.ts +12 -0
- package/dist/components/approval-instance-field-filters.d.cts +86 -0
- package/dist/components/approval-instance-field-filters.d.ts +86 -0
- package/dist/components/approval-instance-list-page.d.cts +4 -0
- package/dist/components/approval-instance-list-page.d.ts +4 -0
- package/dist/components/notification-drawer-options.d.cts +18 -0
- package/dist/components/notification-drawer-options.d.ts +18 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +23 -23
- package/dist/index.js.map +1 -1
- package/dist/lib/organization-time-zone-provider.d.cts +20 -0
- package/dist/lib/organization-time-zone-provider.d.ts +20 -0
- package/dist/lib/organization-time-zone.d.cts +8 -0
- package/dist/lib/organization-time-zone.d.ts +8 -0
- package/dist/lib/providers.d.cts +10 -1
- package/dist/lib/providers.d.ts +10 -1
- package/dist/next/BPMNextProviders.d.cts +8 -1
- package/dist/next/BPMNextProviders.d.ts +8 -1
- package/dist/next/index.cjs +1 -1
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +12 -11
- package/dist/next/index.js.map +1 -1
- package/dist/next/workflow-chat-route.cjs +2 -2
- package/dist/next/workflow-chat-route.cjs.map +1 -1
- package/dist/next/workflow-chat-route.js +13 -13
- package/dist/pages/admin/delegations/index.cjs +1 -1
- package/dist/pages/admin/delegations/index.js +1 -1
- package/dist/pages/delegations/index.cjs +1 -1
- package/dist/pages/delegations/index.js +1 -1
- package/dist/pages/instances/detail/index.cjs +1 -1
- package/dist/pages/instances/detail/index.js +1 -1
- package/dist/pages/templates/categories/index.cjs +1 -1
- package/dist/pages/templates/categories/index.js +1 -1
- package/dist/pages/templates/compose/index.cjs +1 -1
- package/dist/pages/templates/compose/index.js +1 -1
- package/dist/pages/templates/designer/index.cjs +1 -1
- package/dist/pages/templates/designer/index.js +1 -1
- package/dist/views/admin/delegations/index.cjs +1 -1
- package/dist/views/admin/delegations/index.js +1 -1
- package/dist/views/admin/index.cjs +1 -1
- package/dist/views/admin/index.js +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
- package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
- package/dist/views/admin/webhook-endpoints/index.js +60 -60
- package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
- package/dist/views/cc/index.cjs +1 -1
- package/dist/views/cc/index.js +1 -1
- package/dist/views/delegations/index.cjs +1 -1
- package/dist/views/delegations/index.js +1 -1
- package/dist/views/forms/builder/FormBuilderView.d.cts +8 -1
- package/dist/views/forms/builder/FormBuilderView.d.ts +8 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/forms/renderer/index.cjs +1 -1
- package/dist/views/forms/renderer/index.js +1 -1
- package/dist/views/instances/approver-filled-form.d.cts +8 -5
- package/dist/views/instances/approver-filled-form.d.ts +8 -5
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.cts +2 -1
- package/dist/views/instances/detail/sections/InstanceTasksSection.d.ts +2 -1
- package/dist/views/instances/detail/sections/shared.d.cts +0 -1
- package/dist/views/instances/detail/sections/shared.d.ts +0 -1
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +8 -8
- package/dist/views/instances/new/index.js.map +1 -1
- package/dist/views/search/index.cjs +1 -1
- package/dist/views/search/index.js +1 -1
- package/dist/views/sent/index.cjs +1 -1
- package/dist/views/sent/index.js +1 -1
- package/dist/views/templates/categories/index.cjs +1 -1
- package/dist/views/templates/categories/index.js +1 -1
- package/dist/views/templates/compose/index.cjs +1 -1
- package/dist/views/templates/compose/index.js +1 -1
- package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.cts +2 -0
- package/dist/views/templates/designer/NotifyWebhookTargetsEditor.d.ts +2 -0
- package/dist/views/templates/designer/approver-resolver-model.d.cts +105 -1
- package/dist/views/templates/designer/approver-resolver-model.d.ts +105 -1
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +5 -0
- package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +5 -0
- package/dist/views/templates/designer/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.cts +44 -1
- package/dist/views/templates/designer/node-actor-resolver-options.d.ts +44 -1
- package/dist/views/templates/designer/notify-recipient-options.d.cts +81 -0
- package/dist/views/templates/designer/notify-recipient-options.d.ts +81 -0
- package/dist/views/templates/designer/position-level-options.d.cts +3 -1
- package/dist/views/templates/designer/position-level-options.d.ts +3 -1
- package/dist/views/templates/designer/position-scope.d.cts +51 -0
- package/dist/views/templates/designer/position-scope.d.ts +51 -0
- package/dist/views/templates/index.cjs +1 -1
- package/dist/views/templates/index.cjs.map +1 -1
- package/dist/views/templates/index.js +7 -7
- package/package.json +3 -3
- package/dist/chunks/FormBuilderView-CFRiw04B.js.map +0 -1
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs +0 -3
- package/dist/chunks/FormBuilderView-CpUgbSbt.cjs.map +0 -1
- package/dist/chunks/approval-instance-list-page-BnI4t5mD.js +0 -279
- package/dist/chunks/approval-instance-list-page-BnI4t5mD.js.map +0 -1
- package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs +0 -2
- package/dist/chunks/approval-instance-list-page-fqvmkBlg.cjs.map +0 -1
- package/dist/chunks/compose-Bb5bUVFd.cjs +0 -2
- package/dist/chunks/compose-Bb5bUVFd.cjs.map +0 -1
- package/dist/chunks/designer-CX9bhYJS.cjs +0 -69
- package/dist/chunks/designer-CX9bhYJS.cjs.map +0 -1
- package/dist/chunks/designer-CZDlQ9Nf.js.map +0 -1
- package/dist/chunks/detail-ByZV1XaI.js.map +0 -1
- package/dist/chunks/detail-ChseSF55.cjs +0 -5
- package/dist/chunks/detail-ChseSF55.cjs.map +0 -1
- package/dist/chunks/instance-error-message-DTARGbGo.cjs +0 -2
- package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +0 -1
- package/dist/chunks/instance-error-message-q6gy5evy.js +0 -120
- package/dist/chunks/instance-error-message-q6gy5evy.js.map +0 -1
- package/dist/chunks/language-provider-Bdnx3Gxl.cjs +0 -2
- package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +0 -1
- package/dist/chunks/language-provider-phkWOapf.js +0 -17
- package/dist/chunks/language-provider-phkWOapf.js.map +0 -1
- package/dist/chunks/providers-BbCs23sk.js.map +0 -1
- package/dist/chunks/providers-D_KAgOOu.cjs +0 -2
- package/dist/chunks/providers-D_KAgOOu.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegations-CrfjsH94.cjs","names":["FormFieldLayout","useAuth","useState","useRef","useCallback","listDelegationRulesPage","searchMembers","useMemo","Typography","formatDateTime","revokeDelegationRule","listApprovalTemplates","createDelegationRule","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","Select","Tab","TabItem","Table","Modal","BPMFormField","AutoComplete","DateTimePicker","Tooltip","formatMemberLabel","Badge","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","require_format_member_label","require_auth_provider","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","delegations_module_default","DELEGATION_MODAL_FIELD_LAYOUT","DELEGATION_PAGE_SIZE_OPTIONS","DELEGATION_STATUS_TABS","SCOPE_FILTER_OPTIONS","SCOPE_OPTIONS","DelegationsView","currentMemberId","member","agentMember","setAgentMember","endAt","setEndAt","error","setError","loading","setLoading","memberLoading","setMemberLoading","memberOptions","setMemberOptions","modalOpen","setModalOpen","rulePage","setRulePage","rulePageSize","setRulePageSize","ruleStatus","setRuleStatus","ruleTotalCount","setRuleTotalCount","rules","setRules","saving","setSaving","scopeFilterType","setScopeFilterType","scopeTemplates","setScopeTemplates","scopeType","setScopeType","startAt","setStartAt","templateLoading","setTemplateLoading","templateOptions","setTemplateOptions","refreshRequestIdRef","refreshRules","requestId","rulePageResult","members","readMemberOption","requestError","readErrorMessage","membersById","option","rows","rule","readScopeLabel","selectedScopeType","columns","MemberNameWithEmailTooltip","record","DelegationStatusBadge","handleRevoke","tableActions","handleSearchMembers","searchText","handleSearchTemplates","nextOptions","readTemplateOption","mergeTemplateOptions","selectedOptions","filterTemplateOptions","openCreateModal","closeCreateModal","handleCreate","isInvalidDelegationDateRange","template","readScopeFilterOption","readDelegationStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","MemberAutoCompleteField","readScopeOptionFromValue","selectedTemplates","readTemplateOptionsFromValue","nextTemplates","currentOptions","open","formatDelegationDateTimePickerValue","nextValue","readDelegationDateTimePickerValue","onChange","readMemberOptionFromValue","readUniqueMemberOption","options","onSearch","email","tooltipProps","name","isRecord","value","displayName","id","normalizedSearchText","matches","item","availableOptions","currentOption","isSelectableDelegationScopeType","status","date","parseDelegationDateTimeValue","formatDateParts","padDatePart","startDate","endDate","parsedDate","datePart","timePart","year","month","day","hour","minute"],"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 useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Badge,\n Button,\n DateTimePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\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 { formatMemberLabel } from '../../lib/format-member-label';\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 function DelegationsView(): 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 const refreshRequestIdRef = useRef(0);\n\n const refreshRules = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n\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 if (requestId === refreshRequestIdRef.current) {\n setRules(rulePageResult.rules);\n setRuleTotalCount(rulePageResult.totalCount);\n setMemberOptions(members.map(readMemberOption));\n }\n } catch (requestError: unknown) {\n if (requestId === refreshRequestIdRef.current) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (requestId === refreshRequestIdRef.current) {\n setLoading(false);\n }\n }\n }, [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 // Phase 23 P4: new rules are written in cel-v2; stored rules keep\n // their dialect.\n scopeConditionDialect: 'cel-v2',\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 <>\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 </>\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 {({ ref, ...tooltipProps }): ReactElement => (\n // Spread the whole payload, as `TooltipProps` asks: picking only the\n // mouse handlers drops `aria-describedby`, so assistive tech never\n // learns the open tooltip describes this name.\n <span\n {...tooltipProps}\n className={styles.memberNameWithTooltip}\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: formatMemberLabel(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\n ? `條件(${rule.scopeConditionDialect}):${rule.scopeConditionCel}`\n : '條件式';\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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"}
|
|
1
|
+
{"version":3,"file":"delegations-D43VDSz1.cjs","names":["FormFieldLayout","useAuth","useState","useRef","useCallback","listDelegationRulesPage","searchMembers","useMemo","Typography","formatDateTime","revokeDelegationRule","listApprovalTemplates","createDelegationRule","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","styles","FilterLine","Filter","FormField","Select","Tab","TabItem","Table","Modal","BPMFormField","AutoComplete","DateTimePicker","Tooltip","formatMemberLabel","Badge","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","require_format_member_label","require_auth_provider","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_core_form","_mezzanine_ui_react_ContentHeader","_rytass_bpm_core_client_template","_mezzanine_ui_icons","delegations_module_default","DELEGATION_MODAL_FIELD_LAYOUT","DELEGATION_PAGE_SIZE_OPTIONS","DELEGATION_STATUS_TABS","SCOPE_FILTER_OPTIONS","SCOPE_OPTIONS","DelegationsView","currentMemberId","member","agentMember","setAgentMember","endAt","setEndAt","error","setError","loading","setLoading","memberLoading","setMemberLoading","memberOptions","setMemberOptions","modalOpen","setModalOpen","rulePage","setRulePage","rulePageSize","setRulePageSize","ruleStatus","setRuleStatus","ruleTotalCount","setRuleTotalCount","rules","setRules","saving","setSaving","scopeFilterType","setScopeFilterType","scopeTemplates","setScopeTemplates","scopeType","setScopeType","startAt","setStartAt","templateLoading","setTemplateLoading","templateOptions","setTemplateOptions","refreshRequestIdRef","refreshRules","requestId","rulePageResult","members","readMemberOption","requestError","readErrorMessage","membersById","option","rows","rule","readScopeLabel","selectedScopeType","columns","MemberNameWithEmailTooltip","record","DelegationStatusBadge","handleRevoke","tableActions","handleSearchMembers","searchText","handleSearchTemplates","nextOptions","readTemplateOption","mergeTemplateOptions","selectedOptions","filterTemplateOptions","openCreateModal","closeCreateModal","handleCreate","isInvalidDelegationDateRange","template","readScopeFilterOption","readDelegationStatusTabKey","activeKey","statusTab","page","pageSize","from","to","total","MemberAutoCompleteField","readScopeOptionFromValue","selectedTemplates","readTemplateOptionsFromValue","nextTemplates","currentOptions","open","formatDelegationDateTimePickerValue","nextValue","readDelegationDateTimePickerValue","onChange","readMemberOptionFromValue","readUniqueMemberOption","options","onSearch","email","tooltipProps","name","isRecord","value","displayName","id","normalizedSearchText","matches","item","availableOptions","currentOption","isSelectableDelegationScopeType","status","date","parseDelegationDateTimeValue","formatDateParts","padDatePart","startDate","endDate","parsedDate","datePart","timePart","year","month","day","hour","minute"],"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 useRef,\n useState,\n} from 'react';\nimport {\n AutoComplete,\n Badge,\n Button,\n DateTimePicker,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\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 { formatMemberLabel } from '../../lib/format-member-label';\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 function DelegationsView(): 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 const refreshRequestIdRef = useRef(0);\n\n const refreshRules = useCallback(async (): Promise<void> => {\n const requestId = refreshRequestIdRef.current + 1;\n refreshRequestIdRef.current = requestId;\n\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 if (requestId === refreshRequestIdRef.current) {\n setRules(rulePageResult.rules);\n setRuleTotalCount(rulePageResult.totalCount);\n setMemberOptions(members.map(readMemberOption));\n }\n } catch (requestError: unknown) {\n if (requestId === refreshRequestIdRef.current) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (requestId === refreshRequestIdRef.current) {\n setLoading(false);\n }\n }\n }, [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 // Phase 23 P4: new rules are written in cel-v2; stored rules keep\n // their dialect.\n scopeConditionDialect: 'cel-v2',\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 <>\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 </>\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 {({ ref, ...tooltipProps }): ReactElement => (\n // Spread the whole payload, as `TooltipProps` asks: picking only the\n // mouse handlers drops `aria-describedby`, so assistive tech never\n // learns the open tooltip describes this name.\n <span\n {...tooltipProps}\n className={styles.memberNameWithTooltip}\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: formatMemberLabel(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\n ? `條件(${rule.scopeConditionDialect}):${rule.scopeConditionCel}`\n : '條件式';\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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"}
|
|
@@ -9,8 +9,8 @@ import { Fragment as de, jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
|
9
9
|
import { createDelegationRule as fe, listDelegationRulesPage as pe, revokeDelegationRule as me, searchMembers as he } from "@rytass/bpm-core-client/workflow";
|
|
10
10
|
import { FormFieldLayout as v } from "@mezzanine-ui/core/form";
|
|
11
11
|
import ge from "@mezzanine-ui/react/ContentHeader";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
12
|
+
import { listApprovalTemplates as _e } from "@rytass/bpm-core-client/template";
|
|
13
|
+
import { PlusIcon as ve } from "@mezzanine-ui/icons";
|
|
14
14
|
import '../delegations.css';var y = {
|
|
15
15
|
delegationModalFields: "bpm_delegationModalFields_gUlCQ",
|
|
16
16
|
delegationFilterArea: "bpm_delegationFilterArea_QDZkw",
|
|
@@ -187,7 +187,7 @@ function C() {
|
|
|
187
187
|
async function $(e, t = W) {
|
|
188
188
|
$e(!0);
|
|
189
189
|
try {
|
|
190
|
-
let n = (await
|
|
190
|
+
let n = (await _e()).map(Ce);
|
|
191
191
|
J(Ee(t, Te(n, e)));
|
|
192
192
|
} catch (e) {
|
|
193
193
|
D(N(e));
|
|
@@ -235,7 +235,7 @@ function C() {
|
|
|
235
235
|
description: "設定簽核代理規則,讓符合範圍的待簽任務自動改派給代理人。",
|
|
236
236
|
title: "代理設定",
|
|
237
237
|
children: /* @__PURE__ */ g(ee, {
|
|
238
|
-
icon:
|
|
238
|
+
icon: ve,
|
|
239
239
|
iconType: "leading",
|
|
240
240
|
onClick: at,
|
|
241
241
|
variant: "base-primary",
|
|
@@ -633,4 +633,4 @@ function P(e) {
|
|
|
633
633
|
}
|
|
634
634
|
export { C as t };
|
|
635
635
|
|
|
636
|
-
//# sourceMappingURL=delegations-
|
|
636
|
+
//# sourceMappingURL=delegations-zisffLwk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegations-CxnNvTCc.js","names":["_Fragment","styles","BPMFormField","formatMemberLabel","Fragment$1","ContentHeader","delegations_module_default","DELEGATION_MODAL_FIELD_LAYOUT","FormFieldLayout","DELEGATION_PAGE_SIZE_OPTIONS","DELEGATION_STATUS_TABS","SCOPE_OPTIONS","SCOPE_FILTER_OPTIONS","AdminDelegationsView","useAuth","currentMemberId","member","agentMember","setAgentMember","useState","endAt","setEndAt","error","setError","loading","setLoading","memberLoading","setMemberLoading","memberOptions","setMemberOptions","principalFilterMember","setPrincipalFilterMember","agentFilterMember","setAgentFilterMember","modalOpen","setModalOpen","principalMember","setPrincipalMember","priority","setPriority","rulePage","setRulePage","rulePageSize","setRulePageSize","ruleStatus","setRuleStatus","ruleTotalCount","setRuleTotalCount","rules","setRules","saving","setSaving","scopeTemplates","setScopeTemplates","scopeFilterType","setScopeFilterType","scopeType","setScopeType","startAt","setStartAt","templateLoading","setTemplateLoading","templateOptions","setTemplateOptions","refreshRules","useCallback","rulePageResult","members","listDelegationRulesPage","searchMembers","readMemberOption","requestError","readErrorMessage","membersById","useMemo","option","rows","rule","readScopeLabel","selectedScopeType","columns","MemberNameWithEmailTooltip","record","DelegationStatusBadge","Typography","formatDateTime","handleRevoke","revokeDelegationRule","tableActions","handleSearchMembers","searchText","handleSearchTemplates","nextOptions","listApprovalTemplates","readTemplateOption","mergeTemplateOptions","selectedOptions","filterTemplateOptions","openCreateModal","closeCreateModal","handleCreate","isInvalidDelegationDateRange","createDelegationRule","template","PageHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","FilterLine","Filter","MemberAutoCompleteField","FormField","Select","readScopeFilterOption","Tab","readDelegationStatusTabKey","activeKey","TabItem","statusTab","Table","page","pageSize","from","to","total","Modal","readScopeOptionFromValue","AutoComplete","selectedTemplates","readTemplateOptionsFromValue","nextTemplates","currentOptions","open","Input","event","DateTimePicker","formatDelegationDateTimePickerValue","nextValue","readDelegationDateTimePickerValue","autoComplete","onChange","readMemberOptionFromValue","readUniqueMemberOption","options","onSearch","hideLabel","label","isRecord","value","id","name","email","displayName","Tooltip","tooltipProps","normalizedSearchText","matches","item","availableOptions","currentOption","isSelectableDelegationScopeType","status","Badge","date","parseDelegationDateTimeValue","formatDateParts","padDatePart","startDate","endDate","parsedDate","datePart","timePart","year","month","day","hour","minute"],"sources":["../../src/views/admin/delegations/delegations.module.scss","../../src/views/admin/delegations/AdminDelegationsView.tsx"],"sourcesContent":[".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-auto-complete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n\n :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.delegationFilterArea {\n width: calc(100vw - 272px);\n\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-filter-area__row) {\n align-items: flex-start;\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 :global(.mzn-auto-complete) {\n width: 100%;\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 ChangeEvent,\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 Input,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport styles from './delegations.module.scss';\nimport { formatDateTime } from '../../../lib/format-date-time';\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 { formatMemberLabel } from '../../../lib/format-member-label';\n\ntype MemberOption = Readonly<{\n displayName: string;\n email: string | null;\n id: string;\n name: string;\n}>;\n\ntype TemplateOption = Readonly<{\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 DelegationRuleRow = Readonly<\n Record<string, unknown> &\n DelegationRuleRecord & {\n agentEmail: string | null;\n agentName: string;\n key: string;\n principalEmail: string | null;\n principalName: 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];\n\ntype DelegationStatusTabKey = 'ALL' | DelegationRuleStatus;\n\nconst SCOPE_OPTIONS: readonly ScopeOption[] = [\n { id: 'ALL', name: '全部簽核' },\n { id: 'TEMPLATE_LIST', name: '指定模板' },\n];\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];\n\n\nexport function AdminDelegationsView(): 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 [principalFilterMember, setPrincipalFilterMember] =\n useState<MemberOption | null>(null);\n const [agentFilterMember, setAgentFilterMember] =\n useState<MemberOption | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [principalMember, setPrincipalMember] = useState<MemberOption | null>(\n null,\n );\n const [priority, setPriority] = useState('100');\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 [scopeTemplates, setScopeTemplates] = useState<\n readonly TemplateOption[]\n >([]);\n const [scopeFilterType, setScopeFilterType] = useState<ScopeFilterOption>(\n SCOPE_FILTER_OPTIONS[0],\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 setLoading(true);\n setError(null);\n\n try {\n const [rulePageResult, members] = await Promise.all([\n listDelegationRulesPage({\n agentMemberId: agentFilterMember?.id ?? null,\n includeInactive: true,\n page: rulePage,\n pageSize: rulePageSize,\n principalMemberId: principalFilterMember?.id ?? null,\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 }, [\n agentFilterMember,\n principalFilterMember,\n rulePage,\n rulePageSize,\n ruleStatus,\n scopeFilterType,\n ]);\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 principalEmail: membersById.get(rule.principalMemberId)?.email ?? null,\n principalName:\n membersById.get(rule.principalMemberId)?.displayName ??\n rule.principalMemberId,\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: 'principal',\n render: (record: DelegationRuleRow): ReactElement => (\n <MemberNameWithEmailTooltip\n email={record.principalEmail}\n name={record.principalName}\n />\n ),\n title: '原簽核人',\n width: 220,\n },\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 { dataIndex: 'priority', key: 'priority', title: '優先序', width: 100 },\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 setPrincipalMember(null);\n setPriority('100');\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 (!principalMember || !agentMember) {\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: principalMember.id,\n priority: Number(priority) || 100,\n requiresConfirmation: false,\n scopeConditionCel: null,\n // Phase 23 P4: new rules are written in cel-v2; stored rules keep\n // their dialect.\n scopeConditionDialect: 'cel-v2',\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 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 <>\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}>\n <FilterLine>\n <Filter span={2}>\n <MemberAutoCompleteField\n hideLabel\n label=\"原簽核人\"\n loading={memberLoading}\n name=\"principalFilterMemberId\"\n onChange={(option): void => {\n setPrincipalFilterMember(option);\n setRulePage(1);\n }}\n onSearch={handleSearchMembers}\n options={memberOptions}\n required={false}\n layout={FormFieldLayout.VERTICAL}\n size=\"sub\"\n value={principalFilterMember}\n />\n </Filter>\n <Filter span={2}>\n <MemberAutoCompleteField\n hideLabel\n label=\"代理人\"\n loading={memberLoading}\n name=\"agentFilterMemberId\"\n onChange={(option): void => {\n setAgentFilterMember(option);\n setRulePage(1);\n }}\n onSearch={handleSearchMembers}\n options={memberOptions}\n required={false}\n layout={FormFieldLayout.VERTICAL}\n size=\"sub\"\n value={agentFilterMember}\n />\n </Filter>\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: !principalMember || !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=\"principalMemberId\"\n onChange={setPrincipalMember}\n onSearch={handleSearchMembers}\n options={memberOptions}\n value={principalMember}\n />\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 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\n hintText=\"數字越大越優先。同一位被代理人同時命中多條規則時,採用優先序最高的那條;優先序相同時採用較早建立的。\"\n label=\"優先序\"\n name=\"priority\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setPriority(event.target.value)\n }\n value={priority}\n variant=\"base\"\n />\n </BPMFormField>\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 </>\n );\n}\n\nfunction MemberAutoCompleteField({\n hideLabel = false,\n label,\n layout = DELEGATION_MODAL_FIELD_LAYOUT,\n loading,\n name,\n onChange,\n onSearch,\n options,\n required = true,\n size,\n value,\n}: {\n readonly hideLabel?: boolean;\n readonly label: string;\n readonly layout?: FormFieldLayout;\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 required?: boolean;\n readonly size?: 'main' | 'sub';\n readonly value: MemberOption | null;\n}): ReactElement {\n const autoComplete = (\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={hideLabel ? label : '搜尋姓名或信箱'}\n searchDebounceTime={300}\n size={size}\n value={value}\n />\n );\n\n if (hideLabel) {\n return (\n <FormField fullWidth layout={layout} name={name}>\n {autoComplete}\n </FormField>\n );\n }\n\n return (\n <BPMFormField label={label} layout={layout} name={name} required={required}>\n {autoComplete}\n </BPMFormField>\n );\n}\n\nfunction readMemberOption(member: MemberProfileRecord): MemberOption {\n return {\n displayName: member.name,\n email: member.email,\n id: member.memberId,\n name: formatMemberLabel(member.name, member.email, 'dot'),\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const id = value.id;\n const name = value.name;\n const email = value.email;\n const displayName = value.displayName;\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 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 {({ ref, ...tooltipProps }): ReactElement => (\n // Spread the whole payload, as `TooltipProps` asks: picking only the\n // mouse handlers drops `aria-describedby`, so assistive tech never\n // learns the open tooltip describes this name.\n <span\n {...tooltipProps}\n className={styles.memberNameWithTooltip}\n ref={ref as RefCallback<HTMLSpanElement>}\n >\n {name}\n </span>\n )}\n </Tooltip>\n );\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 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 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 isSelectableDelegationScopeType(\n value: unknown,\n): value is ScopeOption['id'] {\n return value === 'ALL' || value === 'TEMPLATE_LIST';\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\n ? `條件(${rule.scopeConditionDialect}):${rule.scopeConditionCel}`\n : '條件式';\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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"}
|
|
1
|
+
{"version":3,"file":"delegations-zisffLwk.js","names":["_Fragment","styles","BPMFormField","formatMemberLabel","Fragment$1","ContentHeader","delegations_module_default","DELEGATION_MODAL_FIELD_LAYOUT","FormFieldLayout","DELEGATION_PAGE_SIZE_OPTIONS","DELEGATION_STATUS_TABS","SCOPE_OPTIONS","SCOPE_FILTER_OPTIONS","AdminDelegationsView","useAuth","currentMemberId","member","agentMember","setAgentMember","useState","endAt","setEndAt","error","setError","loading","setLoading","memberLoading","setMemberLoading","memberOptions","setMemberOptions","principalFilterMember","setPrincipalFilterMember","agentFilterMember","setAgentFilterMember","modalOpen","setModalOpen","principalMember","setPrincipalMember","priority","setPriority","rulePage","setRulePage","rulePageSize","setRulePageSize","ruleStatus","setRuleStatus","ruleTotalCount","setRuleTotalCount","rules","setRules","saving","setSaving","scopeTemplates","setScopeTemplates","scopeFilterType","setScopeFilterType","scopeType","setScopeType","startAt","setStartAt","templateLoading","setTemplateLoading","templateOptions","setTemplateOptions","refreshRules","useCallback","rulePageResult","members","listDelegationRulesPage","searchMembers","readMemberOption","requestError","readErrorMessage","membersById","useMemo","option","rows","rule","readScopeLabel","selectedScopeType","columns","MemberNameWithEmailTooltip","record","DelegationStatusBadge","Typography","formatDateTime","handleRevoke","revokeDelegationRule","tableActions","handleSearchMembers","searchText","handleSearchTemplates","nextOptions","listApprovalTemplates","readTemplateOption","mergeTemplateOptions","selectedOptions","filterTemplateOptions","openCreateModal","closeCreateModal","handleCreate","isInvalidDelegationDateRange","createDelegationRule","template","PageHeader","Button","PlusIcon","SectionGroup","Section","FilterArea","FilterLine","Filter","MemberAutoCompleteField","FormField","Select","readScopeFilterOption","Tab","readDelegationStatusTabKey","activeKey","TabItem","statusTab","Table","page","pageSize","from","to","total","Modal","readScopeOptionFromValue","AutoComplete","selectedTemplates","readTemplateOptionsFromValue","nextTemplates","currentOptions","open","Input","event","DateTimePicker","formatDelegationDateTimePickerValue","nextValue","readDelegationDateTimePickerValue","autoComplete","onChange","readMemberOptionFromValue","readUniqueMemberOption","options","onSearch","hideLabel","label","isRecord","value","id","name","email","displayName","Tooltip","tooltipProps","normalizedSearchText","matches","item","availableOptions","currentOption","isSelectableDelegationScopeType","status","Badge","date","parseDelegationDateTimeValue","formatDateParts","padDatePart","startDate","endDate","parsedDate","datePart","timePart","year","month","day","hour","minute"],"sources":["../../src/views/admin/delegations/delegations.module.scss","../../src/views/admin/delegations/AdminDelegationsView.tsx"],"sourcesContent":[".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-auto-complete) {\n width: 100%;\n min-width: 0;\n }\n\n :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-select),\n :global(.mzn-select-trigger),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n\n :global(.mzn-select-trigger__input) {\n width: 100%;\n min-width: 0 !important;\n text-overflow: ellipsis;\n }\n}\n\n.delegationFilterArea {\n width: calc(100vw - 272px);\n\n :global(.mzn-filter-area__actions) {\n display: none;\n }\n\n :global(.mzn-filter-area__row) {\n align-items: flex-start;\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 :global(.mzn-auto-complete) {\n width: 100%;\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 ChangeEvent,\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 Input,\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 type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport styles from './delegations.module.scss';\nimport { formatDateTime } from '../../../lib/format-date-time';\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 { formatMemberLabel } from '../../../lib/format-member-label';\n\ntype MemberOption = Readonly<{\n displayName: string;\n email: string | null;\n id: string;\n name: string;\n}>;\n\ntype TemplateOption = Readonly<{\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 DelegationRuleRow = Readonly<\n Record<string, unknown> &\n DelegationRuleRecord & {\n agentEmail: string | null;\n agentName: string;\n key: string;\n principalEmail: string | null;\n principalName: 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];\n\ntype DelegationStatusTabKey = 'ALL' | DelegationRuleStatus;\n\nconst SCOPE_OPTIONS: readonly ScopeOption[] = [\n { id: 'ALL', name: '全部簽核' },\n { id: 'TEMPLATE_LIST', name: '指定模板' },\n];\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];\n\n\nexport function AdminDelegationsView(): 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 [principalFilterMember, setPrincipalFilterMember] =\n useState<MemberOption | null>(null);\n const [agentFilterMember, setAgentFilterMember] =\n useState<MemberOption | null>(null);\n const [modalOpen, setModalOpen] = useState(false);\n const [principalMember, setPrincipalMember] = useState<MemberOption | null>(\n null,\n );\n const [priority, setPriority] = useState('100');\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 [scopeTemplates, setScopeTemplates] = useState<\n readonly TemplateOption[]\n >([]);\n const [scopeFilterType, setScopeFilterType] = useState<ScopeFilterOption>(\n SCOPE_FILTER_OPTIONS[0],\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 setLoading(true);\n setError(null);\n\n try {\n const [rulePageResult, members] = await Promise.all([\n listDelegationRulesPage({\n agentMemberId: agentFilterMember?.id ?? null,\n includeInactive: true,\n page: rulePage,\n pageSize: rulePageSize,\n principalMemberId: principalFilterMember?.id ?? null,\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 }, [\n agentFilterMember,\n principalFilterMember,\n rulePage,\n rulePageSize,\n ruleStatus,\n scopeFilterType,\n ]);\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 principalEmail: membersById.get(rule.principalMemberId)?.email ?? null,\n principalName:\n membersById.get(rule.principalMemberId)?.displayName ??\n rule.principalMemberId,\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: 'principal',\n render: (record: DelegationRuleRow): ReactElement => (\n <MemberNameWithEmailTooltip\n email={record.principalEmail}\n name={record.principalName}\n />\n ),\n title: '原簽核人',\n width: 220,\n },\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 { dataIndex: 'priority', key: 'priority', title: '優先序', width: 100 },\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 setPrincipalMember(null);\n setPriority('100');\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 (!principalMember || !agentMember) {\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: principalMember.id,\n priority: Number(priority) || 100,\n requiresConfirmation: false,\n scopeConditionCel: null,\n // Phase 23 P4: new rules are written in cel-v2; stored rules keep\n // their dialect.\n scopeConditionDialect: 'cel-v2',\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 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 <>\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}>\n <FilterLine>\n <Filter span={2}>\n <MemberAutoCompleteField\n hideLabel\n label=\"原簽核人\"\n loading={memberLoading}\n name=\"principalFilterMemberId\"\n onChange={(option): void => {\n setPrincipalFilterMember(option);\n setRulePage(1);\n }}\n onSearch={handleSearchMembers}\n options={memberOptions}\n required={false}\n layout={FormFieldLayout.VERTICAL}\n size=\"sub\"\n value={principalFilterMember}\n />\n </Filter>\n <Filter span={2}>\n <MemberAutoCompleteField\n hideLabel\n label=\"代理人\"\n loading={memberLoading}\n name=\"agentFilterMemberId\"\n onChange={(option): void => {\n setAgentFilterMember(option);\n setRulePage(1);\n }}\n onSearch={handleSearchMembers}\n options={memberOptions}\n required={false}\n layout={FormFieldLayout.VERTICAL}\n size=\"sub\"\n value={agentFilterMember}\n />\n </Filter>\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: !principalMember || !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=\"principalMemberId\"\n onChange={setPrincipalMember}\n onSearch={handleSearchMembers}\n options={memberOptions}\n value={principalMember}\n />\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 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\n hintText=\"數字越大越優先。同一位被代理人同時命中多條規則時,採用優先序最高的那條;優先序相同時採用較早建立的。\"\n label=\"優先序\"\n name=\"priority\"\n >\n <Input\n fullWidth\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setPriority(event.target.value)\n }\n value={priority}\n variant=\"base\"\n />\n </BPMFormField>\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 </>\n );\n}\n\nfunction MemberAutoCompleteField({\n hideLabel = false,\n label,\n layout = DELEGATION_MODAL_FIELD_LAYOUT,\n loading,\n name,\n onChange,\n onSearch,\n options,\n required = true,\n size,\n value,\n}: {\n readonly hideLabel?: boolean;\n readonly label: string;\n readonly layout?: FormFieldLayout;\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 required?: boolean;\n readonly size?: 'main' | 'sub';\n readonly value: MemberOption | null;\n}): ReactElement {\n const autoComplete = (\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={hideLabel ? label : '搜尋姓名或信箱'}\n searchDebounceTime={300}\n size={size}\n value={value}\n />\n );\n\n if (hideLabel) {\n return (\n <FormField fullWidth layout={layout} name={name}>\n {autoComplete}\n </FormField>\n );\n }\n\n return (\n <BPMFormField label={label} layout={layout} name={name} required={required}>\n {autoComplete}\n </BPMFormField>\n );\n}\n\nfunction readMemberOption(member: MemberProfileRecord): MemberOption {\n return {\n displayName: member.name,\n email: member.email,\n id: member.memberId,\n name: formatMemberLabel(member.name, member.email, 'dot'),\n };\n}\n\nfunction readMemberOptionFromValue(value: unknown): MemberOption | null {\n if (!isRecord(value)) {\n return null;\n }\n\n const id = value.id;\n const name = value.name;\n const email = value.email;\n const displayName = value.displayName;\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 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 {({ ref, ...tooltipProps }): ReactElement => (\n // Spread the whole payload, as `TooltipProps` asks: picking only the\n // mouse handlers drops `aria-describedby`, so assistive tech never\n // learns the open tooltip describes this name.\n <span\n {...tooltipProps}\n className={styles.memberNameWithTooltip}\n ref={ref as RefCallback<HTMLSpanElement>}\n >\n {name}\n </span>\n )}\n </Tooltip>\n );\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 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 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 isSelectableDelegationScopeType(\n value: unknown,\n): value is ScopeOption['id'] {\n return value === 'ALL' || value === 'TEMPLATE_LIST';\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\n ? `條件(${rule.scopeConditionDialect}):${rule.scopeConditionCel}`\n : '條件式';\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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"}
|