@rytass/bpm-core-react 0.17.8 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +8 -0
- package/dist/chunks/{FormBuilderView-ClLnQ1e_.js → FormBuilderView-BVKY1j_0.js} +504 -452
- package/dist/chunks/FormBuilderView-BVKY1j_0.js.map +1 -0
- package/dist/chunks/FormBuilderView-SrGltzFT.cjs +3 -0
- package/dist/chunks/FormBuilderView-SrGltzFT.cjs.map +1 -0
- package/dist/chunks/approver-filled-form-Dm3Iw7iw.cjs +2 -0
- package/dist/chunks/approver-filled-form-Dm3Iw7iw.cjs.map +1 -0
- package/dist/chunks/{approver-filled-form-DuQGPtNB.js → approver-filled-form-ZEwpmsHJ.js} +21 -8
- package/dist/chunks/approver-filled-form-ZEwpmsHJ.js.map +1 -0
- package/dist/chunks/{compose-jnvnnVfN.js → compose-B1GlrZW9.js} +3 -3
- package/dist/chunks/{compose-jnvnnVfN.js.map → compose-B1GlrZW9.js.map} +1 -1
- package/dist/chunks/{compose-Cock_B2Q.cjs → compose-DZk-SfHT.cjs} +2 -2
- package/dist/chunks/{compose-Cock_B2Q.cjs.map → compose-DZk-SfHT.cjs.map} +1 -1
- package/dist/chunks/{designer-B8Gvew_k.js → designer-BCLrjb4H.js} +886 -851
- package/dist/chunks/designer-BCLrjb4H.js.map +1 -0
- package/dist/chunks/designer-BYYxEN9L.cjs +65 -0
- package/dist/chunks/designer-BYYxEN9L.cjs.map +1 -0
- package/dist/chunks/{detail-D6X61pkg.js → detail-4F39ggBn.js} +883 -827
- package/dist/chunks/detail-4F39ggBn.js.map +1 -0
- package/dist/chunks/detail-BkMtA_0K.cjs +2 -0
- package/dist/chunks/detail-BkMtA_0K.cjs.map +1 -0
- package/dist/chunks/{orgs-Lg7tXv2u.js → orgs-8hje_l2n.js} +9 -4
- package/dist/chunks/orgs-8hje_l2n.js.map +1 -0
- package/dist/chunks/{orgs-C8usknWb.cjs → orgs-BeeDDWL1.cjs} +2 -2
- package/dist/chunks/orgs-BeeDDWL1.cjs.map +1 -0
- package/dist/chunks/users-O2L_M3BK.cjs +2 -0
- package/dist/chunks/users-O2L_M3BK.cjs.map +1 -0
- package/dist/chunks/{users-DRbuDYF1.js → users-Pl6hY5Y5.js} +160 -93
- package/dist/chunks/users-Pl6hY5Y5.js.map +1 -0
- package/dist/pages/admin/orgs/index.cjs +1 -1
- package/dist/pages/admin/orgs/index.js +1 -1
- package/dist/pages/admin/users/index.cjs +1 -1
- package/dist/pages/admin/users/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/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/index.cjs +1 -1
- package/dist/views/admin/index.js +2 -2
- package/dist/views/admin/orgs/index.cjs +1 -1
- package/dist/views/admin/orgs/index.js +1 -1
- package/dist/views/admin/users/index.cjs +1 -1
- package/dist/views/admin/users/index.js +1 -1
- package/dist/views/forms/builder/index.cjs +1 -1
- package/dist/views/forms/builder/index.js +1 -1
- package/dist/views/inbox/index.cjs +1 -1
- package/dist/views/inbox/index.cjs.map +1 -1
- package/dist/views/inbox/index.js +159 -78
- package/dist/views/inbox/index.js.map +1 -1
- package/dist/views/instances/detail/index.cjs +1 -1
- package/dist/views/instances/detail/index.js +1 -1
- package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +9 -1
- package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +9 -1
- package/dist/views/instances/detail/use-resubmit-comment-draft.d.cts +18 -0
- package/dist/views/instances/detail/use-resubmit-comment-draft.d.ts +18 -0
- package/dist/views/instances/new/index.cjs +1 -1
- package/dist/views/instances/new/index.cjs.map +1 -1
- package/dist/views/instances/new/index.js +15 -11
- package/dist/views/instances/new/index.js.map +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/index.cjs +1 -1
- package/dist/views/templates/designer/index.js +1 -1
- package/package.json +3 -3
- package/dist/chunks/FormBuilderView-CUOyS07f.cjs +0 -3
- package/dist/chunks/FormBuilderView-CUOyS07f.cjs.map +0 -1
- package/dist/chunks/FormBuilderView-ClLnQ1e_.js.map +0 -1
- package/dist/chunks/approver-filled-form-D1DmqDVP.cjs +0 -2
- package/dist/chunks/approver-filled-form-D1DmqDVP.cjs.map +0 -1
- package/dist/chunks/approver-filled-form-DuQGPtNB.js.map +0 -1
- package/dist/chunks/designer-B8Gvew_k.js.map +0 -1
- package/dist/chunks/designer-CAEFV1ve.cjs +0 -65
- package/dist/chunks/designer-CAEFV1ve.cjs.map +0 -1
- package/dist/chunks/detail-COh5sjAt.cjs +0 -2
- package/dist/chunks/detail-COh5sjAt.cjs.map +0 -1
- package/dist/chunks/detail-D6X61pkg.js.map +0 -1
- package/dist/chunks/orgs-C8usknWb.cjs.map +0 -1
- package/dist/chunks/orgs-Lg7tXv2u.js.map +0 -1
- package/dist/chunks/users-DRbuDYF1.js.map +0 -1
- package/dist/chunks/users-DVQicZIo.cjs +0 -2
- package/dist/chunks/users-DVQicZIo.cjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"users-Pl6hY5Y5.js","names":["readErrorMessage","styles","_Fragment","styles","BPMFormField","MemberPicker","Fragment$1","ContentHeader","users_module_default","MemberTaskReassignModal","tasks","setTasks","useState","tasksLoading","setTasksLoading","target","setTarget","reason","setReason","preview","setPreview","committed","setCommitted","busy","setBusy","error","setError","trimmedReason","inputKey","previewIsCurrent","canConfirm","result","latestRequestRef","useRef","loadTasks","useCallback","request","loaded","listMemberOpenTasks","memberId","requestError","readErrorMessage$1","member","titleById","useMemo","task","runReassignment","outcomes","reassignMemberTasks","dryRun","shownResultRows","shownResults","shownTitleById","readOutcomeLabel","taskColumns","record","resultColumns","Modal","onClose","Typography","Table","option","Input","event","Button","outcome","MEMBER_PAGE_SIZE_OPTIONS","AdminUsersView","detailMember","setDetailMember","detailMemberships","setDetailMemberships","detailManagerProfile","setDetailManagerProfile","detailResolvedManager","setDetailResolvedManager","inactiveMembers","setInactiveMembers","inactiveMembersError","setInactiveMembersError","loading","setLoading","memberPage","setMemberPage","memberPageSize","setMemberPageSize","memberTotalCount","setMemberTotalCount","members","setMembers","orgUnits","setOrgUnits","positions","setPositions","reassignMember","setReassignMember","searchText","setSearchText","orgUnitsById","orgUnit","positionsById","position","refreshMembers","memberPageResult","organization","listMemberDirectoryPage","readOrganizationDashboard","readErrorMessage","latestInactiveRequestRef","refreshInactiveMembers","listInactiveMembersWithOpenTasks","inactiveMemberRows","inactiveMemberColumns","inactiveMemberActions","rows","openDetail","memberships","resolvedManager","listMemberships","readResolvedManager","resolveMembers","columns","tableActions","closeDetail","PageHeader","SectionGroup","Section","FilterArea","FilterLine","Filter","FormField","FormFieldLayout","page","pageSize","from","to","total","MemberDetailModal","BaseCard","readOrgUnitLabel","membership","readPositionLabel","readMemberLabel","managerProfile","formatMemberLabel"],"sources":["../../src/views/admin/users/users.module.scss","../../src/views/admin/users/MemberTaskReassignModal.tsx","../../src/views/admin/users/AdminUsersView.tsx"],"sourcesContent":[".memberFilterArea {\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 :global(.mzn-input),\n :global(.mzn-input-container),\n :global(.mzn-text-field) {\n width: 100%;\n min-width: 0 !important;\n }\n}\n\n.header {\n display: grid;\n gap: 4px;\n padding: 24px 24px 0;\n}\n\n.detailFields {\n display: grid;\n gap: 16px;\n}\n\n.detailSection {\n display: grid;\n gap: 8px;\n}\n\n.membershipList {\n display: grid;\n gap: 8px;\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Button, Input, Modal, Table, Typography } from '@mezzanine-ui/react';\nimport type { TableColumn } from '@mezzanine-ui/core/table';\nimport type { MemberProfileRecord } from '@rytass/bpm-core-client';\nimport {\n listMemberOpenTasks,\n type MemberOpenTaskRecord,\n reassignMemberTasks,\n type TaskReassignmentResultRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { MemberOption, MemberPicker } from '../../../components/admin-pickers';\nimport styles from './users.module.scss';\n\ntype TaskRow = Readonly<\n Record<string, unknown> &\n MemberOpenTaskRecord & {\n key: string;\n }\n>;\n\ntype ResultRow = Readonly<\n Record<string, unknown> & {\n instanceTitle: string;\n key: string;\n message: string | null;\n outcomeLabel: string;\n }\n>;\n\ninterface PreviewState {\n readonly inputKey: string;\n readonly results: readonly TaskReassignmentResultRecord[];\n}\n\n/**\n * A committed run keeps the titles it was started with: the task list reloads\n * right after, and a member whose every task moved no longer lists any of them.\n */\ninterface CommittedState {\n readonly results: readonly TaskReassignmentResultRecord[];\n readonly titleById: ReadonlyMap<string, string>;\n}\n\n/**\n * Administrator reassignment of a member's open tasks. Lists what the member\n * holds, takes a target and a reason, previews every task's outcome (dry run),\n * and only then commits. Confirm stays disabled until the preview matches the\n * current target and reason. Replacing a seat is not a decision: no signature\n * is written, and the task keeps its id.\n */\nexport function MemberTaskReassignModal({\n member,\n onClose,\n}: {\n readonly member: MemberProfileRecord | null;\n readonly onClose: () => void;\n}): ReactElement {\n const [tasks, setTasks] = useState<readonly MemberOpenTaskRecord[]>([]);\n const [tasksLoading, setTasksLoading] = useState(false);\n const [target, setTarget] = useState<MemberOption | null>(null);\n const [reason, setReason] = useState('');\n const [preview, setPreview] = useState<PreviewState | null>(null);\n const [committed, setCommitted] = useState<CommittedState | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const trimmedReason = reason.trim();\n const inputKey = `${target?.id ?? ''}|${trimmedReason}`;\n const previewIsCurrent = preview !== null && preview.inputKey === inputKey;\n const canConfirm =\n preview !== null &&\n previewIsCurrent &&\n preview.results.some((result) => result.outcome === 'WOULD_REASSIGN');\n\n // Only the latest request may write: switching members while an earlier\n // listing is in flight must not let its late answer replace the current one.\n const latestRequestRef = useRef(0);\n\n const loadTasks = useCallback(async (memberId: string): Promise<void> => {\n const request = latestRequestRef.current + 1;\n\n latestRequestRef.current = request;\n setTasksLoading(true);\n\n try {\n const loaded = await listMemberOpenTasks(memberId);\n\n if (latestRequestRef.current === request) {\n setTasks(loaded);\n }\n } catch (requestError: unknown) {\n if (latestRequestRef.current === request) {\n setError(readErrorMessage(requestError));\n }\n } finally {\n if (latestRequestRef.current === request) {\n setTasksLoading(false);\n }\n }\n }, []);\n\n useEffect((): void => {\n setTarget(null);\n setReason('');\n setPreview(null);\n setCommitted(null);\n setError(null);\n\n if (!member) {\n latestRequestRef.current += 1;\n setTasks([]);\n setTasksLoading(false);\n\n return;\n }\n\n setTasks([]);\n void loadTasks(member.memberId);\n }, [member, loadTasks]);\n\n const titleById = useMemo(\n (): ReadonlyMap<string, string> =>\n new Map(tasks.map((task) => [task.taskId, task.instanceTitle])),\n [tasks],\n );\n\n async function runReassignment(dryRun: boolean): Promise<void> {\n if (!member || !target || !trimmedReason) {\n return;\n }\n\n setBusy(true);\n setError(null);\n\n try {\n const outcomes = await reassignMemberTasks({\n dryRun,\n fromMemberId: member.memberId,\n reason: trimmedReason,\n toMemberId: target.id,\n });\n\n if (dryRun) {\n setPreview({ inputKey, results: outcomes });\n setCommitted(null);\n } else {\n setCommitted({ results: outcomes, titleById });\n setPreview(null);\n await loadTasks(member.memberId);\n }\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setBusy(false);\n }\n }\n\n const shownResultRows = useMemo((): ResultRow[] => {\n const shownResults = committed?.results ?? preview?.results ?? [];\n const shownTitleById = committed?.titleById ?? titleById;\n\n return shownResults.map((result) => ({\n instanceTitle: shownTitleById.get(result.taskId) ?? result.taskId,\n key: result.taskId,\n message: result.message,\n outcomeLabel: readOutcomeLabel(result.outcome),\n }));\n }, [committed, preview, titleById]);\n\n const taskColumns = useMemo(\n (): TableColumn<TaskRow>[] => [\n {\n dataIndex: 'instanceTitle',\n key: 'instanceTitle',\n title: '案件',\n width: 220,\n },\n {\n dataIndex: 'nodeLabel',\n key: 'nodeLabel',\n title: '節點',\n width: 160,\n },\n {\n key: 'memberRole',\n render: (record: TaskRow): string =>\n record.memberRole === 'ASSIGNEE' ? '指派人' : '會簽候選人',\n title: '身分',\n width: 120,\n },\n ],\n [],\n );\n const resultColumns = useMemo(\n (): TableColumn<ResultRow>[] => [\n {\n dataIndex: 'instanceTitle',\n key: 'instanceTitle',\n title: '案件',\n width: 220,\n },\n {\n dataIndex: 'outcomeLabel',\n key: 'outcomeLabel',\n title: '結果',\n width: 100,\n },\n {\n dataIndex: 'message',\n key: 'message',\n title: '說明',\n width: 160,\n },\n ],\n [],\n );\n\n return (\n <Modal\n cancelText=\"關閉\"\n confirmButtonProps={{ disabled: !canConfirm || busy }}\n confirmText=\"確認改派\"\n loading={busy}\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={(): void => {\n void runReassignment(false);\n }}\n open={Boolean(member)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={member ? `改派待辦:${member.name}` : '改派待辦'}\n >\n {member ? (\n <div className={styles.detailFields}>\n <Typography variant=\"body\">\n 改派會保留任務編號,但不產生簽核紀錄;原簽核人的待辦會結案為已轉交,\n 接手人會收到新的待辦通知。\n </Typography>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {tasks.length ? (\n <Table\n columns={taskColumns}\n dataSource={tasks.map((task): TaskRow => ({\n ...task,\n key: task.taskId,\n }))}\n fullWidth\n loading={tasksLoading}\n />\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n {tasksLoading ? '載入待辦中…' : '此成員目前沒有待簽任務。'}\n </Typography>\n )}\n <BPMFormField label=\"接手人\" name=\"reassignTarget\">\n <MemberPicker\n name=\"reassignTarget\"\n onChange={(option): void => {\n setTarget(option);\n setPreview(null);\n setCommitted(null);\n }}\n placeholder=\"搜尋接手人姓名或信箱\"\n value={target}\n />\n </BPMFormField>\n <BPMFormField label=\"改派原因\" name=\"reassignReason\">\n <Input\n fullWidth\n name=\"reassignReason\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void => {\n setReason(event.target.value);\n setPreview(null);\n setCommitted(null);\n }}\n placeholder=\"例如:原簽核人已離職\"\n value={reason}\n />\n </BPMFormField>\n <div className={styles.membershipList}>\n <Typography color=\"text-neutral\" variant=\"caption\">\n 先按「預覽」確認每筆任務的結果,確認無誤後再按「確認改派」。\n </Typography>\n <div>\n <Button\n disabled={\n busy || !target || !trimmedReason || tasks.length === 0\n }\n onClick={(): void => {\n void runReassignment(true);\n }}\n variant=\"base-secondary\"\n >\n 預覽\n </Button>\n </div>\n </div>\n {shownResultRows.length ? (\n <Table\n columns={resultColumns}\n dataSource={shownResultRows}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n </Modal>\n );\n}\n\nfunction readOutcomeLabel(\n outcome: TaskReassignmentResultRecord['outcome'],\n): string {\n if (outcome === 'WOULD_REASSIGN') {\n return '會改派';\n }\n\n if (outcome === 'REASSIGNED') {\n return '已改派';\n }\n\n return '會被拒';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '改派待辦失敗。';\n}\n","'use client';\n\nimport {\n ChangeEvent,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n BaseCard,\n Filter,\n FilterArea,\n FilterLine,\n FormField,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { FormFieldLayout } from '@mezzanine-ui/core/form';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { formatMemberLabel } from '../../../lib/format-member-label';\nimport styles from './users.module.scss';\nimport { MemberTaskReassignModal } from './MemberTaskReassignModal';\nimport {\n listMemberDirectoryPage,\n MemberProfileRecord,\n resolveMembers,\n} from '@rytass/bpm-core-client';\nimport {\n listMemberships,\n MembershipRecord,\n OrgUnitRecord,\n PositionRecord,\n readOrganizationDashboard,\n readResolvedManager,\n ResolvedManagerRecord,\n} from '@rytass/bpm-core-client/organization';\nimport {\n type InactiveMemberWithOpenTasksRecord,\n listInactiveMembersWithOpenTasks,\n} from '@rytass/bpm-core-client/workflow';\n\ntype MemberRow = Readonly<\n Record<string, unknown> &\n MemberProfileRecord & {\n key: string;\n }\n>;\n\ntype InactiveMemberRow = Readonly<\n Record<string, unknown> &\n InactiveMemberWithOpenTasksRecord & {\n key: string;\n }\n>;\n\nconst MEMBER_PAGE_SIZE_OPTIONS = [10, 20, 50];\n\nexport function AdminUsersView(): ReactElement {\n const [detailMember, setDetailMember] = useState<MemberProfileRecord | null>(\n null,\n );\n const [detailMemberships, setDetailMemberships] = useState<\n readonly MembershipRecord[]\n >([]);\n const [detailManagerProfile, setDetailManagerProfile] =\n useState<MemberProfileRecord | null>(null);\n const [detailResolvedManager, setDetailResolvedManager] =\n useState<ResolvedManagerRecord | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [inactiveMembers, setInactiveMembers] = useState<\n readonly InactiveMemberWithOpenTasksRecord[]\n >([]);\n const [inactiveMembersError, setInactiveMembersError] = useState<\n string | null\n >(null);\n const [loading, setLoading] = useState(true);\n const [memberPage, setMemberPage] = useState(1);\n const [memberPageSize, setMemberPageSize] = useState(10);\n const [memberTotalCount, setMemberTotalCount] = useState(0);\n const [members, setMembers] = useState<readonly MemberProfileRecord[]>([]);\n const [orgUnits, setOrgUnits] = useState<readonly OrgUnitRecord[]>([]);\n const [positions, setPositions] = useState<readonly PositionRecord[]>([]);\n const [reassignMember, setReassignMember] =\n useState<MemberProfileRecord | null>(null);\n const [searchText, setSearchText] = useState('');\n\n const orgUnitsById = useMemo(\n (): ReadonlyMap<string, OrgUnitRecord> =>\n new Map(orgUnits.map((orgUnit) => [orgUnit.id, orgUnit])),\n [orgUnits],\n );\n const positionsById = useMemo(\n (): ReadonlyMap<string, PositionRecord> =>\n new Map(positions.map((position) => [position.id, position])),\n [positions],\n );\n\n const refreshMembers = useCallback(async (): Promise<void> => {\n setLoading(true);\n setError(null);\n\n try {\n const [memberPageResult, organization] = await Promise.all([\n listMemberDirectoryPage({\n page: memberPage,\n pageSize: memberPageSize,\n searchText,\n }),\n readOrganizationDashboard(),\n ]);\n\n setMembers(memberPageResult.members);\n setMemberTotalCount(memberPageResult.totalCount);\n setOrgUnits(organization.orgUnits);\n setPositions(organization.positions);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, [memberPage, memberPageSize, searchText]);\n\n useEffect((): void => {\n void refreshMembers();\n }, [refreshMembers]);\n\n const latestInactiveRequestRef = useRef(0);\n\n // Loaded on its own so a failure here leaves the member directory usable.\n // Only the latest request may write: a reload started when the reassignment\n // closes must not be overwritten by an earlier one answering late.\n const refreshInactiveMembers = useCallback(async (): Promise<void> => {\n const request = latestInactiveRequestRef.current + 1;\n\n latestInactiveRequestRef.current = request;\n\n try {\n const loaded = await listInactiveMembersWithOpenTasks();\n\n if (latestInactiveRequestRef.current === request) {\n setInactiveMembers(loaded);\n setInactiveMembersError(null);\n }\n } catch (requestError: unknown) {\n if (latestInactiveRequestRef.current === request) {\n setInactiveMembersError(readErrorMessage(requestError));\n }\n }\n }, []);\n\n useEffect((): void => {\n void refreshInactiveMembers();\n }, [refreshInactiveMembers]);\n\n const inactiveMemberRows = useMemo(\n (): InactiveMemberRow[] =>\n inactiveMembers.map(\n (member): InactiveMemberRow => ({ ...member, key: member.memberId }),\n ),\n [inactiveMembers],\n );\n const inactiveMemberColumns = useMemo(\n (): TableColumn<InactiveMemberRow>[] => [\n { dataIndex: 'name', key: 'name', title: '姓名', width: 160 },\n { dataIndex: 'email', key: 'email', title: '信箱', width: 260 },\n {\n dataIndex: 'openTaskCount',\n key: 'openTaskCount',\n title: '待簽數',\n width: 96,\n },\n ],\n [],\n );\n const inactiveMemberActions = useMemo(\n (): TableActions<InactiveMemberRow> => ({\n render: (): ReturnType<TableActions<InactiveMemberRow>['render']> => [\n {\n name: '改派待辦',\n onClick: (record): void => {\n setReassignMember({\n customFieldsJson: '{}',\n email: record.email,\n memberId: record.memberId,\n name: record.name,\n });\n },\n },\n ],\n variant: 'base-secondary',\n width: 112,\n }),\n [],\n );\n\n const rows = useMemo(\n (): MemberRow[] =>\n members.map((member) => ({\n ...member,\n key: member.memberId,\n })),\n [members],\n );\n\n const openDetail = useCallback(\n async (member: MemberProfileRecord): Promise<void> => {\n setDetailMember(member);\n setDetailManagerProfile(null);\n setError(null);\n\n try {\n const [memberships, resolvedManager] = await Promise.all([\n listMemberships({ memberId: member.memberId }),\n readResolvedManager(member.memberId),\n ]);\n\n setDetailMemberships(memberships);\n setDetailResolvedManager(resolvedManager);\n setDetailManagerProfile(\n (\n await resolveMembers(\n resolvedManager.managerMemberId\n ? [resolvedManager.managerMemberId]\n : [],\n )\n )[0] ?? null,\n );\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n }\n },\n [],\n );\n\n const columns = useMemo(\n (): TableColumn<MemberRow>[] => [\n { dataIndex: 'name', key: 'name', title: '姓名', width: 160 },\n { dataIndex: 'email', key: 'email', title: '信箱', width: 260 },\n ],\n [],\n );\n const tableActions = useMemo(\n (): TableActions<MemberRow> => ({\n render: (): ReturnType<TableActions<MemberRow>['render']> => [\n {\n name: '檢視',\n onClick: (record): void => {\n void openDetail(record);\n },\n },\n {\n name: '改派待辦',\n onClick: (record): void => {\n setReassignMember(record);\n },\n },\n ],\n variant: 'base-secondary',\n width: 176,\n }),\n [openDetail],\n );\n\n function closeDetail(): void {\n setDetailMember(null);\n setDetailManagerProfile(null);\n setDetailMemberships([]);\n setDetailResolvedManager(null);\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"會員資料由 host member resolver 提供,BPM 僅維護組織歸屬與主管解析。\"\n title=\"會員對照\"\n />\n </PageHeader>\n\n <SectionGroup>\n {inactiveMemberRows.length || inactiveMembersError ? (\n <Section\n contentHeader={\n <ContentHeader\n description=\"這些會員已停用,身上仍有待簽,請改派給在職的人。\"\n title=\"已停用、仍有待簽的會員\"\n />\n }\n >\n <div data-inactive-members=\"\">\n {inactiveMembersError ? (\n <Typography color=\"text-error\" variant=\"body\">\n {inactiveMembersError}\n </Typography>\n ) : (\n <Table\n actions={inactiveMemberActions}\n columns={inactiveMemberColumns}\n dataSource={inactiveMemberRows}\n fullWidth\n />\n )}\n </div>\n </Section>\n ) : null}\n <Section\n filterArea={\n <FilterArea className={styles.memberFilterArea}>\n <FilterLine>\n <Filter span={3}>\n <FormField\n fullWidth\n layout={FormFieldLayout.VERTICAL}\n name=\"memberSearchText\"\n >\n <Input\n fullWidth\n onChange={(\n event: ChangeEvent<HTMLInputElement>,\n ): void => {\n setSearchText(event.target.value);\n setMemberPage(1);\n }}\n placeholder=\"搜尋姓名或信箱\"\n size=\"sub\"\n value={searchText}\n variant=\"base\"\n />\n </FormField>\n </Filter>\n </FilterLine>\n </FilterArea>\n }\n >\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Table\n actions={tableActions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n pagination={{\n current: memberPage,\n onChange: (page): void => {\n setMemberPage(page);\n },\n onChangePageSize: (pageSize): void => {\n setMemberPage(1);\n setMemberPageSize(pageSize);\n },\n pageSize: memberPageSize,\n pageSizeLabel: '每頁筆數',\n pageSizeOptions: MEMBER_PAGE_SIZE_OPTIONS,\n renderResultSummary: (from, to, total): string =>\n `顯示 ${from}-${to} 筆,共 ${total} 筆`,\n showPageSizeOptions: true,\n total: memberTotalCount,\n }}\n />\n </Section>\n </SectionGroup>\n\n <MemberTaskReassignModal\n member={reassignMember}\n onClose={(): void => {\n setReassignMember(null);\n // A reassignment may have cleared someone off the list.\n void refreshInactiveMembers();\n }}\n />\n\n <MemberDetailModal\n managerProfile={detailManagerProfile}\n member={detailMember}\n memberships={detailMemberships}\n onClose={closeDetail}\n orgUnitsById={orgUnitsById}\n positionsById={positionsById}\n resolvedManager={detailResolvedManager}\n />\n </>\n );\n}\n\nfunction MemberDetailModal({\n managerProfile,\n member,\n memberships,\n onClose,\n orgUnitsById,\n positionsById,\n resolvedManager,\n}: {\n readonly managerProfile: MemberProfileRecord | null;\n readonly member: MemberProfileRecord | null;\n readonly memberships: readonly MembershipRecord[];\n readonly onClose: () => void;\n readonly orgUnitsById: ReadonlyMap<string, OrgUnitRecord>;\n readonly positionsById: ReadonlyMap<string, PositionRecord>;\n readonly resolvedManager: ResolvedManagerRecord | null;\n}): ReactElement {\n return (\n <Modal\n cancelText=\"關閉\"\n confirmText=\"關閉\"\n modalType=\"standard\"\n onCancel={onClose}\n onClose={onClose}\n onConfirm={onClose}\n open={Boolean(member)}\n showModalFooter\n showModalHeader\n size=\"regular\"\n title={member?.name ?? '會員明細'}\n >\n {member ? (\n <div className={styles.detailFields}>\n <BaseCard title=\"基本資料\">\n <div className={styles.detailSection}>\n <Typography variant=\"body\">\n 信箱:{member.email?.trim() ? member.email : '未設定'}\n </Typography>\n </div>\n </BaseCard>\n <BaseCard title=\"BPM 組織歸屬\">\n <div className={styles.membershipList}>\n {memberships.length ? (\n memberships.map((membership) => (\n <Typography key={membership.id} variant=\"body\">\n {readOrgUnitLabel(orgUnitsById.get(membership.orgUnitId))}\n {' / '}\n {membership.positionId\n ? readPositionLabel(\n positionsById.get(membership.positionId),\n )\n : '未指定職位'}\n {' / '}\n {membership.isPrimary ? '主要' : '一般'}\n </Typography>\n ))\n ) : (\n <Typography color=\"text-neutral\" variant=\"body\">\n 尚未建立 BPM 組織歸屬\n </Typography>\n )}\n </div>\n </BaseCard>\n <BaseCard title=\"主管解析\">\n <Typography variant=\"body\">\n {resolvedManager?.managerMemberId\n ? readMemberLabel(managerProfile)\n : '尚未解析到主管'}\n </Typography>\n </BaseCard>\n </div>\n ) : null}\n </Modal>\n );\n}\n\nfunction readOrgUnitLabel(orgUnit: OrgUnitRecord | undefined): string {\n return orgUnit ? `${orgUnit.name} · ${orgUnit.code}` : '未知組織';\n}\n\nfunction readPositionLabel(position: PositionRecord | undefined): string {\n return position ? `${position.name} · ${position.code}` : '未知職位';\n}\n\nfunction readMemberLabel(member: MemberProfileRecord | null): string {\n return member\n ? formatMemberLabel(member.name, member.email, 'dot')\n : '主管資料尚未載入';\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '讀取會員資料失敗。';\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AC6DA,SAAgBS,EAAwB,EACtC,WACA,cAIe;CACf,IAAM,CAACC,GAAOC,KAAYC,EAA0C,CAAC,CAAC,GAChE,CAACC,GAAcC,KAAmBF,EAAS,EAAK,GAChD,CAACG,GAAQC,KAAaJ,EAA8B,IAAI,GACxD,CAACK,GAAQC,KAAaN,EAAS,EAAE,GACjC,CAACO,GAASC,KAAcR,EAA8B,IAAI,GAC1D,CAACS,GAAWC,KAAgBV,EAAgC,IAAI,GAChE,CAACW,GAAMC,KAAWZ,EAAS,EAAK,GAChC,CAACa,GAAOC,KAAYd,EAAwB,IAAI,GAEhDe,IAAgBV,EAAO,KAAK,GAC5BW,IAAW,GAAGb,GAAQ,MAAM,GAAG,GAAGY,KAClCE,IAAmBV,MAAY,QAAQA,EAAQ,aAAaS,GAC5DE,KACJX,MAAY,QACZU,KACAV,EAAQ,QAAQ,MAAM,MAAWY,EAAO,YAAY,gBAAgB,GAIhEC,IAAmBC,EAAO,CAAC,GAE3BC,IAAYC,EAAY,OAAO,MAAoC;EACvE,IAAMC,IAAUJ,EAAiB,UAAU;EAG3C,AADA,EAAiB,UAAUI,GAC3BtB,EAAgB,EAAI;EAEpB,IAAI;GACF,IAAMuB,IAAS,MAAMC,GAAoBC,CAAQ;GAEjD,AAAIP,EAAiB,YAAYI,KAC/BzB,EAAS0B,CAAM;EAEnB,SAASG,GAAuB;GAC9B,AAAIR,EAAiB,YAAYI,KAC/BV,EAAS1B,EAAiBwC,CAAY,CAAC;EAE3C,UAAU;GACR,AAAIR,EAAiB,YAAYI,KAC/BtB,EAAgB,EAAK;EAEzB;CACF,GAAG,CAAC,CAAC;CAEL,QAAsB;EAOpB,AANAE,EAAU,IAAI,GACdE,EAAU,EAAE,GACZE,EAAW,IAAI,GACfE,EAAa,IAAI,GACjBI,EAAS,IAAI,GAERgB,KAQL/B,EAAS,CAAC,CAAC,GACXuB,EAAeQ,EAAO,QAAQ,MAR5B,EAAiB,WAAW,GAC5B/B,EAAS,CAAC,CAAC,GACXG,EAAgB,EAAK;CAOzB,GAAG,CAAC4B,GAAQR,CAAS,CAAC;CAEtB,IAAMS,IAAYC,QAEd,IAAI,IAAIlC,EAAM,KAAK,MAAS,CAACmC,EAAK,QAAQA,EAAK,aAAa,CAAC,CAAC,GAChE,CAACnC,CAAK,CACR;CAEA,eAAeoC,EAAgB,GAAgC;EAC7D,IAAKJ,KAAW3B,KAAWY,GAI3B;GACA,AADAH,EAAQ,EAAI,GACZE,EAAS,IAAI;GAEb,IAAI;IACF,IAAMqB,IAAW,MAAMC,EAAoB;KACzC;KACA,cAAcN,EAAO;KACrB,QAAQf;KACR,YAAYZ,EAAO;IACrB,CAAC;IAED,AAAIkC,KACF7B,EAAW;KAAE;KAAU,SAAS2B;IAAS,CAAC,GAC1CzB,EAAa,IAAI,MAEjBA,EAAa;KAAE,SAASyB;KAAU;IAAU,CAAC,GAC7C3B,EAAW,IAAI,GACf,MAAMc,EAAUQ,EAAO,QAAQ;GAEnC,SAASF,GAAuB;IAC9B,EAASxC,EAAiBwC,CAAY,CAAC;GACzC,UAAU;IACR,EAAQ,EAAK;GACf;EAvBY;CAwBd;CAEA,IAAMU,IAAkBN,QAA2B;EACjD,IAAMO,IAAe9B,GAAW,WAAWF,GAAS,WAAW,CAAC,GAC1DiC,IAAiB/B,GAAW,aAAasB;EAE/C,OAAOQ,EAAa,KAAK,OAAY;GACnC,eAAeC,EAAe,IAAIrB,EAAO,MAAM,KAAKA,EAAO;GAC3D,KAAKA,EAAO;GACZ,SAASA,EAAO;GAChB,cAAcsB,EAAiBtB,EAAO,OAAO;EAC/C,EAAE;CACJ,GAAG;EAACV;EAAWF;EAASwB;CAAS,CAAC,GAE5BW,IAAcV,QACY;EAC5B;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,KAAK;GACL,SAAS,MACPW,EAAO,eAAe,aAAa,QAAQ;GAC7C,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACMC,IAAgBZ,QACY;EAC9B;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;EACA;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH;CAEA,OACE,kBAACa,GAAD;EACE,YAAW;EACX,oBAAoB,EAAE,UAAU,CAAC3B,MAAcP,EAAK;EACpD,aAAY;EACZ,SAASA;EACT,WAAU;EACV,UAAUmC;EACD;EACT,iBAAuB;GACrB,EAAqB,EAAK;EAC5B;EACA,MAAM,EAAQhB;EACd,iBAAA;EACA,iBAAA;EACA,MAAK;EACL,OAAOA,IAAS,QAAQA,EAAO,SAAS;EAEvC,UAAAA,IACC,kBAAC,OAAD;GAAK,WAAWzC,EAAO;GAAvB,UAAA;IACE,kBAAC0D,GAAD;KAAY,SAAQ;KAAO,UAAA;IAGf,CAAA;IACXlC,IACC,kBAACkC,GAAD;KAAY,OAAM;KAAa,SAAQ;KACpC,UAAAlC;IACS,CAAA,IACV;IACHf,EAAM,SACL,kBAACkD,GAAD;KACE,SAASN;KACT,YAAY5C,EAAM,KAAK,OAAmB;MACxC,GAAGmC;MACH,KAAKA,EAAK;KACZ,EAAE;KACF,WAAA;KACA,SAAShC;IACV,CAAA,IAED,kBAAC8C,GAAD;KAAY,OAAM;KAAe,SAAQ;KACtC,UAAA9C,IAAe,WAAW;IACjB,CAAA;IAEd,kBAACT,GAAD;KAAc,OAAM;KAAM,MAAK;KAC7B,UAAA,kBAACC,GAAD;MACE,MAAK;MACL,WAAW,MAAiB;OAG1B,AAFAW,EAAU6C,CAAM,GAChBzC,EAAW,IAAI,GACfE,EAAa,IAAI;MACnB;MACA,aAAY;MACZ,OAAOP;KACR,CAAA;IACW,CAAA;IACd,kBAACX,GAAD;KAAc,OAAM;KAAO,MAAK;KAC9B,UAAA,kBAAC0D,GAAD;MACE,WAAA;MACA,MAAK;MACL,WAAW,MAA+C;OAGxD,AAFA5C,EAAU6C,EAAM,OAAO,KAAK,GAC5B3C,EAAW,IAAI,GACfE,EAAa,IAAI;MACnB;MACA,aAAY;MACZ,OAAOL;KACR,CAAA;IACW,CAAA;IACd,kBAAC,OAAD;KAAK,WAAWhB,EAAO;KAAvB,UAAA,CACE,kBAAC0D,GAAD;MAAY,OAAM;MAAe,SAAQ;MAAU,UAAA;KAEvC,CAAA,GACZ,kBAAC,OAAD,EAAA,UACE,kBAACK,GAAD;MACE,UACEzC,KAAQ,CAACR,KAAU,CAACY,KAAiBjB,EAAM,WAAW;MAExD,eAAqB;OACnB,EAAqB,EAAI;MAC3B;MACA,SAAQ;MACT,UAAA;KAEO,CAAA,EACL,CAAA,CACF;;IACJwC,EAAgB,SACf,kBAACU,GAAD;KACE,SAASJ;KACT,YAAYN;KACZ,WAAA;IACD,CAAA,IACC;GACD;EACH,CAAA,IAAA;CACC,CAAA;AAEX;AAEA,SAASG,EACP,GACQ;CASR,OARIY,MAAY,mBACP,QAGLA,MAAY,eACP,QAGF;AACT;AAEA,SAASjE,EAAiB,GAAwB;CAChD,OAAOyB,aAAiB,QAAQA,EAAM,UAAU;AAClD;;;ACxRA,IAAMyC,IAA2B;CAAC;CAAI;CAAI;AAAE;AAE5C,SAAgBC,IAA+B;CAC7C,IAAM,CAACC,GAAcC,KAAmBzD,EACtC,IACF,GACM,CAAC0D,GAAmBC,KAAwB3D,EAEhD,CAAC,CAAC,GACE,CAAC4D,GAAsBC,KAC3B7D,EAAqC,IAAI,GACrC,CAAC8D,IAAuBC,KAC5B/D,EAAuC,IAAI,GACvC,CAACa,GAAOC,KAAYd,EAAwB,IAAI,GAChD,CAACgE,GAAiBC,KAAsBjE,EAE5C,CAAC,CAAC,GACE,CAACkE,GAAsBC,KAA2BnE,EAEtD,IAAI,GACA,CAACoE,GAASC,KAAcrE,EAAS,EAAI,GACrC,CAACsE,GAAYC,KAAiBvE,EAAS,CAAC,GACxC,CAACwE,GAAgBC,MAAqBzE,EAAS,EAAE,GACjD,CAAC0E,IAAkBC,MAAuB3E,EAAS,CAAC,GACpD,CAAC4E,GAASC,MAAc7E,EAAyC,CAAC,CAAC,GACnE,CAAC8E,GAAUC,MAAe/E,EAAmC,CAAC,CAAC,GAC/D,CAACgF,IAAWC,MAAgBjF,EAAoC,CAAC,CAAC,GAClE,CAACkF,IAAgBC,KACrBnF,EAAqC,IAAI,GACrC,CAACoF,GAAYC,MAAiBrF,EAAS,EAAE,GAEzCsF,KAAetD,QAEjB,IAAI,IAAI8C,EAAS,KAAK,MAAY,CAACS,EAAQ,IAAIA,CAAO,CAAC,CAAC,GAC1D,CAACT,CAAQ,CACX,GACMU,KAAgBxD,QAElB,IAAI,IAAIgD,GAAU,KAAK,MAAa,CAACS,EAAS,IAAIA,CAAQ,CAAC,CAAC,GAC9D,CAACT,EAAS,CACZ,GAEMU,KAAiBnE,EAAY,YAA2B;EAE5D,AADA8C,EAAW,EAAI,GACfvD,EAAS,IAAI;EAEb,IAAI;GACF,IAAM,CAAC6E,GAAkBC,KAAgB,MAAM,QAAQ,IAAI,CACzDC,EAAwB;IACtB,MAAMvB;IACN,UAAUE;IACV;GACF,CAAC,GACDsB,EAA0B,CAC5B,CAAC;GAKD,AAHAjB,GAAWc,EAAiB,OAAO,GACnChB,GAAoBgB,EAAiB,UAAU,GAC/CZ,GAAYa,EAAa,QAAQ,GACjCX,GAAaW,EAAa,SAAS;EACrC,SAAShE,GAAuB;GAC9B,EAASmE,EAAiBnE,CAAY,CAAC;EACzC,UAAU;GACR,EAAW,EAAK;EAClB;CACF,GAAG;EAAC0C;EAAYE;EAAgBY;CAAU,CAAC;CAE3C,QAAsB;EACpB,GAAoB;CACtB,GAAG,CAACM,EAAc,CAAC;CAEnB,IAAMM,IAA2B3E,EAAO,CAAC,GAKnC4E,IAAyB1E,EAAY,YAA2B;EACpE,IAAMC,IAAUwE,EAAyB,UAAU;EAEnD,EAAyB,UAAUxE;EAEnC,IAAI;GACF,IAAMC,IAAS,MAAMyE,EAAiC;GAEtD,AAAIF,EAAyB,YAAYxE,MACvCyC,EAAmBxC,CAAM,GACzB0C,EAAwB,IAAI;EAEhC,SAASvC,GAAuB;GAC9B,AAAIoE,EAAyB,YAAYxE,KACvC2C,EAAwB4B,EAAiBnE,CAAY,CAAC;EAE1D;CACF,GAAG,CAAC,CAAC;CAEL,QAAsB;EACpB,EAA4B;CAC9B,GAAG,CAACqE,CAAsB,CAAC;CAE3B,IAAME,KAAqBnE,QAEvBgC,EAAgB,KACb,OAA+B;EAAE,GAAGlC;EAAQ,KAAKA,EAAO;CAAS,EACpE,GACF,CAACkC,CAAe,CAClB,GACMoC,KAAwBpE,QACY;EACtC;GAAE,WAAW;GAAQ,KAAK;GAAQ,OAAO;GAAM,OAAO;EAAI;EAC1D;GAAE,WAAW;GAAS,KAAK;GAAS,OAAO;GAAM,OAAO;EAAI;EAC5D;GACE,WAAW;GACX,KAAK;GACL,OAAO;GACP,OAAO;EACT;CACF,GACA,CAAC,CACH,GACMqE,KAAwBrE,SACY;EACtC,cAAqE,CACnE;GACE,MAAM;GACN,UAAU,MAAiB;IACzB,EAAkB;KAChB,kBAAkB;KAClB,OAAOW,EAAO;KACd,UAAUA,EAAO;KACjB,MAAMA,EAAO;IACf,CAAC;GACH;EACF,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC,CACH,GAEM2D,KAAOtE,QAET4C,EAAQ,KAAK,OAAY;EACvB,GAAG9C;EACH,KAAKA,EAAO;CACd,EAAE,GACJ,CAAC8C,CAAO,CACV,GAEM2B,KAAahF,EACjB,OAAO,MAA+C;EAGpD,AAFAkC,EAAgB3B,CAAM,GACtB+B,EAAwB,IAAI,GAC5B/C,EAAS,IAAI;EAEb,IAAI;GACF,IAAM,CAAC0F,GAAaC,KAAmB,MAAM,QAAQ,IAAI,CACvDC,EAAgB,EAAE,UAAU5E,EAAO,SAAS,CAAC,GAC7C6E,EAAoB7E,EAAO,QAAQ,CACrC,CAAC;GAID,AAFA6B,EAAqB6C,CAAW,GAChCzC,EAAyB0C,CAAe,GACxC5C,GAEI,MAAM+C,EACJH,EAAgB,kBACZ,CAACA,EAAgB,eAAe,IAChC,CAAC,CACP,EAAA,CACA,MAAM,IACV;EACF,SAAS7E,GAAuB;GAC9B,EAASmE,EAAiBnE,CAAY,CAAC;EACzC;CACF,GACA,CAAC,CACH,GAEMiF,KAAU7E,QACkB,CAC9B;EAAE,WAAW;EAAQ,KAAK;EAAQ,OAAO;EAAM,OAAO;CAAI,GAC1D;EAAE,WAAW;EAAS,KAAK;EAAS,OAAO;EAAM,OAAO;CAAI,CAC9D,GACA,CAAC,CACH,GACM8E,KAAe9E,SACa;EAC9B,cAA6D,CAC3D;GACE,MAAM;GACN,UAAU,MAAiB;IACzB,GAAgBW,CAAM;GACxB;EACF,GACA;GACE,MAAM;GACN,UAAU,MAAiB;IACzB,EAAkBA,CAAM;GAC1B;EACF,CACF;EACA,SAAS;EACT,OAAO;CACT,IACA,CAAC4D,EAAU,CACb;CAEA,SAASQ,KAAoB;EAI3B,AAHAtD,EAAgB,IAAI,GACpBI,EAAwB,IAAI,GAC5BF,EAAqB,CAAC,CAAC,GACvBI,EAAyB,IAAI;CAC/B;CAEA,OACE,kBAAAzE,GAAA,EAAA,UAAA;EACE,kBAAC0H,GAAD,EAAA,UACE,kBAACrH,GAAD;GACE,aAAY;GACZ,OAAM;EACP,CAAA,EACS,CAAA;EAEZ,kBAACsH,GAAD,EAAA,UAAA,CACGd,GAAmB,UAAUjC,IAC5B,kBAACgD,GAAD;GACE,eACE,kBAACvH,GAAD;IACE,aAAY;IACZ,OAAM;GACP,CAAA;GAGH,UAAA,kBAAC,OAAD;IAAK,yBAAsB;IACxB,UAAAuE,IACC,kBAACnB,GAAD;KAAY,OAAM;KAAa,SAAQ;KACpC,UAAAmB;IACS,CAAA,IAEZ,kBAAClB,GAAD;KACE,SAASqD;KACT,SAASD;KACT,YAAYD;KACZ,WAAA;IACD,CAAA;GAEA,CAAA;EACE,CAAA,IACP,MACJ,kBAACe,GAAD;GACE,YACE,kBAACC,GAAD;IAAY,WAAW5H,EAAO;IAC5B,UAAA,kBAAC6H,GAAD,EAAA,UACE,kBAACC,GAAD;KAAQ,MAAM;KACZ,UAAA,kBAACC,GAAD;MACE,WAAA;MACA,QAAQC,EAAgB;MACxB,MAAK;MAEL,UAAA,kBAACrE,GAAD;OACE,WAAA;OACA,WACE,MACS;QAET,AADAmC,GAAclC,EAAM,OAAO,KAAK,GAChCoB,EAAc,CAAC;OACjB;OACA,aAAY;OACZ,MAAK;OACL,OAAOa;OACP,SAAQ;MACT,CAAA;KACQ,CAAA;IACL,CAAA,EACE,CAAA;GACF,CAAA;GA1BhB,UAAA,CA6BGvE,IACC,kBAACkC,GAAD;IAAY,OAAM;IAAa,SAAQ;IACpC,UAAAlC;GACS,CAAA,IACV,MACJ,kBAACmC,GAAD;IACE,SAAS8D;IACA;IACT,YAAYR;IACZ,WAAA;IACS;IACT,YAAY;KACV,SAAShC;KACT,WAAW,MAAe;MACxB,EAAckD,CAAI;KACpB;KACA,mBAAmB,MAAmB;MAEpC,AADAjD,EAAc,CAAC,GACfE,GAAkBgD,CAAQ;KAC5B;KACA,UAAUjD;KACV,eAAe;KACf,iBAAiBlB;KACjB,sBAAsB,GAAM,GAAI,MAC9B,MAAMoE,EAAK,GAAGC,EAAG,OAAOC,EAAM;KAChC,qBAAqB;KACrB,OAAOlD;IACT;GACD,CAAA,CACM;EACG,CAAA,CAAA,EAAA,CAAA;EAEd,kBAAC7E,GAAD;GACE,QAAQqF;GACR,eAAqB;IAGnB,AAFAC,EAAkB,IAAI,GAEtBc,EAA4B;GAC9B;EACD,CAAA;EAED,kBAAC4B,IAAD;GACE,gBAAgBjE;GAChB,QAAQJ;GACR,aAAaE;GACb,SAASqD;GACK;GACC;GACf,iBAAiBjD;EAClB,CAAA;CACD,EAAA,CAAA;AAEN;AAEA,SAAS+D,GAAkB,EACzB,mBACA,WACA,gBACA,YACA,iBACA,kBACA,sBASe;CACf,OACE,kBAAChF,GAAD;EACE,YAAW;EACX,aAAY;EACZ,WAAU;EACV,UAAUC;EACD;EACT,WAAWA;EACX,MAAM,EAAQhB;EACd,iBAAA;EACA,iBAAA;EACA,MAAK;EACL,OAAOA,GAAQ,QAAQ;EAEtB,UAAAA,IACC,kBAAC,OAAD;GAAK,WAAWvC,EAAO;GAAvB,UAAA;IACE,kBAACuI,GAAD;KAAU,OAAM;KACd,UAAA,kBAAC,OAAD;MAAK,WAAWvI,EAAO;MACrB,UAAA,kBAACwD,GAAD;OAAY,SAAQ;OAApB,UAAA,CAA2B,OACrBjB,EAAO,OAAO,KAAK,IAAIA,EAAO,QAAQ,KAChC;;KACT,CAAA;IACG,CAAA;IACV,kBAACgG,GAAD;KAAU,OAAM;KACd,UAAA,kBAAC,OAAD;MAAK,WAAWvI,EAAO;MACpB,UAAAiH,EAAY,SACXA,EAAY,KAAK,MACf,kBAACzD,GAAD;OAAgC,SAAQ;OAAxC,UAAA;QACGgF,EAAiBzC,EAAa,IAAI0C,EAAW,SAAS,CAAC;QACvD;QACAA,EAAW,aACRC,EACEzC,EAAc,IAAIwC,EAAW,UAAU,CACzC,IACA;QACH;QACAA,EAAW,YAAY,OAAO;OACrB;MAVK,GAAAA,EAAW,EAUhB,CACb,IAED,kBAACjF,GAAD;OAAY,OAAM;OAAe,SAAQ;OAAO,UAAA;MAEpC,CAAA;KAEX,CAAA;IACG,CAAA;IACV,kBAAC+E,GAAD;KAAU,OAAM;KACd,UAAA,kBAAC/E,GAAD;MAAY,SAAQ;MACjB,UAAA0D,GAAiB,kBACdyB,EAAgBC,CAAc,IAC9B;KACM,CAAA;IACJ,CAAA;GACP;EACH,CAAA,IAAA;CACC,CAAA;AAEX;AAEA,SAASJ,EAAiB,GAA4C;CACpE,OAAOxC,IAAU,GAAGA,EAAQ,KAAK,KAAKA,EAAQ,SAAS;AACzD;AAEA,SAAS0C,EAAkB,GAA8C;CACvE,OAAOxC,IAAW,GAAGA,EAAS,KAAK,KAAKA,EAAS,SAAS;AAC5D;AAEA,SAASyC,EAAgB,GAA4C;CACnE,OAAOpG,IACHsG,EAAkBtG,EAAO,MAAMA,EAAO,OAAO,KAAK,IAClD;AACN;AAEA,SAASiE,EAAiB,GAAwB;CAChD,OAAOlF,aAAiB,QAAQA,EAAM,UAAU;AAClD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/orgs-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/orgs-BeeDDWL1.cjs");let t=require("react/jsx-runtime");var n={title:`組織管理 | BPM Admin`,description:`維護組織樹、職位、會員歸屬與簽核主管解析規則。`};function r(){return(0,t.jsx)(e.t,{})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/users-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/users-O2L_M3BK.cjs");let t=require("react/jsx-runtime");var n={title:`會員對照 | BPM Admin`,description:`檢視 BPM 內部會員組織歸屬與主管解析。`};function r(){return(0,t.jsx)(e.t,{})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/detail-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/detail-BkMtA_0K.cjs");let t=require("react/jsx-runtime");var n={title:`案件詳情 | BPM Admin`};async function r({params:n}){let{id:r}=await n;return(0,t.jsx)(e.t,{instanceId:r})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/compose-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/compose-DZk-SfHT.cjs");let t=require("react/jsx-runtime"),n=require("next/server");var r={title:`建立模板(表單 + 流程) | BPM Admin`,description:`以精靈式流程一次完成 BPM 表單與簽核流程設計並發佈。`};async function i(){return await(0,n.connection)(),(0,t.jsx)(e.t,{aiAssistantAvailable:!!process.env.OPENAI_API_KEY,showAiAssistant:process.env.BPM_AI_ASSISTANT_ENABLED===`true`})}exports.default=i,exports.metadata=r;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "../../../chunks/compose-
|
|
1
|
+
import { t as e } from "../../../chunks/compose-B1GlrZW9.js";
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
3
|
import { connection as n } from "next/server";
|
|
4
4
|
//#region src/pages/templates/compose/index.tsx
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/designer-
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("../../../chunks/designer-BYYxEN9L.cjs");let t=require("react/jsx-runtime");var n={title:`流程設計器 | BPM Admin`,description:`以視覺化設計器編輯 BPM 簽核流程節點、條件與發佈版本。`};async function r({params:n}){let{id:r}=await n;return(0,t.jsx)(e.t,{aiAssistantAvailable:!!process.env.OPENAI_API_KEY,showAiAssistant:process.env.BPM_AI_ASSISTANT_ENABLED===`true`,showDryRun:process.env.BPM_TEMPLATE_DRY_RUN_ENABLED!==`false`,templateId:r})}exports.default=r,exports.metadata=n;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/users-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/users-O2L_M3BK.cjs"),t=require("../../chunks/orgs-BeeDDWL1.cjs"),n=require("../../chunks/delegations-V9HIe3_P.cjs"),r=require("./webhook-endpoints/index.cjs");exports.AdminDelegationsView=n.t,exports.AdminOrgsView=t.t,exports.AdminUsersView=e.t,exports.AdminWebhookEndpointsView=r.AdminWebhookEndpointsView;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as e } from "../../chunks/users-
|
|
2
|
-
import { t } from "../../chunks/orgs-
|
|
1
|
+
import { t as e } from "../../chunks/users-Pl6hY5Y5.js";
|
|
2
|
+
import { t } from "../../chunks/orgs-8hje_l2n.js";
|
|
3
3
|
import { t as n } from "../../chunks/delegations-xUt1tj8d.js";
|
|
4
4
|
import { AdminWebhookEndpointsView as r } from "./webhook-endpoints/index.js";
|
|
5
5
|
export { n as AdminDelegationsView, t as AdminOrgsView, e as AdminUsersView, r as AdminWebhookEndpointsView };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/orgs-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/orgs-BeeDDWL1.cjs");exports.AdminOrgsView=e.t;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as AdminOrgsView } from "../../../chunks/orgs-
|
|
1
|
+
export { t as AdminOrgsView } from "../../../chunks/orgs-8hje_l2n.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/users-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/users-O2L_M3BK.cjs");exports.AdminUsersView=e.t;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as AdminUsersView } from "../../../chunks/users-
|
|
1
|
+
export { t as AdminUsersView } from "../../../chunks/users-Pl6hY5Y5.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/FormBuilderView-SrGltzFT.cjs");exports.FormBuilderView=e.t;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as FormBuilderView } from "../../../chunks/FormBuilderView-
|
|
1
|
+
export { t as FormBuilderView } from "../../../chunks/FormBuilderView-BVKY1j_0.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons");
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../chunks/router-adapter--gYs13E8.cjs"),n=require("../../chunks/auth-provider-4BeCw7cI.cjs"),r=require("../../chunks/format-date-time-D-cx5M8z.cjs"),i=require("../../chunks/routes-config-C1j_vFKo.cjs"),a=require("../../chunks/task-node-label-BF6UllxP.cjs");let o=require("react"),s=require("@mezzanine-ui/react"),c=require("react/jsx-runtime"),l=require("@rytass/bpm-core-client/workflow"),u=require("@mezzanine-ui/react/ContentHeader");u=e.t(u,1);let d=require("@mezzanine-ui/icons");var f=100,p={display:`grid`,gap:`var(--mzn-spacing-gap-base)`,marginBottom:`var(--mzn-spacing-padding-vertical-spacious)`};function m(){let e=t.r(),a=i.r(),{member:f}=n.n(),m=f?.memberId??null,[_,b]=(0,o.useState)(`pending`),[x,S]=(0,o.useState)(null),[C,w]=(0,o.useState)([]),[E,O]=(0,o.useState)(!0),[A,j]=(0,o.useState)([]),[M,N]=(0,o.useState)([]),[F,I]=(0,o.useState)(!1);(0,o.useEffect)(()=>{m&&G()},[m]);let L=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{dataIndex:`statusLabel`,key:`statusLabel`,title:`狀態`,width:120},{key:`fill`,render:e=>e.hasFillableFields?(0,c.jsx)(s.Badge,{size:`sub`,text:`需補填`,variant:`dot-warning`}):null,title:`補填`,width:120},{key:`slaDueAt`,render:e=>(0,c.jsx)(s.Typography,{color:e.slaStatusColor,component:`span`,variant:`body`,children:e.slaStatusText}),title:`SLA`,width:180},{key:`createdAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.createdAt)}),title:`建立時間`,width:220}],[]),R=(0,o.useMemo)(()=>({render:t=>[{name:`處理`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),z=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{key:`startedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:r.t(e.startedAt)}),title:`發起時間`,width:220}],[]),B=(0,o.useMemo)(()=>({render:t=>[{name:`重新送出`,onClick:()=>e.push(a.caseDetail(t.id))}],variant:`base-secondary`,width:120}),[e,a]),V=(0,o.useMemo)(()=>[{dataIndex:`caseTitle`,key:`caseTitle`,title:`案件`,width:280},{dataIndex:`nodeText`,key:`nodeText`,title:`節點`,width:180},{key:`decisionLabel`,render:e=>(0,c.jsx)(s.Typography,{color:T(e.decisionAction),component:`span`,variant:`body`,children:e.decisionLabel}),title:`決議`,width:120},{key:`decisionComment`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:e.decisionCommentText}),title:`意見`,width:240},{key:`instanceStateLabel`,render:e=>(0,c.jsx)(s.Typography,{color:D(e.instanceState),component:`span`,variant:`body`,children:e.instanceStateLabel}),title:`流程狀態`,width:140},{key:`decidedAt`,render:e=>(0,c.jsx)(s.Typography,{component:`span`,variant:`body`,children:k(e.decidedAt)}),title:`簽核時間`,width:220}],[]),H=(0,o.useMemo)(()=>({render:t=>[{name:`查看`,onClick:()=>e.push(a.caseDetail(t.instanceId))}],variant:`base-secondary`,width:88}),[e,a]),U=(0,o.useMemo)(()=>C.filter(e=>e.instanceState===`RUNNING`),[C]);function W(e){b(e===`history`||e===`pending`||e===`tracking`?e:`pending`)}async function G(){O(!0),S(null);try{if(!m){j([]),w([]),N([]),I(!1);return}let[e,t,n]=await Promise.all([(0,l.listInboxTasks)(m),(0,l.listApprovalHistoryTasks)(m),g(m)]),[r,i]=await Promise.all([v(e),y(t)]);j(r),w(i),N(n?.rows??[]),I(n?.truncated??!1)}catch(e){S(P(e))}finally{O(!1)}}return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.PageHeader,{children:(0,c.jsx)(u.default,{description:`目前以 ${f?.name??m??`目前登入會員`} 查詢待處理與歷史簽核任務。`,title:`我的待簽`,children:(0,c.jsx)(s.Button,{icon:d.PlusIcon,iconType:`leading`,onClick:()=>e.push(a.caseNew()),variant:`base-primary`,children:`發起簽核`})})}),(0,c.jsx)(s.SectionGroup,{children:(0,c.jsxs)(s.Section,{children:[x?(0,c.jsx)(s.Typography,{color:`text-error`,variant:`body`,children:x}):null,(0,c.jsxs)(s.Tab,{activeKey:_,onChange:W,size:`sub`,children:[(0,c.jsx)(s.TabItem,{badgeCount:E?void 0:A.length,children:`待簽核`},`pending`),(0,c.jsx)(s.TabItem,{badgeCount:E?void 0:U.length,children:`已處理未結束`},`tracking`),(0,c.jsx)(s.TabItem,{children:`歷史簽核記錄`},`history`)]}),_===`pending`&&(M.length>0||F)?(0,c.jsxs)(`div`,{"data-returned-instances":``,style:p,children:[M.length>0?(0,c.jsx)(s.Typography,{component:`h2`,variant:`label-primary`,children:`被退回待重送`}):null,(0,c.jsx)(s.Typography,{color:`text-neutral`,variant:`caption`,children:h(M.length>0,F)}),M.length>0?(0,c.jsx)(s.Table,{actions:B,columns:z,dataSource:[...M],fullWidth:!0}):null]}):null,_===`pending`?(0,c.jsx)(s.Table,{actions:R,columns:L,dataSource:A,fullWidth:!0,loading:E}):null,_===`tracking`?(0,c.jsx)(s.Table,{actions:H,columns:V,dataSource:U,fullWidth:!0,loading:E}):null,_===`history`?(0,c.jsx)(s.Table,{actions:H,columns:V,dataSource:C,fullWidth:!0,loading:E}):null]})})]})}function h(e,t){return e?t?`你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。`:`你發起的案件被退回,請修改後重新送出。`:`前 ${f} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`}async function g(e){try{let t=await(0,l.listApprovalInstancesPage)({page:1,pageSize:f,searchText:null,state:`RETURNED`,templateId:null,view:`SENT`});return{rows:_(t.instances,e),truncated:t.totalCount>t.instances.length}}catch{return null}}function _(e,t){return e.filter(e=>e.initiatorMemberId===t).map(e=>({caseTitle:(0,l.readApprovalInstanceCaseTitle)(e),id:e.id,key:e.id,startedAt:e.startedAt}))}async function v(e){let t=await b(e);return e.map((e,n)=>({...e,caseTitle:x(e,t[n]??null),key:e.id,nodeText:a.t(e),slaStatusColor:j(e.slaDueAt),slaStatusText:A(e.slaDueAt),statusLabel:N(e.status)}))}async function y(e){let[t,n]=await Promise.all([Promise.all(e.map(e=>(0,l.listTaskDecisions)(e.id))),b(e)]);return e.map((e,r)=>{let i=S(t[r]??[]),o=n[r]??null;return{...e,caseTitle:x(e,o),decisionAction:i?.action??null,decisionComment:i?.comment??null,decisionCommentText:O(i?.comment??null),decisionLabel:w(i?.action??null),decidedAt:i?.decidedAt??e.completedAt,instanceState:o?.state??null,instanceStateLabel:E(o?.state??null),key:e.id,nodeText:a.t(e)}})}async function b(e){return Promise.all(e.map(async e=>{try{return(await(0,l.readApprovalInstance)(e.instanceId)).instance}catch{return null}}))}function x(e,t){return t?(0,l.readApprovalInstanceCaseTitle)(t):e.instanceId}function S(e){return[...e].sort(C)[0]??null}function C(e,t){return new Date(t.decidedAt).getTime()-new Date(e.decidedAt).getTime()}function w(e){return e===`APPROVED`?`同意`:e===`REJECTED`?`拒絕`:e===`RETURNED`?`退回`:e===`TRANSFERRED`?`轉派`:`未記錄`}function T(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`RETURNED`?`text-error`:`text-neutral`}function E(e){return e===`RUNNING`?`進行中`:e===`APPROVED`?`已通過`:e===`REJECTED`?`已拒絕`:e===`RETURNED`?`已退回`:e===`CANCELLED`?`已取消`:e===`EXPIRED`?`已逾期`:e===`DRAFT`?`草稿`:`-`}function D(e){return e===`APPROVED`?`text-success`:e===`REJECTED`||e===`CANCELLED`||e===`EXPIRED`?`text-error`:`text-neutral`}function O(e){return(e?.trim()??``)||`-`}function k(e){return r.t(e)}function A(e){if(!e)return`-`;let t=new Date(e).getTime(),n=Date.now(),r=M(Math.abs(t-n));return t<n?`已逾期 ${r}`:`剩餘 ${r}`}function j(e){return e?new Date(e).getTime()<Date.now()?`text-error`:`text-success`:`text-neutral`}function M(e){let t=Math.max(1,Math.ceil(e/6e4)),n=Math.floor(t/1440),r=Math.floor(t%1440/60),i=t%60;return n>0?`${n}天 ${r}小時`:r>0?`${r}小時 ${i}分鐘`:`${i}分鐘`}function N(e){return e===`PENDING`?`待處理`:e===`IN_PROGRESS`?`處理中`:e===`COMPLETED`?`已完成`:e===`TRANSFERRED`?`已轉派`:e===`CANCELLED`?`已取消`:e}function P(e){return e instanceof Error?e.message:`發生未知錯誤`}exports.InboxView=m;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","Badge","Typography","formatDateTime","listInboxTasks","listApprovalHistoryTasks","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","readTaskNodeText","listTaskDecisions","readApprovalInstance","readApprovalInstanceCaseTitle","require_rolldown_runtime","require_router_adapter","require_auth_provider","require_format_date_time","require_routes_config","require_task_node_label","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","refreshTasks","pendingColumns","record","pendingTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","instances","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decision","readLatestTaskDecision","instance","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","decisions","compareTaskDecisionDesc","right","left","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport { type Key, ReactElement, useEffect, useMemo, useState } from 'react';\nimport {\n Badge,\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n listApprovalHistoryTasks,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'fill',\n // Approving one of these needs the case page, where the fill is entered.\n render: (record: InboxTaskRow): ReactElement | null =>\n record.hasFillableFields ? (\n <Badge size=\"sub\" text=\"需補填\" variant=\"dot-warning\" />\n ) : null,\n title: '補填',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks] = await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["useRouterAdapter","useBPMRoutes","useAuth","useState","useMemo","Badge","Typography","formatDateTime","listInboxTasks","listApprovalHistoryTasks","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Tab","TabItem","Table","listApprovalInstancesPage","readApprovalInstanceCaseTitle","readTaskNodeText","listTaskDecisions","readApprovalInstance","require_rolldown_runtime","require_router_adapter","require_auth_provider","require_format_date_time","require_routes_config","require_task_node_label","react","_mezzanine_ui_react","react_jsx_runtime","_rytass_bpm_core_client_workflow","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","RETURNED_INSTANCE_PAGE_SIZE","RETURNED_SECTION_STYLE","InboxView","router","routes","currentMemberId","member","activeTab","setActiveTab","error","setError","historyRows","setHistoryRows","loading","setLoading","pendingRows","setPendingRows","returnedRows","setReturnedRows","returnedTruncated","setReturnedTruncated","refreshTasks","pendingColumns","record","pendingTableActions","returnedColumns","returnedTableActions","historyColumns","readTaskDecisionColor","readInstanceStateColor","formatHistoryDateTime","historyTableActions","trackingRows","row","handleTabChange","activeKey","nextPendingTasks","nextHistoryTasks","returned","readReturnedInstances","nextPendingRows","nextHistoryRows","readInboxTaskRows","readApprovalHistoryRows","requestError","readErrorMessage","readReturnedSectionHint","hasRows","truncated","page","readReturnedInstanceRows","instances","instance","readTaskInstances","tasks","task","readTaskCaseTitle","index","readSlaStatusColor","readSlaStatusText","readTaskStatusLabel","decisionLists","decision","readLatestTaskDecision","readDecisionCommentText","readTaskDecisionLabel","readInstanceStateLabel","decisions","compareTaskDecisionDesc","right","left","action","state","comment","value","dueAt","now","label","formatDuration","totalMinutes","days","hours","minutes","status"],"sources":["../../../src/views/inbox/InboxView.tsx"],"sourcesContent":["'use client';\n\nimport {\n type CSSProperties,\n type Key,\n ReactElement,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n PageHeader,\n Section,\n SectionGroup,\n Tab,\n TabItem,\n Table,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport {\n ApprovalInstanceRecord,\n type ApprovalInstancesPageResult,\n listApprovalHistoryTasks,\n listApprovalInstancesPage,\n listInboxTasks,\n listTaskDecisions,\n readApprovalInstance,\n readApprovalInstanceCaseTitle,\n TaskDecisionRecord,\n TaskRecord,\n} from '@rytass/bpm-core-client/workflow';\nimport { formatDateTime } from '../../lib/format-date-time';\nimport { useAuth } from '../../lib/auth-provider';\nimport { readTaskNodeText } from '../../lib/task-node-label';\nimport { useRouterAdapter } from '../../lib/router-adapter';\nimport { useBPMRoutes } from '../../lib/routes-config';\n\ntype InboxTabKey = 'history' | 'pending' | 'tracking';\n\ntype InboxTaskRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n key: string;\n nodeText: string;\n slaStatusColor: 'text-error' | 'text-neutral' | 'text-success';\n slaStatusText: string;\n statusLabel: string;\n }\n>;\n\ntype ReturnedInstanceRow = Readonly<{\n caseTitle: string;\n id: string;\n key: string;\n startedAt: string | null;\n}>;\n\n/** The server caps a page at 100; more than that is left to 我發起的. */\nconst RETURNED_INSTANCE_PAGE_SIZE = 100;\n\nconst RETURNED_SECTION_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n marginBottom: 'var(--mzn-spacing-padding-vertical-spacious)',\n};\n\ntype ApprovalHistoryRow = Readonly<\n Record<string, unknown> &\n TaskRecord & {\n caseTitle: string;\n decisionAction: TaskDecisionRecord['action'] | null;\n decisionComment: string | null;\n decisionCommentText: string;\n decisionLabel: string;\n decidedAt: string | null;\n instanceState: ApprovalInstanceRecord['state'] | null;\n instanceStateLabel: string;\n key: string;\n nodeText: string;\n }\n>;\n\n\n/**\n * Framework-agnostic view for the BPM \"我的待簽\" inbox. Mechanical port of\n * `apps/client/src/app/inbox/page.tsx` — renders pending tasks, tracking,\n * and history tabs.\n */\nexport function InboxView(): ReactElement {\n const router = useRouterAdapter();\n const routes = useBPMRoutes();\n const { member } = useAuth();\n const currentMemberId = member?.memberId ?? null;\n const [activeTab, setActiveTab] = useState<InboxTabKey>('pending');\n const [error, setError] = useState<string | null>(null);\n const [historyRows, setHistoryRows] = useState<ApprovalHistoryRow[]>([]);\n const [loading, setLoading] = useState(true);\n const [pendingRows, setPendingRows] = useState<InboxTaskRow[]>([]);\n const [returnedRows, setReturnedRows] = useState<\n readonly ReturnedInstanceRow[]\n >([]);\n const [returnedTruncated, setReturnedTruncated] = useState(false);\n\n useEffect((): void => {\n if (!currentMemberId) {\n return;\n }\n\n void refreshTasks();\n }, [currentMemberId]);\n\n const pendingColumns = useMemo(\n (): TableColumn<InboxTaskRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n dataIndex: 'statusLabel',\n key: 'statusLabel',\n title: '狀態',\n width: 120,\n },\n {\n key: 'fill',\n // Approving one of these needs the case page, where the fill is entered.\n render: (record: InboxTaskRow): ReactElement | null =>\n record.hasFillableFields ? (\n <Badge size=\"sub\" text=\"需補填\" variant=\"dot-warning\" />\n ) : null,\n title: '補填',\n width: 120,\n },\n {\n key: 'slaDueAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography\n color={record.slaStatusColor}\n component=\"span\"\n variant=\"body\"\n >\n {record.slaStatusText}\n </Typography>\n ),\n title: 'SLA',\n width: 180,\n },\n {\n key: 'createdAt',\n render: (record: InboxTaskRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.createdAt)}\n </Typography>\n ),\n title: '建立時間',\n width: 220,\n },\n ],\n [],\n );\n const pendingTableActions = useMemo(\n (): TableActions<InboxTaskRow> => ({\n render: (record): ReturnType<TableActions<InboxTaskRow>['render']> => [\n {\n name: '處理',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const returnedColumns = useMemo(\n (): TableColumn<ReturnedInstanceRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n {\n key: 'startedAt',\n render: (record: ReturnedInstanceRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(record.startedAt)}\n </Typography>\n ),\n title: '發起時間',\n width: 220,\n },\n ],\n [],\n );\n const returnedTableActions = useMemo(\n (): TableActions<ReturnedInstanceRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ReturnedInstanceRow>['render']> => [\n {\n name: '重新送出',\n onClick: (): void => router.push(routes.caseDetail(record.id)),\n },\n ],\n variant: 'base-secondary',\n width: 120,\n }),\n [router, routes],\n );\n const historyColumns = useMemo(\n (): TableColumn<ApprovalHistoryRow>[] => [\n { dataIndex: 'caseTitle', key: 'caseTitle', title: '案件', width: 280 },\n { dataIndex: 'nodeText', key: 'nodeText', title: '節點', width: 180 },\n {\n key: 'decisionLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readTaskDecisionColor(record.decisionAction)}\n component=\"span\"\n variant=\"body\"\n >\n {record.decisionLabel}\n </Typography>\n ),\n title: '決議',\n width: 120,\n },\n {\n key: 'decisionComment',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {record.decisionCommentText}\n </Typography>\n ),\n title: '意見',\n width: 240,\n },\n {\n key: 'instanceStateLabel',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography\n color={readInstanceStateColor(record.instanceState)}\n component=\"span\"\n variant=\"body\"\n >\n {record.instanceStateLabel}\n </Typography>\n ),\n title: '流程狀態',\n width: 140,\n },\n {\n key: 'decidedAt',\n render: (record: ApprovalHistoryRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatHistoryDateTime(record.decidedAt)}\n </Typography>\n ),\n title: '簽核時間',\n width: 220,\n },\n ],\n [],\n );\n const historyTableActions = useMemo(\n (): TableActions<ApprovalHistoryRow> => ({\n render: (\n record,\n ): ReturnType<TableActions<ApprovalHistoryRow>['render']> => [\n {\n name: '查看',\n onClick: (): void => router.push(routes.caseDetail(record.instanceId)),\n },\n ],\n variant: 'base-secondary',\n width: 88,\n }),\n [router, routes],\n );\n const trackingRows = useMemo(\n (): ApprovalHistoryRow[] =>\n historyRows.filter((row) => row.instanceState === 'RUNNING'),\n [historyRows],\n );\n\n function handleTabChange(activeKey: Key): void {\n if (\n activeKey === 'history' ||\n activeKey === 'pending' ||\n activeKey === 'tracking'\n ) {\n setActiveTab(activeKey);\n return;\n }\n\n setActiveTab('pending');\n }\n\n async function refreshTasks(): Promise<void> {\n setLoading(true);\n setError(null);\n\n try {\n if (!currentMemberId) {\n setPendingRows([]);\n setHistoryRows([]);\n setReturnedRows([]);\n setReturnedTruncated(false);\n return;\n }\n\n const [nextPendingTasks, nextHistoryTasks, returned] =\n await Promise.all([\n listInboxTasks(currentMemberId),\n listApprovalHistoryTasks(currentMemberId),\n readReturnedInstances(currentMemberId),\n ]);\n const [nextPendingRows, nextHistoryRows] = await Promise.all([\n readInboxTaskRows(nextPendingTasks),\n readApprovalHistoryRows(nextHistoryTasks),\n ]);\n\n setPendingRows(nextPendingRows);\n setHistoryRows(nextHistoryRows);\n setReturnedRows(returned?.rows ?? []);\n setReturnedTruncated(returned?.truncated ?? false);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description={`目前以 ${member?.name ?? currentMemberId ?? '目前登入會員'} 查詢待處理與歷史簽核任務。`}\n title=\"我的待簽\"\n >\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => router.push(routes.caseNew())}\n variant=\"base-primary\"\n >\n 發起簽核\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n <Tab activeKey={activeTab} onChange={handleTabChange} size=\"sub\">\n <TabItem\n badgeCount={loading ? undefined : pendingRows.length}\n key=\"pending\"\n >\n 待簽核\n </TabItem>\n <TabItem\n badgeCount={loading ? undefined : trackingRows.length}\n key=\"tracking\"\n >\n 已處理未結束\n </TabItem>\n <TabItem key=\"history\">歷史簽核記錄</TabItem>\n </Tab>\n\n {/* A truncated page with none of the member's own cases still\n points to 我發起的: theirs may sit past the first page. */}\n {activeTab === 'pending' &&\n (returnedRows.length > 0 || returnedTruncated) ? (\n <div data-returned-instances=\"\" style={RETURNED_SECTION_STYLE}>\n {/* Without rows there is nothing here to resubmit, only the\n pointer to 我發起的. */}\n {returnedRows.length > 0 ? (\n <Typography component=\"h2\" variant=\"label-primary\">\n 被退回待重送\n </Typography>\n ) : null}\n <Typography color=\"text-neutral\" variant=\"caption\">\n {readReturnedSectionHint(\n returnedRows.length > 0,\n returnedTruncated,\n )}\n </Typography>\n {returnedRows.length > 0 ? (\n <Table\n actions={returnedTableActions}\n columns={returnedColumns}\n dataSource={[...returnedRows]}\n fullWidth\n />\n ) : null}\n </div>\n ) : null}\n {activeTab === 'pending' ? (\n <Table\n actions={pendingTableActions}\n columns={pendingColumns}\n dataSource={pendingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'tracking' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={trackingRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n {activeTab === 'history' ? (\n <Table\n actions={historyTableActions}\n columns={historyColumns}\n dataSource={historyRows}\n fullWidth\n loading={loading}\n />\n ) : null}\n </Section>\n </SectionGroup>\n </>\n );\n}\n\nfunction readReturnedSectionHint(\n hasRows: boolean,\n truncated: boolean,\n): string {\n if (!hasRows) {\n return `前 ${RETURNED_INSTANCE_PAGE_SIZE} 筆被退回的案件中沒有你發起的,可能還有其他被退回的案件,請到「我發起的」查看。`;\n }\n\n return truncated\n ? '你發起的案件被退回,請修改後重新送出。可能還有其他被退回的案件,請到「我發起的」查看。'\n : '你發起的案件被退回,請修改後重新送出。';\n}\n\n/**\n * Returned cases are a side list: a failure here, in the request or in reading\n * its rows, hides that section instead of taking the pending and history tasks\n * down with it.\n */\nasync function readReturnedInstances(\n currentMemberId: string,\n): Promise<Readonly<{\n rows: readonly ReturnedInstanceRow[];\n truncated: boolean;\n}> | null> {\n try {\n // SENT also lists cases filed on someone else's behalf; only the\n // initiator may resubmit, so those are filtered out here.\n const page: ApprovalInstancesPageResult = await listApprovalInstancesPage({\n page: 1,\n pageSize: RETURNED_INSTANCE_PAGE_SIZE,\n searchText: null,\n state: 'RETURNED',\n templateId: null,\n view: 'SENT',\n });\n\n return {\n rows: readReturnedInstanceRows(page.instances, currentMemberId),\n // The total includes cases filed for someone else, so compare it with\n // what this page fetched rather than with the rows kept.\n truncated: page.totalCount > page.instances.length,\n };\n } catch {\n return null;\n }\n}\n\nfunction readReturnedInstanceRows(\n instances: readonly ApprovalInstanceRecord[],\n currentMemberId: string,\n): readonly ReturnedInstanceRow[] {\n return instances\n .filter(\n (instance): boolean => instance.initiatorMemberId === currentMemberId,\n )\n .map(\n (instance): ReturnedInstanceRow => ({\n caseTitle: readApprovalInstanceCaseTitle(instance),\n id: instance.id,\n key: instance.id,\n startedAt: instance.startedAt,\n }),\n );\n}\n\nasync function readInboxTaskRows(\n tasks: readonly TaskRecord[],\n): Promise<InboxTaskRow[]> {\n const instances = await readTaskInstances(tasks);\n\n return tasks.map(\n (task, index): InboxTaskRow => ({\n ...task,\n caseTitle: readTaskCaseTitle(task, instances[index] ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n slaStatusColor: readSlaStatusColor(task.slaDueAt),\n slaStatusText: readSlaStatusText(task.slaDueAt),\n statusLabel: readTaskStatusLabel(task.status),\n }),\n );\n}\n\nasync function readApprovalHistoryRows(\n tasks: readonly TaskRecord[],\n): Promise<ApprovalHistoryRow[]> {\n const [decisionLists, instances] = await Promise.all([\n Promise.all(tasks.map((task) => listTaskDecisions(task.id))),\n readTaskInstances(tasks),\n ]);\n\n return tasks.map((task, index): ApprovalHistoryRow => {\n const decision = readLatestTaskDecision(decisionLists[index] ?? []);\n const instance = instances[index] ?? null;\n\n return {\n ...task,\n caseTitle: readTaskCaseTitle(task, instance),\n decisionAction: decision?.action ?? null,\n decisionComment: decision?.comment ?? null,\n decisionCommentText: readDecisionCommentText(decision?.comment ?? null),\n decisionLabel: readTaskDecisionLabel(decision?.action ?? null),\n decidedAt: decision?.decidedAt ?? task.completedAt,\n instanceState: instance?.state ?? null,\n instanceStateLabel: readInstanceStateLabel(instance?.state ?? null),\n key: task.id,\n nodeText: readTaskNodeText(task),\n };\n });\n}\n\nasync function readTaskInstances(\n tasks: readonly TaskRecord[],\n): Promise<readonly (ApprovalInstanceRecord | null)[]> {\n return Promise.all(\n tasks.map(async (task): Promise<ApprovalInstanceRecord | null> => {\n try {\n return (await readApprovalInstance(task.instanceId)).instance;\n } catch {\n return null;\n }\n }),\n );\n}\n\nfunction readTaskCaseTitle(\n task: TaskRecord,\n instance: ApprovalInstanceRecord | null,\n): string {\n return instance ? readApprovalInstanceCaseTitle(instance) : task.instanceId;\n}\n\nfunction readLatestTaskDecision(\n decisions: readonly TaskDecisionRecord[],\n): TaskDecisionRecord | null {\n return [...decisions].sort(compareTaskDecisionDesc)[0] ?? null;\n}\n\nfunction compareTaskDecisionDesc(\n left: TaskDecisionRecord,\n right: TaskDecisionRecord,\n): number {\n return (\n new Date(right.decidedAt).getTime() - new Date(left.decidedAt).getTime()\n );\n}\n\nfunction readTaskDecisionLabel(\n action: TaskDecisionRecord['action'] | null,\n): string {\n if (action === 'APPROVED') {\n return '同意';\n }\n\n if (action === 'REJECTED') {\n return '拒絕';\n }\n\n if (action === 'RETURNED') {\n return '退回';\n }\n\n if (action === 'TRANSFERRED') {\n return '轉派';\n }\n\n return '未記錄';\n}\n\nfunction readTaskDecisionColor(\n action: TaskDecisionRecord['action'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (action === 'APPROVED') {\n return 'text-success';\n }\n\n if (action === 'REJECTED' || action === 'RETURNED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readInstanceStateLabel(\n state: ApprovalInstanceRecord['state'] | null,\n): string {\n if (state === 'RUNNING') {\n return '進行中';\n }\n\n if (state === 'APPROVED') {\n return '已通過';\n }\n\n if (state === 'REJECTED') {\n return '已拒絕';\n }\n\n if (state === 'RETURNED') {\n return '已退回';\n }\n\n if (state === 'CANCELLED') {\n return '已取消';\n }\n\n if (state === 'EXPIRED') {\n return '已逾期';\n }\n\n if (state === 'DRAFT') {\n return '草稿';\n }\n\n return '-';\n}\n\nfunction readInstanceStateColor(\n state: ApprovalInstanceRecord['state'] | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (state === 'APPROVED') {\n return 'text-success';\n }\n\n if (state === 'REJECTED' || state === 'CANCELLED' || state === 'EXPIRED') {\n return 'text-error';\n }\n\n return 'text-neutral';\n}\n\nfunction readDecisionCommentText(comment: string | null): string {\n const trimmedComment = comment?.trim() ?? '';\n\n return trimmedComment || '-';\n}\n\nfunction formatHistoryDateTime(value: string | null): string {\n return formatDateTime(value);\n}\n\nfunction readSlaStatusText(value: string | null): string {\n if (!value) {\n return '-';\n }\n\n const dueAt = new Date(value).getTime();\n const now = Date.now();\n const diffMs = Math.abs(dueAt - now);\n const label = formatDuration(diffMs);\n\n return dueAt < now ? `已逾期 ${label}` : `剩餘 ${label}`;\n}\n\nfunction readSlaStatusColor(\n value: string | null,\n): 'text-error' | 'text-neutral' | 'text-success' {\n if (!value) {\n return 'text-neutral';\n }\n\n return new Date(value).getTime() < Date.now() ? 'text-error' : 'text-success';\n}\n\nfunction formatDuration(value: number): string {\n const totalMinutes = Math.max(1, Math.ceil(value / 60_000));\n const days = Math.floor(totalMinutes / 1440);\n const hours = Math.floor((totalMinutes % 1440) / 60);\n const minutes = totalMinutes % 60;\n\n if (days > 0) {\n return `${days}天 ${hours}小時`;\n }\n\n if (hours > 0) {\n return `${hours}小時 ${minutes}分鐘`;\n }\n\n return `${minutes}分鐘`;\n}\n\nfunction readTaskStatusLabel(status: TaskRecord['status']): string {\n if (status === 'PENDING') {\n return '待處理';\n }\n\n if (status === 'IN_PROGRESS') {\n return '處理中';\n }\n\n if (status === 'COMPLETED') {\n return '已完成';\n }\n\n if (status === 'TRANSFERRED') {\n return '已轉派';\n }\n\n if (status === 'CANCELLED') {\n return '已取消';\n }\n\n return status;\n}\n\nfunction readErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : '發生未知錯誤';\n}\n"],"mappings":"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"}
|