@fudanda/admin-antd 2.20261107.1-beta.1 → 2.20261109.1-beta.2
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/dist/chunks/ApiTokensPage-w3JGRNQC.js +2 -0
- package/dist/chunks/ApiTokensPage-w3JGRNQC.js.map +1 -0
- package/dist/chunks/{App-BF96TQ_D.js → App-nh6_qOo8.js} +5 -5
- package/dist/chunks/{App-BF96TQ_D.js.map → App-nh6_qOo8.js.map} +1 -1
- package/dist/chunks/{AppModal-CLkMJ-96.js → AppModal-CEouaU03.js} +2 -2
- package/dist/chunks/{AppModal-CLkMJ-96.js.map → AppModal-CEouaU03.js.map} +1 -1
- package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js → ArcBaseAdmin-CX7fQz4x.js} +2 -2
- package/dist/chunks/{ArcBaseAdmin--xQxd4tg.js.map → ArcBaseAdmin-CX7fQz4x.js.map} +1 -1
- package/dist/chunks/{DepartmentsPage-D6YVegPU.js → DepartmentsPage-BdD9VfDI.js} +2 -2
- package/dist/chunks/{DepartmentsPage-D6YVegPU.js.map → DepartmentsPage-BdD9VfDI.js.map} +1 -1
- package/dist/chunks/{DictsPage-uV3Uukwc.js → DictsPage-fxBdV1-3.js} +2 -2
- package/dist/chunks/{DictsPage-uV3Uukwc.js.map → DictsPage-fxBdV1-3.js.map} +1 -1
- package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js → EntityContextRuntime-CMhoj6qe.js} +2 -2
- package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js.map → EntityContextRuntime-CMhoj6qe.js.map} +1 -1
- package/dist/chunks/EntityContextRuntime-Dc89ZSnM.js +1 -0
- package/dist/chunks/{ExportButton-e2ybxuHb.js → ExportButton-DGxB2tcu.js} +2 -2
- package/dist/chunks/{ExportButton-e2ybxuHb.js.map → ExportButton-DGxB2tcu.js.map} +1 -1
- package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js → FileViewerPreviewPanel-BMZ7FdKV.js} +3 -3
- package/dist/chunks/{FileViewerPreviewPanel-BhI3pTi8.js.map → FileViewerPreviewPanel-BMZ7FdKV.js.map} +1 -1
- package/dist/chunks/{FilesPage-BI35mStl.js → FilesPage-DrgWELKy.js} +3 -3
- package/dist/chunks/{FilesPage-BI35mStl.js.map → FilesPage-DrgWELKy.js.map} +1 -1
- package/dist/chunks/IdentitySecurityPage-BjTKvr-O.js +9 -0
- package/dist/chunks/IdentitySecurityPage-BjTKvr-O.js.map +1 -0
- package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js → LogStatsScaffold-DaB0JeAN.js} +2 -2
- package/dist/chunks/{LogStatsScaffold-m0vVUXPh.js.map → LogStatsScaffold-DaB0JeAN.js.map} +1 -1
- package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js → LoginLogsPage-VmYC7i6q.js} +2 -2
- package/dist/chunks/{LoginLogsPage-BzBUR4Oo.js.map → LoginLogsPage-VmYC7i6q.js.map} +1 -1
- package/dist/chunks/{LoginLogsTable-BweUEjQX.js → LoginLogsTable-CULcc_e8.js} +2 -2
- package/dist/chunks/{LoginLogsTable-BweUEjQX.js.map → LoginLogsTable-CULcc_e8.js.map} +1 -1
- package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js → MarkdownPreviewPanel-CBcPc7Wv.js} +2 -2
- package/dist/chunks/{MarkdownPreviewPanel-C1OKSLmh.js.map → MarkdownPreviewPanel-CBcPc7Wv.js.map} +1 -1
- package/dist/chunks/{MasterDetailLayout-KVizcSNO.js → MasterDetailLayout-ByIBpmkZ.js} +2 -2
- package/dist/chunks/{MasterDetailLayout-KVizcSNO.js.map → MasterDetailLayout-ByIBpmkZ.js.map} +1 -1
- package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js → McpSettingsPage-C5V_rj2V.js} +2 -2
- package/dist/chunks/{McpSettingsPage-Dhf0CbDN.js.map → McpSettingsPage-C5V_rj2V.js.map} +1 -1
- package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js → MemberAssignmentSheet-DL0fg1Yf.js} +2 -2
- package/dist/chunks/{MemberAssignmentSheet-TYpnyA0z.js.map → MemberAssignmentSheet-DL0fg1Yf.js.map} +1 -1
- package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js → MenuCommandPalette-C2PvK3Gh.js} +2 -2
- package/dist/chunks/{MenuCommandPalette-BcvpUfK7.js.map → MenuCommandPalette-C2PvK3Gh.js.map} +1 -1
- package/dist/chunks/{MenusPage-Dd7OLQYT.js → MenusPage-Bytd1HlW.js} +2 -2
- package/dist/chunks/{MenusPage-Dd7OLQYT.js.map → MenusPage-Bytd1HlW.js.map} +1 -1
- package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js → MonacoPreviewPanel-BZrNIcFZ.js} +2 -2
- package/dist/chunks/{MonacoPreviewPanel-BW1j3ZTF.js.map → MonacoPreviewPanel-BZrNIcFZ.js.map} +1 -1
- package/dist/chunks/{NavListPanel-Iz1RCkVw.js → NavListPanel-zwUDIYSP.js} +2 -2
- package/dist/chunks/{NavListPanel-Iz1RCkVw.js.map → NavListPanel-zwUDIYSP.js.map} +1 -1
- package/dist/chunks/{OperationLogsPage-Dt22tU4I.js → OperationLogsPage-D2BQdGNp.js} +2 -2
- package/dist/chunks/{OperationLogsPage-Dt22tU4I.js.map → OperationLogsPage-D2BQdGNp.js.map} +1 -1
- package/dist/chunks/{OperationLogsTable-B23Ry-2v.js → OperationLogsTable-DaaON4QR.js} +3 -3
- package/dist/chunks/{OperationLogsTable-B23Ry-2v.js.map → OperationLogsTable-DaaON4QR.js.map} +1 -1
- package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js → PDFPreviewPanel-CMmnWBKW.js} +3 -3
- package/dist/chunks/{PDFPreviewPanel-kBPz5dQr.js.map → PDFPreviewPanel-CMmnWBKW.js.map} +1 -1
- package/dist/chunks/{PositionsPage-BIKYQDB5.js → PositionsPage-CBZITssT.js} +2 -2
- package/dist/chunks/{PositionsPage-BIKYQDB5.js.map → PositionsPage-CBZITssT.js.map} +1 -1
- package/dist/chunks/{PreferencesSheetBody-D276rrp4.js → PreferencesSheetBody-B0poTPEA.js} +2 -2
- package/dist/chunks/{PreferencesSheetBody-D276rrp4.js.map → PreferencesSheetBody-B0poTPEA.js.map} +1 -1
- package/dist/chunks/{ProfilePage-DLftC6KZ.js → ProfilePage-DLhacdWt.js} +2 -2
- package/dist/chunks/{ProfilePage-DLftC6KZ.js.map → ProfilePage-DLhacdWt.js.map} +1 -1
- package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js → ProjectInfoPage-CJpGxpu5.js} +2 -2
- package/dist/chunks/{ProjectInfoPage-DkuBLC8t.js.map → ProjectInfoPage-CJpGxpu5.js.map} +1 -1
- package/dist/chunks/{RelationPanel-B4BeO0Bz.js → RelationPanel-BsbfEDo2.js} +2 -2
- package/dist/chunks/{RelationPanel-B4BeO0Bz.js.map → RelationPanel-BsbfEDo2.js.map} +1 -1
- package/dist/chunks/{RolesPage-BhltU2Qm.js → RolesPage-46dzdiah.js} +2 -2
- package/dist/chunks/{RolesPage-BhltU2Qm.js.map → RolesPage-46dzdiah.js.map} +1 -1
- package/dist/chunks/{SessionConflictModal-3R8jdYkI.js → SessionConflictModal-Bm38eExL.js} +2 -2
- package/dist/chunks/{SessionConflictModal-3R8jdYkI.js.map → SessionConflictModal-Bm38eExL.js.map} +1 -1
- package/dist/chunks/SettingModuleDetail-BjxUJeH5.js +17 -0
- package/dist/chunks/SettingModuleDetail-BjxUJeH5.js.map +1 -0
- package/dist/chunks/{SettingsPage-DMzeDrnc.js → SettingsPage-C32Vuizm.js} +2 -2
- package/dist/chunks/{SettingsPage-DMzeDrnc.js.map → SettingsPage-C32Vuizm.js.map} +1 -1
- package/dist/chunks/{StatCard-C0xSZyiS.js → StatCard-CRPfkSBY.js} +2 -2
- package/dist/chunks/{StatCard-C0xSZyiS.js.map → StatCard-CRPfkSBY.js.map} +1 -1
- package/dist/chunks/{UserGroupsPage-DTJdszHl.js → UserGroupsPage-08G5MdGm.js} +2 -2
- package/dist/chunks/{UserGroupsPage-DTJdszHl.js.map → UserGroupsPage-08G5MdGm.js.map} +1 -1
- package/dist/chunks/{UserLogsPanels-z4UhQtgu.js → UserLogsPanels-nbIrMym9.js} +2 -2
- package/dist/chunks/{UserLogsPanels-z4UhQtgu.js.map → UserLogsPanels-nbIrMym9.js.map} +1 -1
- package/dist/chunks/{UserTransferSelect-BJNUXMhl.js → UserTransferSelect-C8betaWG.js} +2 -2
- package/dist/chunks/{UserTransferSelect-BJNUXMhl.js.map → UserTransferSelect-C8betaWG.js.map} +1 -1
- package/dist/chunks/{UsersPage--p68X2Yr.js → UsersPage-BjTiNEqF.js} +2 -2
- package/dist/chunks/{UsersPage--p68X2Yr.js.map → UsersPage-BjTiNEqF.js.map} +1 -1
- package/dist/chunks/{browser-BKLM0ThC-3Xar5rZw.js → browser-BKLM0ThC-Cp7Gi4-F.js} +1 -1
- package/dist/chunks/{code-P0HJS_q1.js → code-LswxAr98.js} +1 -1
- package/dist/chunks/{direct-engine-BYEscsGg.js → direct-engine-Dv_6v4sx.js} +1 -1
- package/dist/chunks/{html-B__1Vr_C.js → html-BokjxlLb.js} +1 -1
- package/dist/chunks/{line-DzLRZVEq.js → line-Bqh6atHH.js} +1 -1
- package/dist/chunks/{lrc-kf-TilFB.js → lrc-T5e1svZG.js} +1 -1
- package/dist/chunks/{markdown-xIo-vnKK.js → markdown-BpWokN1s.js} +1 -1
- package/dist/chunks/{patch-BEaX-xYV.js → patch-BYVX5C9G.js} +1 -1
- package/dist/chunks/{worker-engine-FCdIQLzN.js → worker-engine-CtUAeI4G.js} +1 -1
- package/dist/core/hooks/queries/settings.d.ts +6 -0
- package/dist/core/hooks/queries/settings.d.ts.map +1 -1
- package/dist/core/hooks/queries/settings.js +34 -25
- package/dist/core/hooks/queries/settings.js.map +1 -1
- package/dist/core/hooks/useAuth.d.ts +2 -0
- package/dist/core/hooks/useAuth.d.ts.map +1 -1
- package/dist/core/hooks/useAuth.js.map +1 -1
- package/dist/core/index.js +7 -7
- package/dist/core/lib/go-auth-api.d.ts +1 -1
- package/dist/core/lib/go-auth-api.d.ts.map +1 -1
- package/dist/core/lib/go-auth-api.js +12 -8
- package/dist/core/lib/go-auth-api.js.map +1 -1
- package/dist/core/lib/native-operations.d.ts +85 -4
- package/dist/core/lib/native-operations.d.ts.map +1 -1
- package/dist/core/lib/native-operations.js +1 -0
- package/dist/core/lib/native-operations.js.map +1 -1
- package/dist/core/providers/GoAuthProvider.d.ts.map +1 -1
- package/dist/core/providers/GoAuthProvider.js +191 -142
- package/dist/core/providers/GoAuthProvider.js.map +1 -1
- package/dist/core/session-renewal.d.ts +15 -0
- package/dist/core/session-renewal.d.ts.map +1 -0
- package/dist/core/session-renewal.js +95 -0
- package/dist/core/session-renewal.js.map +1 -0
- package/dist/core/session-transition.d.ts +2 -0
- package/dist/core/session-transition.d.ts.map +1 -1
- package/dist/core/session-transition.js +20 -7
- package/dist/core/session-transition.js.map +1 -1
- package/dist/core/session.d.ts +4 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +88 -61
- package/dist/core/session.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{src-C8_bzBi4.js → src-D6UlLiVN.js} +2 -2
- package/dist/{src-C8_bzBi4.js.map → src-D6UlLiVN.js.map} +1 -1
- package/package.json +9 -9
- package/dist/chunks/ApiTokensPage-DiRMgViD.js +0 -2
- package/dist/chunks/ApiTokensPage-DiRMgViD.js.map +0 -1
- package/dist/chunks/EntityContextRuntime-BOJySc1D.js +0 -1
- package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js +0 -9
- package/dist/chunks/IdentitySecurityPage-DW5ybVL4.js.map +0 -1
- package/dist/chunks/SettingModuleDetail-Dppk9An1.js +0 -17
- package/dist/chunks/SettingModuleDetail-Dppk9An1.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DictsPage-uV3Uukwc.js","mappings":"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","names":["__iconData","__iconData$1","createLucideIcon","resolveExplicitDictionary","records","id","record","selectWebMcpDictionary","assertAllowed","execution","port","deadline","resolve","DictListCard","select","onSelect","dict","CheckCard","active","event","DateTimeText","Tag","extra","useDictItemModalDetail","useDictItemDetail","enabled","DictsPage","usePermission","jsonViewerRef","useRef","dicts","setDicts","useState","useListSearch","dictKeys","filterQuery","useFilterQuery","submittedParams","selectedDictKey","setSelectedDictKey","useUrlSelectionState","selectedDictDetail","setSelectedDictDetail","selectionRevision","itemParentId","setItemParentId","itemColor","setItemColor","metadataStr","setMetadataStr","statusItems","statusOptions","useDictItems","tagColor","color","isNarrowLayout","setIsNarrowLayout","dictListQuery","useDictList","total","explicitId","explicitIdValid","dictInPage","d","detachedDict","dictFallbackQuery","useDictDetail","selectedDict","activeDictId","committedDictId","useEffect","clearSelectedDictionary","itemsQuery","useDictItemsById","items","useMemo","itemSearch","defaultItemSearch","saveDictMutation","useSaveDict","dictModal","useEditModal","formSaveMutation","dictContract","values","editing","toggleDictStatusMutation","deleteDictMutation","useDeleteDicts","createItemMutation","useCreateDictItem","updateItemMutation","useUpdateDictItem","toggleItemStatusMutation","deleteItemMutation","useDeleteDictItem","togglingDictStatusId","itemModal","abortSubmit","item","metadata","currentJson","Toast","payload","editingItem","selectionBusy","useStandardWebMcpCrudAdapter","hasPermission","z.object","z.number","input","revision","api","recordId","itemId","isEdit","expandInitedDictIdRef","handleDictPageChange","setPage","nextPage","handleDictPageSizeChange","setPageSize","nextPageSize","selectDict","filteredItems","itemKeyword","itemStatusFilter","treeItems","filteredIds","i","buildChildren","c","grandchildren","children","useTreeExpansion","setExpandedRowKeys","allRowKeys","editingSubtreeIds","result","addDescendants","child","parentSelectorTreeData","buildTree","parentId","openEditDict","row","handleDictDelete","handleItemDelete","openCreateItem","openCreateChildItem","openEditItem","itemStatus","useStatusToggle","handleToggleDictStatus","newStatus","confirmDangerAsync","dictMaster","NavListPanel","Space","ExportButton","NavListItemActions","RefreshCw","Plus","draftParams","setField","handleSearch","Pagination","page","Pencil","Trash2","confirmDelete","operationColumn","useCrudOperationColumn","itemColumns","v","renderEllipsis","createdAtColumn","renderItemExpandButton","Button","jsx","isAllExpanded","ChevronsDownUp","ChevronsUpDown","toggleExpandAll","dictDetail","_Fragment","MasterDetailLayout","BookOpen","Switch","checked","ConfigurableTable","buildTableSearch","KeywordInput","StatusSelect","CreateButton","EditFormModal","Form","value","Row","Col","TreeSelect","val","TAG_COLORS","COLOR_LABELS","Select","option","style","selected","label","JsonViewer"],"ignoreList":[0,1],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/book-open.mjs","../../../../node_modules/lucide-react/dist/esm/icons/pencil.mjs","../../src/pages/system/dicts/webmcp-selection.ts","../../src/pages/system/dicts/DictListCard.tsx","../../src/pages/system/dicts/DictsPage.tsx"],"sourcesContent":[null,null,"import type { WebMcpExecutionContext } from '../../../webmcp-types';\n\n/** A detail fallback is usable only for the explicitly selected real record. */\nexport function resolveExplicitDictionary<T extends { id: number }>(id: number | undefined, ...records: readonly (T | null | undefined)[]): T | null {\n return id === undefined ? null : records.find(record => record?.id === id) ?? null;\n}\n\nexport async function selectWebMcpDictionary<T extends { id: number }>(id: number, execution: WebMcpExecutionContext, port: {\n read(id: number, signal: AbortSignal): Promise<T>;\n /** Live editor/mutation and concurrent/manual selection checks. */\n assertCanSelect(): void;\n commit(record: T): void;\n isCommitted(id: number): boolean;\n}): Promise<{ status: 'selected'; id: number }> {\n const assertAllowed = () => { execution.assertActive(); port.assertCanSelect(); };\n assertAllowed();\n // Fetch before touching selection: 403/404/network failures retain current UI.\n const record = await port.read(id, execution.signal);\n assertAllowed();\n if (!record || record.id !== id) throw new Error('字典详情与选择目标不匹配');\n port.commit(record);\n const deadline = Date.now() + 20_000;\n while (!port.isCommitted(id)) {\n assertAllowed();\n if (Date.now() >= deadline) throw new Error('字典选择尚未完成');\n await new Promise(resolve => setTimeout(resolve, 20));\n }\n assertAllowed();\n return { status: 'selected', id };\n}\n","import { CheckCard } from '@ant-design/pro-components';\nimport type { ReactNode } from 'react';\nimport type { Dict } from '@fudanda/shared/platform';\nimport { Tag } from '@/ui';\nimport DateTimeText from '@/components/DateTimeText';\n\nexport function DictListCard({ dict, active, onSelect, extra }: {\n dict: Dict;\n active: boolean;\n onSelect: (dict: Dict) => void;\n extra?: ReactNode;\n}) {\n const select = () => onSelect(dict);\n return <CheckCard\n className=\"dict-check-card\"\n value={dict.id}\n checked={active}\n onClick={select}\n style={dict.status === 'disabled' ? { opacity: 0.55 } : undefined}\n title={<button\n type=\"button\"\n className=\"dict-check-card__select\"\n aria-label={`${dict.name} ${dict.code}`}\n aria-current={active ? 'true' : undefined}\n onClick={event => { event.stopPropagation(); select(); }}\n >{dict.name}</button>}\n subTitle={<span className=\"dict-check-card__code\">{dict.code}</span>}\n description={<span className=\"dict-check-card__meta\">\n <DateTimeText value={dict.createdAt} />\n {dict.status === 'disabled' && <Tag size=\"small\" color=\"grey\">停用</Tag>}\n </span>}\n extra={extra === undefined ? undefined : <span onClick={event => event.stopPropagation()}>{extra}</span>}\n />;\n}\n","import type { ApiUpdateItemRequestBodyInput } from '@fudanda/shared/api/dictionaries';\nimport { dictContract } from '@fudanda/react-core/lib/native-operations';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { CheckCard } from '@ant-design/pro-components';\nimport type { ComponentProps } from 'react';\nimport { Button, Select, Tag, Form, Pagination, Toast, TreeSelect, JsonViewer, Row, Col, Space, Switch } from \"@/ui\";\nimport { Plus, BookOpen, ChevronsDownUp, ChevronsUpDown, RefreshCw, Pencil, Trash2 } from 'lucide-react';\nimport type { CreateDictInput, CreateDictItemInput, Dict, DictItem } from '@fudanda/shared/platform';\nimport ExportButton from \"@/components/ExportButton\";\nimport ConfigurableTable from \"@/components/ConfigurableTable\";\nimport { useListSearch } from \"@fudanda/react-core/hooks/useListSearch\";\nimport { useEditModal, formSaveMutation } from \"@/hooks/useEditModal\";\nimport { useTreeExpansion } from \"@fudanda/react-core/hooks/useTreeExpansion\";\nimport { useUrlSelectionState } from \"@fudanda/react-core/hooks/useUrlSelectionState\";\nimport { MasterDetailLayout } from \"@/components/MasterDetailLayout\";\nimport { NavListPanel, NavListItemActions } from \"@/components/NavListPanel\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\nimport type { ColumnProps } from \"@/ui\";\nimport { usePermission } from \"@fudanda/react-core/hooks/usePermission\";\nimport \"@/pages/system/dicts/DictsPage.css\";\nimport { createdAtColumn, renderEllipsis } from \"@/utils/table-columns\";\nimport { dictKeys, useCreateDictItem, useDeleteDictItem, useDeleteDicts, useDictDetail, useDictItemDetail, useDictItemsById, useDictList, useSaveDict, useUpdateDictItem } from \"@fudanda/react-core/hooks/queries/dicts\";\nimport { CreateButton } from \"@/components/toolbar-controls\";\nimport { confirmDelete, confirmDangerAsync } from \"@/utils/confirm\";\nimport { buildTableSearch, useStatusToggle, useCrudOperationColumn } from \"@/components/list-page/index\";\nimport { abortSubmit } from \"@fudanda/react-core/lib/abort-submit\";\nimport { KeywordInput, StatusSelect } from \"@/components/search-filters\";\nimport { useFilterQuery } from \"@fudanda/react-core/hooks/useFilterQuery\";\nimport { EditFormModal } from \"@/components/EditFormModal\";\nimport { useStandardWebMcpCrudAdapter } from '@/webmcp-crud';\nimport { api } from '@fudanda/react-core/lib/contract-query';\nimport { resolveExplicitDictionary, selectWebMcpDictionary } from './webmcp-selection';\nimport { DictListCard } from './DictListCard';\nimport * as z from 'zod';\ninterface ItemSearchParams {\n keyword: string;\n status?: string;\n}\nconst defaultItemSearch: ItemSearchParams = { keyword: '', status: undefined };\n/** 字典项详情按 (dictId, itemId) 取数;useEditModal 只传 itemId,所属字典从打开弹窗时的行记录取 */\nfunction useDictItemModalDetail(id: number | undefined, enabled?: boolean, record?: DictItem) {\n return useDictItemDetail(record?.dictId, id, enabled);\n}\nexport default function DictsPage() {\n const { hasPermission } = usePermission();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonViewerRef = useRef<any>(null);\n // ─── 字典列表 ──────────────────────────────────────────────────────────────\n const [dicts, setDicts] = useState<Dict[]>([]);\n const { page, pageSize, setPage, setPageSize, draftParams, setField, submittedParams, handleSearch, } = useListSearch<{\n keyword: string;\n }>({ defaults: { keyword: '' }, listKey: dictKeys.lists });\n // 已提交筛选 → 契约查询参数:列表与导出共用同一份映射\n const filterQuery = useFilterQuery({\n keyword: submittedParams.keyword,\n });\n // ─── 字典项列表 ────────────────────────────────────────────────────────────\n // 显式选中的字典以 `?dict=` 同步到 URL(深链/刷新/页签直达);选中对象按 key 派生\n const [selectedDictKey, setSelectedDictKey] = useUrlSelectionState('dict');\n const [selectedDictDetail, setSelectedDictDetail] = useState<Dict | null>(null);\n const selectionRevision = useRef(0);\n const [itemParentId, setItemParentId] = useState<number | null>(null);\n const [itemColor, setItemColor] = useState<string | null>(null);\n // metadataStr 仅用于 JsonViewer 的初始值(非受控),提交时通过 ref.getValue() 读取\n const [metadataStr, setMetadataStr] = useState<string>('{}');\n const { items: statusItems, options: statusOptions } = useDictItems('common_status');\n const tagColor = (color: string) => color as ComponentProps<typeof Tag>['color'];\n // 单栏(窄屏)下 showDetail 由 selectedDict 驱动,若沿用桌面端「默认选中第一项」\n // 会直接落到字典项详情,字典列表反而要点返回才能看到。布局形态参与选中派生,故用 state。\n const [isNarrowLayout, setIsNarrowLayout] = useState(false);\n // ─── 数据获取 ──────────────────────────────────────────────────────────────\n const dictListQuery = useDictList({\n page,\n pageSize,\n ...filterQuery,\n });\n const total = dictListQuery.data?.total ?? 0;\n // 选中派生:URL 深链值优先;无深链时桌面端回退首项(默认选中不入 URL),窄屏不自动选中。\n // 深链目标可能不在当前页/当前筛选(列表分页),成员资格不可当存在性判据,\n // 不在页内时按 id 拉详情兜底,仅确认无效(非法 id / 404)才清参回退\n const explicitId = selectedDictKey !== null ? Number(selectedDictKey) : undefined;\n const explicitIdValid = explicitId !== undefined && Number.isInteger(explicitId) && explicitId > 0;\n const dictInPage = explicitIdValid ? dicts.find((d) => d.id === explicitId) ?? null : null;\n const detachedDict = resolveExplicitDictionary(explicitId, selectedDictDetail);\n const dictFallbackQuery = useDictDetail(explicitId, explicitIdValid && !dictInPage && !detachedDict);\n const explicitDict = resolveExplicitDictionary(explicitId, dictInPage, detachedDict, dictFallbackQuery.data);\n const selectedDict = explicitDict ?? (isNarrowLayout ? null : dicts[0] ?? null);\n const activeDictId = useRef<number | undefined>(selectedDict?.id);\n const committedDictId = useRef<number | undefined>(selectedDict?.id);\n activeDictId.current = selectedDict?.id;\n useEffect(() => { committedDictId.current = selectedDict?.id; }, [selectedDict?.id]);\n useEffect(() => {\n if (selectedDictDetail && selectedDictKey !== String(selectedDictDetail.id)) setSelectedDictDetail(null);\n }, [selectedDictDetail, selectedDictKey]);\n const clearSelectedDictionary = () => { selectionRevision.current++; setSelectedDictDetail(null); setSelectedDictKey(null); };\n useEffect(() => {\n if (selectedDictKey === null)\n return;\n if (!explicitIdValid || !dictInPage && !detachedDict && dictFallbackQuery.isError)\n setSelectedDictKey(null);\n }, [selectedDictKey, explicitIdValid, dictInPage, detachedDict, dictFallbackQuery.isError, setSelectedDictKey]);\n const itemsQuery = useDictItemsById(selectedDict?.id);\n const items = useMemo(() => itemsQuery.data ?? [], [itemsQuery.data]);\n // 字典项全量取回后在客户端过滤:submittedParams 进过滤谓词,「查询 / 重置」仍回源刷新当前字典的项\n const itemSearch = useListSearch<ItemSearchParams>({ defaults: defaultItemSearch, listKey: dictKeys.items(selectedDict?.id) });\n const saveDictMutation = useSaveDict();\n const dictModal = useEditModal<Dict, Partial<CreateDictInput>>({\n entityName: '字典',\n save: formSaveMutation(saveDictMutation, { create: dictContract.create.input.shape.body, update: dictContract.update.input.shape.body }),\n useDetail: useDictDetail,\n defaults: { status: 'enabled' },\n toValues: dict => ({ name: dict.name, code: dict.code, description: dict.description, status: dict.status }),\n beforeSave: (values, { editing }) => ({ ...values, description: values.description || undefined, ...(editing ? { clearFields: values.description ? [] : ['description'] } : {}) }),\n });\n const toggleDictStatusMutation = useSaveDict();\n const deleteDictMutation = useDeleteDicts();\n const createItemMutation = useCreateDictItem();\n const updateItemMutation = useUpdateDictItem();\n const toggleItemStatusMutation = useUpdateDictItem();\n const deleteItemMutation = useDeleteDictItem();\n const togglingDictStatusId = toggleDictStatusMutation.isPending ? (toggleDictStatusMutation.variables?.id ?? null) : null;\n // 字典项是所选字典的子资源:创建 / 更新契约都绑定 dictId,由 save 适配层按是否有 id 分派;\n // 父级 / 颜色 / 元数据不在 Semi 表单内(Form.Slot 受控控件),在 beforeSave 合入载荷\n const itemModal = useEditModal<DictItem, Partial<CreateDictItemInput>, Partial<CreateDictItemInput> & ApiUpdateItemRequestBodyInput>({\n entityName: '字典项',\n save: {\n mutateAsync: ({ id, values }) => {\n if (!selectedDict)\n abortSubmit('validation');\n return id === undefined\n ? createItemMutation.mutateAsync({ params: { id: selectedDict.id }, body: dictContract.createItem.input.shape.body.parse(values) })\n : updateItemMutation.mutateAsync({ params: { id: selectedDict.id, itemId: id }, body: dictContract.updateItem.input.shape.body.parse(values) });\n },\n isPending: createItemMutation.isPending || updateItemMutation.isPending,\n },\n useDetail: useDictItemModalDetail,\n defaults: { status: 'enabled', sort: 0 },\n toValues: (item) => ({ label: item.label, value: item.value, sort: item.sort, status: item.status, remark: item.remark ?? undefined }),\n beforeSave: (values, { editing }) => {\n let metadata: unknown;\n const currentJson = (jsonViewerRef.current?.getValue() ?? metadataStr).trim();\n if (currentJson && currentJson !== '{}') {\n try {\n metadata = JSON.parse(currentJson);\n }\n catch {\n Toast.error('元数据 JSON 格式有误,请检查后重试');\n abortSubmit();\n }\n }\n // 表单值来自 Semi validate(),形状由表单字段决定;label / value 必填由表单 rules 保证\n const payload = { ...values, parentId: itemParentId ?? undefined, color: itemColor || undefined, remark: values.remark || undefined, metadata };\n return editing\n ? dictContract.updateItem.input.shape.body.parse({ ...payload, clearFields: [...(itemParentId == null ? ['parentId'] : []), ...(!itemColor ? ['color'] : []), ...(!values.remark ? ['remark'] : []), ...(metadata === undefined ? ['metadata'] : [])] })\n : dictContract.createItem.input.shape.body.parse(payload);\n },\n labelWidth: 72,\n });\n const editingItem = itemModal.editing;\n const selectionBusy = useRef(false);\n selectionBusy.current = dictModal.visible || itemModal.visible || dictModal.footerProps.loading || itemModal.footerProps.loading\n || saveDictMutation.isPending || createItemMutation.isPending || updateItemMutation.isPending || deleteDictMutation.isPending || deleteItemMutation.isPending\n || toggleDictStatusMutation.isPending || toggleItemStatusMutation.isPending;\n useStandardWebMcpCrudAdapter({ resource: 'dicts', title: '字典', permission: 'system:dict', hasPermission, modal: dictModal,\n list: dictContract.list, detail: dictContract.detail, create: dictContract.create.input.shape.body, update: dictContract.update.input.shape.body,\n fields: ['id', 'name', 'code', 'description', 'status', 'createdAt', 'updatedAt'], filters: filterQuery,\n remove: id => deleteDictMutation.mutateAsync([id]), onDeleted: clearSelectedDictionary,\n extraTools: hasPermission('system:dict:list') ? [{ name: 'arcbase_system_dicts_select', description: '选择字典以操作其字典项', kind: 'read', inputSchema: { type: 'object', properties: { id: { type: 'integer', minimum: 1 } }, required: ['id'], additionalProperties: false },\n parse: input => z.object({ id: z.number().int().positive() }).strict().parse(input), execute: async (input, execution) => {\n const id = (input as { id: number }).id;\n const revision = ++selectionRevision.current;\n return selectWebMcpDictionary(id, execution, {\n read: (recordId, signal) => api(dictContract.detail, { params: { id: recordId } }, { signal, silent: true }),\n assertCanSelect: () => {\n if (selectionRevision.current !== revision) throw new Error('字典选择已变更');\n if (selectionBusy.current) throw new Error('请先关闭字典或字典项编辑器并等待保存完成');\n },\n commit: record => { setSelectedDictDetail(record); setSelectedDictKey(String(record.id)); },\n isCommitted: recordId => activeDictId.current === recordId && committedDictId.current === recordId,\n });\n } }] : [] });\n useStandardWebMcpCrudAdapter({ resource: 'dict_items', title: '字典项', permission: 'system:dict', hasPermission, modal: itemModal,\n permissions: { list: 'system:dict:list', create: 'system:dict:item', update: 'system:dict:item', delete: 'system:dict:item' },\n list: dictContract.items, detail: dictContract.itemDetail, create: dictContract.createItem.input.shape.body, update: dictContract.updateItem.input.shape.body,\n fields: ['id', 'dictId', 'parentId', 'label', 'value', 'sort', 'status', 'color', 'remark', 'metadata', 'createdAt', 'updatedAt'],\n scope: selectedDict?.id, disabled: !selectedDict, filters: { ...itemSearch.submittedParams },\n params: itemId => ({ id: selectedDict?.id, ...(itemId === undefined ? {} : { itemId }) }),\n assertScope: () => { if (!selectedDict || activeDictId.current !== selectedDict.id) throw new Error('字典已切换,请重新调用'); },\n remove: itemId => deleteItemMutation.mutateAsync({ params: { id: selectedDict!.id, itemId } }),\n applyValues: (values, { isEdit }) => { if (!isEdit || 'parentId' in values) setItemParentId(values.parentId as number ?? null); if (!isEdit || 'color' in values) setItemColor(values.color as string ?? null); if (!isEdit || 'metadata' in values) setMetadataStr(values.metadata ? JSON.stringify(values.metadata, null, 2) : '{}'); } });\n useEffect(() => {\n if (!dictListQuery.data)\n return;\n setDicts(dictListQuery.data.list);\n }, [dictListQuery.data]);\n // 每个字典的条目首次加载完成时默认全展开;同一字典内(数据刷新 / keepAlive 页签切回)保持用户展开/折叠状态\n const expandInitedDictIdRef = useRef<number | null>(null);\n // 打开瞬间先按列表行占位,详情到达后(editing 切换为详情对象)用服务端值覆盖表单外的父级 / 颜色 / 元数据\n useEffect(() => {\n if (!editingItem)\n return;\n setItemParentId(editingItem.parentId ?? null);\n setItemColor(editingItem.color ?? null);\n setMetadataStr(editingItem.metadata ? JSON.stringify(editingItem.metadata, null, 2) : '{}');\n }, [editingItem]);\n const handleDictPageChange = (nextPage: number) => {\n setPage(nextPage);\n };\n const handleDictPageSizeChange = (nextPageSize: number) => {\n setPage(1);\n setPageSize(nextPageSize);\n };\n const selectDict = (dict: Dict) => {\n if (selectedDict?.id === dict.id) return;\n selectionRevision.current++;\n setSelectedDictDetail(null);\n setSelectedDictKey(String(dict.id));\n itemSearch.handleReset();\n };\n const filteredItems = useMemo(() => {\n const { keyword: itemKeyword, status: itemStatusFilter } = itemSearch.submittedParams;\n const flat = items.filter((item) => {\n if (itemKeyword && !item.label.includes(itemKeyword) && !item.value.includes(itemKeyword))\n return false;\n if (itemStatusFilter && item.status !== itemStatusFilter)\n return false;\n return true;\n });\n return flat;\n }, [items, itemSearch.submittedParams]);\n // 将扁平列表递归转为树结构,用于表格展示\n const treeItems = useMemo(() => {\n const filteredIds = new Set(filteredItems.map((i) => i.id));\n const buildChildren = (id: number): DictItem[] => filteredItems\n .filter((c) => c.parentId === id)\n .map((c) => {\n const grandchildren = buildChildren(c.id);\n return grandchildren.length > 0 ? { ...c, children: grandchildren } : c;\n });\n return filteredItems\n .filter((i) => !i.parentId || !filteredIds.has(i.parentId))\n .map((item) => {\n const children = buildChildren(item.id);\n return children.length > 0 ? { ...item, children } : item;\n });\n }, [filteredItems]);\n const { expandedRowKeys, setExpandedRowKeys, allRowKeys, isAllExpanded, toggleExpandAll, onExpandedRowsChange, } = useTreeExpansion(treeItems);\n useEffect(() => {\n if (!selectedDict || itemsQuery.data === undefined)\n return;\n if (expandInitedDictIdRef.current === selectedDict.id)\n return;\n expandInitedDictIdRef.current = selectedDict.id;\n setExpandedRowKeys(allRowKeys);\n }, [selectedDict, itemsQuery.data, allRowKeys, setExpandedRowKeys]);\n // 编辑项的子孙节点 id 集合(父级选择器中禁用,避免循环引用)\n const editingSubtreeIds = useMemo(() => {\n if (!editingItem)\n return new Set<number>();\n const result = new Set<number>([editingItem.id]);\n const addDescendants = (id: number) => {\n items.filter((i) => i.parentId === id).forEach((child) => {\n result.add(child.id);\n addDescendants(child.id);\n });\n };\n addDescendants(editingItem.id);\n return result;\n }, [editingItem, items]);\n // 父级选择器的树形数据(递归构建,排除编辑项及其子孙)\n const parentSelectorTreeData = useMemo(() => {\n type SNode = {\n label: string;\n value: number;\n key: string;\n disabled?: boolean;\n children?: SNode[];\n };\n const buildTree = (parentId: number | null): SNode[] => items\n .filter((i) => (i.parentId ?? null) === parentId)\n .map((item) => ({\n label: item.label,\n value: item.id,\n key: String(item.id),\n disabled: editingSubtreeIds.has(item.id),\n children: buildTree(item.id),\n }));\n return [\n { label: '无(根项目)', value: 0, key: '0' },\n ...buildTree(null),\n ];\n }, [items, editingSubtreeIds]);\n // ─── 字典 CRUD ─────────────────────────────────────────────────────────────\n const openEditDict = (row: Dict) => {\n dictModal.openEdit(row);\n };\n const handleDictDelete = async (id: number) => {\n await deleteDictMutation.mutateAsync([id]);\n Toast.success('删除成功');\n if (selectedDictKey === String(id)) {\n clearSelectedDictionary();\n }\n };\n // ─── 字典项 CRUD ───────────────────────────────────────────────────────────\n const handleItemDelete = async (id: number) => {\n if (!selectedDict)\n return;\n await deleteItemMutation.mutateAsync({ params: { id: selectedDict.id, itemId: id } });\n };\n const openCreateItem = (parentId: number | null = null) => {\n setItemParentId(parentId);\n setItemColor(null);\n setMetadataStr('{}');\n itemModal.openCreate();\n };\n const openCreateChildItem = (row: DictItem) => openCreateItem(row.id);\n const openEditItem = (row: DictItem) => {\n if (!selectedDict)\n return;\n setItemParentId(row.parentId ?? null);\n setItemColor(row.color ?? null);\n setMetadataStr(row.metadata ? JSON.stringify(row.metadata, null, 2) : '{}');\n itemModal.openEdit(row);\n };\n const itemStatus = useStatusToggle<DictItem>({\n toggle: (item, enabled) => {\n if (!selectedDict)\n return Promise.resolve();\n return toggleItemStatusMutation.mutateAsync({ params: { id: selectedDict.id, itemId: item.id }, body: { status: enabled ? 'enabled' : 'disabled' } });\n },\n confirmDisable: (item) => ({ danger: true, title: `确认禁用字典项「${item.label}」?`, okText: '确认禁用' }),\n disabled: !selectedDict || !hasPermission('system:dict:item'),\n });\n const handleToggleDictStatus = async (dict: Dict, newStatus: 'enabled' | 'disabled') => {\n if (newStatus === 'disabled') {\n const confirmed = await confirmDangerAsync({\n title: `确认禁用字典「${dict.name}」?`,\n okText: '确认禁用',\n });\n if (!confirmed)\n return;\n }\n await toggleDictStatusMutation.mutateAsync({ id: dict.id, values: { status: newStatus } });\n Toast.success(newStatus === 'enabled' ? '已启用' : '已禁用');\n };\n const renderDictListItem = (dict: Dict) => {\n const active = selectedDict?.id === dict.id;\n return (<DictListCard key={dict.id} dict={dict} active={active} onSelect={selectDict} extra={<NavListItemActions items={[\n { key: 'edit', label: '编辑', icon: <Pencil size={14}/>, hidden: !hasPermission('system:dict:update'), onClick: () => void openEditDict(dict) },\n {\n key: 'delete', label: '删除', icon: <Trash2 size={14}/>, danger: true, hidden: !hasPermission('system:dict:delete'),\n onClick: () => {\n confirmDelete({\n title: '确认删除此字典?',\n content: '字典下的所有字典项也将一并删除',\n onOk: () => handleDictDelete(dict.id),\n });\n },\n },\n ]}/>}/>);\n };\n const dictMaster = (<NavListPanel title=\"字典列表\" headerExtra={<Space spacing={6}>\n <ExportButton entity=\"system.dicts\" query={filterQuery}/>\n <NavListItemActions items={[\n { key: 'refresh', label: '刷新', icon: <RefreshCw size={14}/>, onClick: () => void dictListQuery.refetch() },\n { key: 'create', label: '新增字典', icon: <Plus size={14}/>, hidden: !hasPermission('system:dict:create'), onClick: dictModal.openCreate },\n ]}/>\n </Space>} search={{\n value: draftParams.keyword,\n onChange: setField('keyword'),\n placeholder: '名称/编码',\n onEnterPress: handleSearch,\n }} loading={dictListQuery.isLoading} footer={<Pagination size=\"small\" hoverShowPageSelect total={total} currentPage={page} pageSize={pageSize} pageSizeOpts={[10, 20, 50, 100]} showSizeChanger showTotal onPageChange={handleDictPageChange} onPageSizeChange={handleDictPageSizeChange}/>} rawBody>\n {dicts.length > 0 ? <CheckCard.Group className=\"dict-check-card-group\" value={selectedDict?.id} multiple={false}>\n {dicts.map(renderDictListItem)}\n </CheckCard.Group> : <div className=\"nav-list-panel__empty\">暂无字典</div>}\n </NavListPanel>);\n const operationColumn = useCrudOperationColumn<DictItem>({\n permissions: { edit: 'system:dict:item', remove: 'system:dict:item' },\n edit: openEditItem,\n remove: (row) => handleItemDelete(row.id),\n title: '确认删除此字典项?',\n extra: (row) => [\n {\n key: 'child',\n label: '子项',\n hidden: !hasPermission('system:dict:item'),\n onClick: () => openCreateChildItem(row),\n },\n ],\n width: 210,\n desktopInlineKeys: ['child', 'edit', 'delete'],\n });\n const itemColumns: ColumnProps<DictItem>[] = [\n { title: '标签', dataIndex: 'label', width: 160, render: (v: string, record: DictItem) => record.color ? <Tag color={tagColor(record.color)} size=\"small\">{v}</Tag> : renderEllipsis(v)\n },\n { title: '键值', dataIndex: 'value', width: 160, render: renderEllipsis },\n { title: '排序', dataIndex: 'sort', width: 70, align: 'center' },\n { title: '备注', dataIndex: 'remark', minWidth: 200, render: renderEllipsis },\n createdAtColumn,\n itemStatus.column(),\n operationColumn,\n ];\n const renderItemExpandButton = () => allRowKeys.length > 0 ? (<Button type=\"primary\" icon={isAllExpanded ? <ChevronsDownUp size={14}/> : <ChevronsUpDown size={14}/>} onClick={toggleExpandAll} disabled={!selectedDict}>\n {isAllExpanded ? '全部折叠' : '全部展开'}\n </Button>) : null;\n const dictDetail = (<>\n <MasterDetailLayout.Header>\n {selectedDict ? (<>\n <div className=\"dict-detail-title\">\n <BookOpen size={16}/>\n <span title={selectedDict.name}>{selectedDict.name}</span>\n </div>\n <Tag size=\"small\" color=\"blue\">{selectedDict.code}</Tag>\n <Switch size=\"small\" checked={selectedDict.status === 'enabled'} loading={togglingDictStatusId === selectedDict.id} disabled={!hasPermission('system:dict:update')} onChange={(checked: boolean) => void handleToggleDictStatus(selectedDict, checked ? 'enabled' : 'disabled')}/>\n </>) : (<span className=\"dict-detail-placeholder\">请选择字典</span>)}\n </MasterDetailLayout.Header>\n <MasterDetailLayout.Body>\n\n <ConfigurableTable searchConfig={buildTableSearch({\n keyword: ((<KeywordInput placeholder=\"标签/键值\" {...itemSearch.bindKeyword('keyword')} width={180} disabled={!selectedDict}/>)),\n filters: ((<StatusSelect items={statusItems} {...itemSearch.bind('status')} disabled={!selectedDict}/>)),\n onSearch: (itemSearch.handleSearch),\n onReset: (itemSearch.handleReset),\n create: (<CreateButton permission=\"system:dict:item\" onClick={() => openCreateItem()} disabled={!selectedDict}/>),\n actions: (renderItemExpandButton()),\n filterTitle: \"字典项筛选\",\n actionTitle: \"字典项操作\"\n })} bordered columns={itemColumns} dataSource={treeItems} rowKey=\"id\" loading={itemsQuery.isFetching} onRefresh={selectedDict ? () => void itemsQuery.refetch() : undefined} refreshLoading={itemsQuery.isFetching} pagination={false} size=\"small\" empty={selectedDict ? '暂无数据' : '请选择字典'} childrenRecordName=\"children\" expandedRowKeys={expandedRowKeys} onExpandedRowsChange={onExpandedRowsChange}/>\n </MasterDetailLayout.Body>\n </>);\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout master={dictMaster} detail={dictDetail} defaultSize={300} minSize={260} maxSize={420} persistKey=\"dicts\" showDetail={!!selectedDict} onBack={clearSelectedDictionary} onResponsiveChange={setIsNarrowLayout} style={{ flex: 1, overflow: 'hidden' }}/>\n\n {/* 字典创建/编辑 Modal */}\n <EditFormModal modal={dictModal} width={480}>\n <Form.Input field=\"name\" label=\"字典名称\" placeholder=\"请输入字典名称\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入字典名称' }]}/>\n <Form.Input field=\"code\" label=\"字典编码\" placeholder=\"小写字母和下划线\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入字典编码' }]} validate={(value) => {\n const result = dictContract.create.input.shape.body.safeParse({ code: value });\n const issue = result.success ? undefined : result.error.issues.find(item => item.path[0] === 'code');\n return issue?.message ?? '';\n }}/>\n <Form.Input field=\"description\" label=\"描述\" placeholder=\"请输入描述\" style={{ width: '100%' }}/>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusOptions} placeholder=\"请选择状态\"/>\n </EditFormModal>\n\n {/* 字典项创建/编辑 Modal */}\n <EditFormModal modal={itemModal} width={600}>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"label\" label=\"标签\" placeholder=\"请输入标签\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入标签' }]}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"value\" label=\"键值\" placeholder=\"请输入键值\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入键值' }]}/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={12}>\n <Form.InputNumber field=\"sort\" label=\"排序\" placeholder=\"请输入排序\" min={0} style={{ width: '100%' }}/>\n </Col>\n <Col span={12}>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusOptions} placeholder=\"请选择状态\"/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={12}>\n <Form.Slot label={{ text: '父级' }}>\n <TreeSelect treeData={parentSelectorTreeData} value={itemParentId ?? 0} onChange={(val) => setItemParentId(val === 0 ? null : (val as number))} style={{ width: '100%' }} filterTreeNode expandAll/>\n </Form.Slot>\n </Col>\n <Col span={12}>\n <Form.Slot label={{ text: '颜色' }}>\n {(() => {\n const TAG_COLORS = ['amber', 'blue', 'cyan', 'green', 'grey', 'indigo', 'light-blue', 'light-green', 'lime', 'orange', 'pink', 'purple', 'red', 'teal', 'violet', 'yellow', 'white'];\n const COLOR_LABELS: Record<string, string> = {\n amber: '琥珀', blue: '蓝色', cyan: '青色', green: '绿色', grey: '灰色',\n indigo: '靛蓝', 'light-blue': '浅蓝', 'light-green': '浅绿', lime: '柠绿',\n orange: '橙色', pink: '粉色', purple: '紫色', red: '红色', teal: '蓝绿',\n violet: '紫罗兰', yellow: '黄色', white: '白色',\n };\n return (<Select value={itemColor ?? undefined} onChange={(val) => setItemColor((val as string) ?? null)} placeholder=\"无颜色\" showClear onClear={() => setItemColor(null)} style={{ width: '100%' }} renderSelectedItem={(option: {\n value?: unknown;\n label?: unknown;\n }) => (<Tag color={tagColor(option.value as string)} size=\"small\" style={{ margin: '2px 0' }}>\n {option.label as string}\n </Tag>)} renderOptionItem={({ selected, style, onClick, value, label }) => (<button type=\"button\" onClick={onClick} style={{\n ...style,\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 12px',\n cursor: 'pointer',\n width: '100%',\n border: 'none',\n background: selected ? 'var(--arc-antd-color-primary-light-default)' : 'transparent',\n textAlign: 'left',\n }}>\n <Tag color={tagColor(value as string)} size=\"small\">{label as string}</Tag>\n </button>)}>\n {TAG_COLORS.map((c) => (<Select.Option key={c} value={c} label={COLOR_LABELS[c] ?? c}>\n <Tag color={tagColor(c)} size=\"small\">{COLOR_LABELS[c] ?? c}</Tag>\n </Select.Option>))}\n </Select>);\n })()}\n </Form.Slot>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={24}>\n <Form.Input field=\"remark\" label=\"备注\" placeholder=\"请输入备注\" style={{ width: '100%' }}/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={24}>\n <Form.Slot label={{ text: '元数据' }}>\n <JsonViewer key={metadataStr} ref={jsonViewerRef} value={metadataStr} height={200} width=\"100%\"/>\n </Form.Slot>\n </Col>\n </Row>\n </EditFormModal>\n </div>);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"DictsPage-fxBdV1-3.js","mappings":"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","names":["__iconData","__iconData$1","createLucideIcon","resolveExplicitDictionary","records","id","record","selectWebMcpDictionary","assertAllowed","execution","port","deadline","resolve","DictListCard","select","onSelect","dict","CheckCard","active","event","DateTimeText","Tag","extra","useDictItemModalDetail","useDictItemDetail","enabled","DictsPage","usePermission","jsonViewerRef","useRef","dicts","setDicts","useState","useListSearch","dictKeys","filterQuery","useFilterQuery","submittedParams","selectedDictKey","setSelectedDictKey","useUrlSelectionState","selectedDictDetail","setSelectedDictDetail","selectionRevision","itemParentId","setItemParentId","itemColor","setItemColor","metadataStr","setMetadataStr","statusItems","statusOptions","useDictItems","tagColor","color","isNarrowLayout","setIsNarrowLayout","dictListQuery","useDictList","total","explicitId","explicitIdValid","dictInPage","d","detachedDict","dictFallbackQuery","useDictDetail","selectedDict","activeDictId","committedDictId","useEffect","clearSelectedDictionary","itemsQuery","useDictItemsById","items","useMemo","itemSearch","defaultItemSearch","saveDictMutation","useSaveDict","dictModal","useEditModal","formSaveMutation","dictContract","values","editing","toggleDictStatusMutation","deleteDictMutation","useDeleteDicts","createItemMutation","useCreateDictItem","updateItemMutation","useUpdateDictItem","toggleItemStatusMutation","deleteItemMutation","useDeleteDictItem","togglingDictStatusId","itemModal","abortSubmit","item","metadata","currentJson","Toast","payload","editingItem","selectionBusy","useStandardWebMcpCrudAdapter","hasPermission","z.object","z.number","input","revision","api","recordId","itemId","isEdit","expandInitedDictIdRef","handleDictPageChange","setPage","nextPage","handleDictPageSizeChange","setPageSize","nextPageSize","selectDict","filteredItems","itemKeyword","itemStatusFilter","treeItems","filteredIds","i","buildChildren","c","grandchildren","children","useTreeExpansion","setExpandedRowKeys","allRowKeys","editingSubtreeIds","result","addDescendants","child","parentSelectorTreeData","buildTree","parentId","openEditDict","row","handleDictDelete","handleItemDelete","openCreateItem","openCreateChildItem","openEditItem","itemStatus","useStatusToggle","handleToggleDictStatus","newStatus","confirmDangerAsync","dictMaster","NavListPanel","Space","ExportButton","NavListItemActions","RefreshCw","Plus","draftParams","setField","handleSearch","Pagination","page","Pencil","Trash2","confirmDelete","operationColumn","useCrudOperationColumn","itemColumns","v","renderEllipsis","createdAtColumn","renderItemExpandButton","Button","jsx","isAllExpanded","ChevronsDownUp","ChevronsUpDown","toggleExpandAll","dictDetail","_Fragment","MasterDetailLayout","BookOpen","Switch","checked","ConfigurableTable","buildTableSearch","KeywordInput","StatusSelect","CreateButton","EditFormModal","Form","value","Row","Col","TreeSelect","val","TAG_COLORS","COLOR_LABELS","Select","option","style","selected","label","JsonViewer"],"ignoreList":[0,1],"sources":["../../../../node_modules/lucide-react/dist/esm/icons/book-open.mjs","../../../../node_modules/lucide-react/dist/esm/icons/pencil.mjs","../../src/pages/system/dicts/webmcp-selection.ts","../../src/pages/system/dicts/DictListCard.tsx","../../src/pages/system/dicts/DictsPage.tsx"],"sourcesContent":[null,null,"import type { WebMcpExecutionContext } from '../../../webmcp-types';\n\n/** A detail fallback is usable only for the explicitly selected real record. */\nexport function resolveExplicitDictionary<T extends { id: number }>(id: number | undefined, ...records: readonly (T | null | undefined)[]): T | null {\n return id === undefined ? null : records.find(record => record?.id === id) ?? null;\n}\n\nexport async function selectWebMcpDictionary<T extends { id: number }>(id: number, execution: WebMcpExecutionContext, port: {\n read(id: number, signal: AbortSignal): Promise<T>;\n /** Live editor/mutation and concurrent/manual selection checks. */\n assertCanSelect(): void;\n commit(record: T): void;\n isCommitted(id: number): boolean;\n}): Promise<{ status: 'selected'; id: number }> {\n const assertAllowed = () => { execution.assertActive(); port.assertCanSelect(); };\n assertAllowed();\n // Fetch before touching selection: 403/404/network failures retain current UI.\n const record = await port.read(id, execution.signal);\n assertAllowed();\n if (!record || record.id !== id) throw new Error('字典详情与选择目标不匹配');\n port.commit(record);\n const deadline = Date.now() + 20_000;\n while (!port.isCommitted(id)) {\n assertAllowed();\n if (Date.now() >= deadline) throw new Error('字典选择尚未完成');\n await new Promise(resolve => setTimeout(resolve, 20));\n }\n assertAllowed();\n return { status: 'selected', id };\n}\n","import { CheckCard } from '@ant-design/pro-components';\nimport type { ReactNode } from 'react';\nimport type { Dict } from '@fudanda/shared/platform';\nimport { Tag } from '@/ui';\nimport DateTimeText from '@/components/DateTimeText';\n\nexport function DictListCard({ dict, active, onSelect, extra }: {\n dict: Dict;\n active: boolean;\n onSelect: (dict: Dict) => void;\n extra?: ReactNode;\n}) {\n const select = () => onSelect(dict);\n return <CheckCard\n className=\"dict-check-card\"\n value={dict.id}\n checked={active}\n onClick={select}\n style={dict.status === 'disabled' ? { opacity: 0.55 } : undefined}\n title={<button\n type=\"button\"\n className=\"dict-check-card__select\"\n aria-label={`${dict.name} ${dict.code}`}\n aria-current={active ? 'true' : undefined}\n onClick={event => { event.stopPropagation(); select(); }}\n >{dict.name}</button>}\n subTitle={<span className=\"dict-check-card__code\">{dict.code}</span>}\n description={<span className=\"dict-check-card__meta\">\n <DateTimeText value={dict.createdAt} />\n {dict.status === 'disabled' && <Tag size=\"small\" color=\"grey\">停用</Tag>}\n </span>}\n extra={extra === undefined ? undefined : <span onClick={event => event.stopPropagation()}>{extra}</span>}\n />;\n}\n","import type { ApiUpdateItemRequestBodyInput } from '@fudanda/shared/api/dictionaries';\nimport { dictContract } from '@fudanda/react-core/lib/native-operations';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { CheckCard } from '@ant-design/pro-components';\nimport type { ComponentProps } from 'react';\nimport { Button, Select, Tag, Form, Pagination, Toast, TreeSelect, JsonViewer, Row, Col, Space, Switch } from \"@/ui\";\nimport { Plus, BookOpen, ChevronsDownUp, ChevronsUpDown, RefreshCw, Pencil, Trash2 } from 'lucide-react';\nimport type { CreateDictInput, CreateDictItemInput, Dict, DictItem } from '@fudanda/shared/platform';\nimport ExportButton from \"@/components/ExportButton\";\nimport ConfigurableTable from \"@/components/ConfigurableTable\";\nimport { useListSearch } from \"@fudanda/react-core/hooks/useListSearch\";\nimport { useEditModal, formSaveMutation } from \"@/hooks/useEditModal\";\nimport { useTreeExpansion } from \"@fudanda/react-core/hooks/useTreeExpansion\";\nimport { useUrlSelectionState } from \"@fudanda/react-core/hooks/useUrlSelectionState\";\nimport { MasterDetailLayout } from \"@/components/MasterDetailLayout\";\nimport { NavListPanel, NavListItemActions } from \"@/components/NavListPanel\";\nimport { useDictItems } from \"@fudanda/react-core/hooks/useDictItems\";\nimport type { ColumnProps } from \"@/ui\";\nimport { usePermission } from \"@fudanda/react-core/hooks/usePermission\";\nimport \"@/pages/system/dicts/DictsPage.css\";\nimport { createdAtColumn, renderEllipsis } from \"@/utils/table-columns\";\nimport { dictKeys, useCreateDictItem, useDeleteDictItem, useDeleteDicts, useDictDetail, useDictItemDetail, useDictItemsById, useDictList, useSaveDict, useUpdateDictItem } from \"@fudanda/react-core/hooks/queries/dicts\";\nimport { CreateButton } from \"@/components/toolbar-controls\";\nimport { confirmDelete, confirmDangerAsync } from \"@/utils/confirm\";\nimport { buildTableSearch, useStatusToggle, useCrudOperationColumn } from \"@/components/list-page/index\";\nimport { abortSubmit } from \"@fudanda/react-core/lib/abort-submit\";\nimport { KeywordInput, StatusSelect } from \"@/components/search-filters\";\nimport { useFilterQuery } from \"@fudanda/react-core/hooks/useFilterQuery\";\nimport { EditFormModal } from \"@/components/EditFormModal\";\nimport { useStandardWebMcpCrudAdapter } from '@/webmcp-crud';\nimport { api } from '@fudanda/react-core/lib/contract-query';\nimport { resolveExplicitDictionary, selectWebMcpDictionary } from './webmcp-selection';\nimport { DictListCard } from './DictListCard';\nimport * as z from 'zod';\ninterface ItemSearchParams {\n keyword: string;\n status?: string;\n}\nconst defaultItemSearch: ItemSearchParams = { keyword: '', status: undefined };\n/** 字典项详情按 (dictId, itemId) 取数;useEditModal 只传 itemId,所属字典从打开弹窗时的行记录取 */\nfunction useDictItemModalDetail(id: number | undefined, enabled?: boolean, record?: DictItem) {\n return useDictItemDetail(record?.dictId, id, enabled);\n}\nexport default function DictsPage() {\n const { hasPermission } = usePermission();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const jsonViewerRef = useRef<any>(null);\n // ─── 字典列表 ──────────────────────────────────────────────────────────────\n const [dicts, setDicts] = useState<Dict[]>([]);\n const { page, pageSize, setPage, setPageSize, draftParams, setField, submittedParams, handleSearch, } = useListSearch<{\n keyword: string;\n }>({ defaults: { keyword: '' }, listKey: dictKeys.lists });\n // 已提交筛选 → 契约查询参数:列表与导出共用同一份映射\n const filterQuery = useFilterQuery({\n keyword: submittedParams.keyword,\n });\n // ─── 字典项列表 ────────────────────────────────────────────────────────────\n // 显式选中的字典以 `?dict=` 同步到 URL(深链/刷新/页签直达);选中对象按 key 派生\n const [selectedDictKey, setSelectedDictKey] = useUrlSelectionState('dict');\n const [selectedDictDetail, setSelectedDictDetail] = useState<Dict | null>(null);\n const selectionRevision = useRef(0);\n const [itemParentId, setItemParentId] = useState<number | null>(null);\n const [itemColor, setItemColor] = useState<string | null>(null);\n // metadataStr 仅用于 JsonViewer 的初始值(非受控),提交时通过 ref.getValue() 读取\n const [metadataStr, setMetadataStr] = useState<string>('{}');\n const { items: statusItems, options: statusOptions } = useDictItems('common_status');\n const tagColor = (color: string) => color as ComponentProps<typeof Tag>['color'];\n // 单栏(窄屏)下 showDetail 由 selectedDict 驱动,若沿用桌面端「默认选中第一项」\n // 会直接落到字典项详情,字典列表反而要点返回才能看到。布局形态参与选中派生,故用 state。\n const [isNarrowLayout, setIsNarrowLayout] = useState(false);\n // ─── 数据获取 ──────────────────────────────────────────────────────────────\n const dictListQuery = useDictList({\n page,\n pageSize,\n ...filterQuery,\n });\n const total = dictListQuery.data?.total ?? 0;\n // 选中派生:URL 深链值优先;无深链时桌面端回退首项(默认选中不入 URL),窄屏不自动选中。\n // 深链目标可能不在当前页/当前筛选(列表分页),成员资格不可当存在性判据,\n // 不在页内时按 id 拉详情兜底,仅确认无效(非法 id / 404)才清参回退\n const explicitId = selectedDictKey !== null ? Number(selectedDictKey) : undefined;\n const explicitIdValid = explicitId !== undefined && Number.isInteger(explicitId) && explicitId > 0;\n const dictInPage = explicitIdValid ? dicts.find((d) => d.id === explicitId) ?? null : null;\n const detachedDict = resolveExplicitDictionary(explicitId, selectedDictDetail);\n const dictFallbackQuery = useDictDetail(explicitId, explicitIdValid && !dictInPage && !detachedDict);\n const explicitDict = resolveExplicitDictionary(explicitId, dictInPage, detachedDict, dictFallbackQuery.data);\n const selectedDict = explicitDict ?? (isNarrowLayout ? null : dicts[0] ?? null);\n const activeDictId = useRef<number | undefined>(selectedDict?.id);\n const committedDictId = useRef<number | undefined>(selectedDict?.id);\n activeDictId.current = selectedDict?.id;\n useEffect(() => { committedDictId.current = selectedDict?.id; }, [selectedDict?.id]);\n useEffect(() => {\n if (selectedDictDetail && selectedDictKey !== String(selectedDictDetail.id)) setSelectedDictDetail(null);\n }, [selectedDictDetail, selectedDictKey]);\n const clearSelectedDictionary = () => { selectionRevision.current++; setSelectedDictDetail(null); setSelectedDictKey(null); };\n useEffect(() => {\n if (selectedDictKey === null)\n return;\n if (!explicitIdValid || !dictInPage && !detachedDict && dictFallbackQuery.isError)\n setSelectedDictKey(null);\n }, [selectedDictKey, explicitIdValid, dictInPage, detachedDict, dictFallbackQuery.isError, setSelectedDictKey]);\n const itemsQuery = useDictItemsById(selectedDict?.id);\n const items = useMemo(() => itemsQuery.data ?? [], [itemsQuery.data]);\n // 字典项全量取回后在客户端过滤:submittedParams 进过滤谓词,「查询 / 重置」仍回源刷新当前字典的项\n const itemSearch = useListSearch<ItemSearchParams>({ defaults: defaultItemSearch, listKey: dictKeys.items(selectedDict?.id) });\n const saveDictMutation = useSaveDict();\n const dictModal = useEditModal<Dict, Partial<CreateDictInput>>({\n entityName: '字典',\n save: formSaveMutation(saveDictMutation, { create: dictContract.create.input.shape.body, update: dictContract.update.input.shape.body }),\n useDetail: useDictDetail,\n defaults: { status: 'enabled' },\n toValues: dict => ({ name: dict.name, code: dict.code, description: dict.description, status: dict.status }),\n beforeSave: (values, { editing }) => ({ ...values, description: values.description || undefined, ...(editing ? { clearFields: values.description ? [] : ['description'] } : {}) }),\n });\n const toggleDictStatusMutation = useSaveDict();\n const deleteDictMutation = useDeleteDicts();\n const createItemMutation = useCreateDictItem();\n const updateItemMutation = useUpdateDictItem();\n const toggleItemStatusMutation = useUpdateDictItem();\n const deleteItemMutation = useDeleteDictItem();\n const togglingDictStatusId = toggleDictStatusMutation.isPending ? (toggleDictStatusMutation.variables?.id ?? null) : null;\n // 字典项是所选字典的子资源:创建 / 更新契约都绑定 dictId,由 save 适配层按是否有 id 分派;\n // 父级 / 颜色 / 元数据不在 Semi 表单内(Form.Slot 受控控件),在 beforeSave 合入载荷\n const itemModal = useEditModal<DictItem, Partial<CreateDictItemInput>, Partial<CreateDictItemInput> & ApiUpdateItemRequestBodyInput>({\n entityName: '字典项',\n save: {\n mutateAsync: ({ id, values }) => {\n if (!selectedDict)\n abortSubmit('validation');\n return id === undefined\n ? createItemMutation.mutateAsync({ params: { id: selectedDict.id }, body: dictContract.createItem.input.shape.body.parse(values) })\n : updateItemMutation.mutateAsync({ params: { id: selectedDict.id, itemId: id }, body: dictContract.updateItem.input.shape.body.parse(values) });\n },\n isPending: createItemMutation.isPending || updateItemMutation.isPending,\n },\n useDetail: useDictItemModalDetail,\n defaults: { status: 'enabled', sort: 0 },\n toValues: (item) => ({ label: item.label, value: item.value, sort: item.sort, status: item.status, remark: item.remark ?? undefined }),\n beforeSave: (values, { editing }) => {\n let metadata: unknown;\n const currentJson = (jsonViewerRef.current?.getValue() ?? metadataStr).trim();\n if (currentJson && currentJson !== '{}') {\n try {\n metadata = JSON.parse(currentJson);\n }\n catch {\n Toast.error('元数据 JSON 格式有误,请检查后重试');\n abortSubmit();\n }\n }\n // 表单值来自 Semi validate(),形状由表单字段决定;label / value 必填由表单 rules 保证\n const payload = { ...values, parentId: itemParentId ?? undefined, color: itemColor || undefined, remark: values.remark || undefined, metadata };\n return editing\n ? dictContract.updateItem.input.shape.body.parse({ ...payload, clearFields: [...(itemParentId == null ? ['parentId'] : []), ...(!itemColor ? ['color'] : []), ...(!values.remark ? ['remark'] : []), ...(metadata === undefined ? ['metadata'] : [])] })\n : dictContract.createItem.input.shape.body.parse(payload);\n },\n labelWidth: 72,\n });\n const editingItem = itemModal.editing;\n const selectionBusy = useRef(false);\n selectionBusy.current = dictModal.visible || itemModal.visible || dictModal.footerProps.loading || itemModal.footerProps.loading\n || saveDictMutation.isPending || createItemMutation.isPending || updateItemMutation.isPending || deleteDictMutation.isPending || deleteItemMutation.isPending\n || toggleDictStatusMutation.isPending || toggleItemStatusMutation.isPending;\n useStandardWebMcpCrudAdapter({ resource: 'dicts', title: '字典', permission: 'system:dict', hasPermission, modal: dictModal,\n list: dictContract.list, detail: dictContract.detail, create: dictContract.create.input.shape.body, update: dictContract.update.input.shape.body,\n fields: ['id', 'name', 'code', 'description', 'status', 'createdAt', 'updatedAt'], filters: filterQuery,\n remove: id => deleteDictMutation.mutateAsync([id]), onDeleted: clearSelectedDictionary,\n extraTools: hasPermission('system:dict:list') ? [{ name: 'arcbase_system_dicts_select', description: '选择字典以操作其字典项', kind: 'read', inputSchema: { type: 'object', properties: { id: { type: 'integer', minimum: 1 } }, required: ['id'], additionalProperties: false },\n parse: input => z.object({ id: z.number().int().positive() }).strict().parse(input), execute: async (input, execution) => {\n const id = (input as { id: number }).id;\n const revision = ++selectionRevision.current;\n return selectWebMcpDictionary(id, execution, {\n read: (recordId, signal) => api(dictContract.detail, { params: { id: recordId } }, { signal, silent: true }),\n assertCanSelect: () => {\n if (selectionRevision.current !== revision) throw new Error('字典选择已变更');\n if (selectionBusy.current) throw new Error('请先关闭字典或字典项编辑器并等待保存完成');\n },\n commit: record => { setSelectedDictDetail(record); setSelectedDictKey(String(record.id)); },\n isCommitted: recordId => activeDictId.current === recordId && committedDictId.current === recordId,\n });\n } }] : [] });\n useStandardWebMcpCrudAdapter({ resource: 'dict_items', title: '字典项', permission: 'system:dict', hasPermission, modal: itemModal,\n permissions: { list: 'system:dict:list', create: 'system:dict:item', update: 'system:dict:item', delete: 'system:dict:item' },\n list: dictContract.items, detail: dictContract.itemDetail, create: dictContract.createItem.input.shape.body, update: dictContract.updateItem.input.shape.body,\n fields: ['id', 'dictId', 'parentId', 'label', 'value', 'sort', 'status', 'color', 'remark', 'metadata', 'createdAt', 'updatedAt'],\n scope: selectedDict?.id, disabled: !selectedDict, filters: { ...itemSearch.submittedParams },\n params: itemId => ({ id: selectedDict?.id, ...(itemId === undefined ? {} : { itemId }) }),\n assertScope: () => { if (!selectedDict || activeDictId.current !== selectedDict.id) throw new Error('字典已切换,请重新调用'); },\n remove: itemId => deleteItemMutation.mutateAsync({ params: { id: selectedDict!.id, itemId } }),\n applyValues: (values, { isEdit }) => { if (!isEdit || 'parentId' in values) setItemParentId(values.parentId as number ?? null); if (!isEdit || 'color' in values) setItemColor(values.color as string ?? null); if (!isEdit || 'metadata' in values) setMetadataStr(values.metadata ? JSON.stringify(values.metadata, null, 2) : '{}'); } });\n useEffect(() => {\n if (!dictListQuery.data)\n return;\n setDicts(dictListQuery.data.list);\n }, [dictListQuery.data]);\n // 每个字典的条目首次加载完成时默认全展开;同一字典内(数据刷新 / keepAlive 页签切回)保持用户展开/折叠状态\n const expandInitedDictIdRef = useRef<number | null>(null);\n // 打开瞬间先按列表行占位,详情到达后(editing 切换为详情对象)用服务端值覆盖表单外的父级 / 颜色 / 元数据\n useEffect(() => {\n if (!editingItem)\n return;\n setItemParentId(editingItem.parentId ?? null);\n setItemColor(editingItem.color ?? null);\n setMetadataStr(editingItem.metadata ? JSON.stringify(editingItem.metadata, null, 2) : '{}');\n }, [editingItem]);\n const handleDictPageChange = (nextPage: number) => {\n setPage(nextPage);\n };\n const handleDictPageSizeChange = (nextPageSize: number) => {\n setPage(1);\n setPageSize(nextPageSize);\n };\n const selectDict = (dict: Dict) => {\n if (selectedDict?.id === dict.id) return;\n selectionRevision.current++;\n setSelectedDictDetail(null);\n setSelectedDictKey(String(dict.id));\n itemSearch.handleReset();\n };\n const filteredItems = useMemo(() => {\n const { keyword: itemKeyword, status: itemStatusFilter } = itemSearch.submittedParams;\n const flat = items.filter((item) => {\n if (itemKeyword && !item.label.includes(itemKeyword) && !item.value.includes(itemKeyword))\n return false;\n if (itemStatusFilter && item.status !== itemStatusFilter)\n return false;\n return true;\n });\n return flat;\n }, [items, itemSearch.submittedParams]);\n // 将扁平列表递归转为树结构,用于表格展示\n const treeItems = useMemo(() => {\n const filteredIds = new Set(filteredItems.map((i) => i.id));\n const buildChildren = (id: number): DictItem[] => filteredItems\n .filter((c) => c.parentId === id)\n .map((c) => {\n const grandchildren = buildChildren(c.id);\n return grandchildren.length > 0 ? { ...c, children: grandchildren } : c;\n });\n return filteredItems\n .filter((i) => !i.parentId || !filteredIds.has(i.parentId))\n .map((item) => {\n const children = buildChildren(item.id);\n return children.length > 0 ? { ...item, children } : item;\n });\n }, [filteredItems]);\n const { expandedRowKeys, setExpandedRowKeys, allRowKeys, isAllExpanded, toggleExpandAll, onExpandedRowsChange, } = useTreeExpansion(treeItems);\n useEffect(() => {\n if (!selectedDict || itemsQuery.data === undefined)\n return;\n if (expandInitedDictIdRef.current === selectedDict.id)\n return;\n expandInitedDictIdRef.current = selectedDict.id;\n setExpandedRowKeys(allRowKeys);\n }, [selectedDict, itemsQuery.data, allRowKeys, setExpandedRowKeys]);\n // 编辑项的子孙节点 id 集合(父级选择器中禁用,避免循环引用)\n const editingSubtreeIds = useMemo(() => {\n if (!editingItem)\n return new Set<number>();\n const result = new Set<number>([editingItem.id]);\n const addDescendants = (id: number) => {\n items.filter((i) => i.parentId === id).forEach((child) => {\n result.add(child.id);\n addDescendants(child.id);\n });\n };\n addDescendants(editingItem.id);\n return result;\n }, [editingItem, items]);\n // 父级选择器的树形数据(递归构建,排除编辑项及其子孙)\n const parentSelectorTreeData = useMemo(() => {\n type SNode = {\n label: string;\n value: number;\n key: string;\n disabled?: boolean;\n children?: SNode[];\n };\n const buildTree = (parentId: number | null): SNode[] => items\n .filter((i) => (i.parentId ?? null) === parentId)\n .map((item) => ({\n label: item.label,\n value: item.id,\n key: String(item.id),\n disabled: editingSubtreeIds.has(item.id),\n children: buildTree(item.id),\n }));\n return [\n { label: '无(根项目)', value: 0, key: '0' },\n ...buildTree(null),\n ];\n }, [items, editingSubtreeIds]);\n // ─── 字典 CRUD ─────────────────────────────────────────────────────────────\n const openEditDict = (row: Dict) => {\n dictModal.openEdit(row);\n };\n const handleDictDelete = async (id: number) => {\n await deleteDictMutation.mutateAsync([id]);\n Toast.success('删除成功');\n if (selectedDictKey === String(id)) {\n clearSelectedDictionary();\n }\n };\n // ─── 字典项 CRUD ───────────────────────────────────────────────────────────\n const handleItemDelete = async (id: number) => {\n if (!selectedDict)\n return;\n await deleteItemMutation.mutateAsync({ params: { id: selectedDict.id, itemId: id } });\n };\n const openCreateItem = (parentId: number | null = null) => {\n setItemParentId(parentId);\n setItemColor(null);\n setMetadataStr('{}');\n itemModal.openCreate();\n };\n const openCreateChildItem = (row: DictItem) => openCreateItem(row.id);\n const openEditItem = (row: DictItem) => {\n if (!selectedDict)\n return;\n setItemParentId(row.parentId ?? null);\n setItemColor(row.color ?? null);\n setMetadataStr(row.metadata ? JSON.stringify(row.metadata, null, 2) : '{}');\n itemModal.openEdit(row);\n };\n const itemStatus = useStatusToggle<DictItem>({\n toggle: (item, enabled) => {\n if (!selectedDict)\n return Promise.resolve();\n return toggleItemStatusMutation.mutateAsync({ params: { id: selectedDict.id, itemId: item.id }, body: { status: enabled ? 'enabled' : 'disabled' } });\n },\n confirmDisable: (item) => ({ danger: true, title: `确认禁用字典项「${item.label}」?`, okText: '确认禁用' }),\n disabled: !selectedDict || !hasPermission('system:dict:item'),\n });\n const handleToggleDictStatus = async (dict: Dict, newStatus: 'enabled' | 'disabled') => {\n if (newStatus === 'disabled') {\n const confirmed = await confirmDangerAsync({\n title: `确认禁用字典「${dict.name}」?`,\n okText: '确认禁用',\n });\n if (!confirmed)\n return;\n }\n await toggleDictStatusMutation.mutateAsync({ id: dict.id, values: { status: newStatus } });\n Toast.success(newStatus === 'enabled' ? '已启用' : '已禁用');\n };\n const renderDictListItem = (dict: Dict) => {\n const active = selectedDict?.id === dict.id;\n return (<DictListCard key={dict.id} dict={dict} active={active} onSelect={selectDict} extra={<NavListItemActions items={[\n { key: 'edit', label: '编辑', icon: <Pencil size={14}/>, hidden: !hasPermission('system:dict:update'), onClick: () => void openEditDict(dict) },\n {\n key: 'delete', label: '删除', icon: <Trash2 size={14}/>, danger: true, hidden: !hasPermission('system:dict:delete'),\n onClick: () => {\n confirmDelete({\n title: '确认删除此字典?',\n content: '字典下的所有字典项也将一并删除',\n onOk: () => handleDictDelete(dict.id),\n });\n },\n },\n ]}/>}/>);\n };\n const dictMaster = (<NavListPanel title=\"字典列表\" headerExtra={<Space spacing={6}>\n <ExportButton entity=\"system.dicts\" query={filterQuery}/>\n <NavListItemActions items={[\n { key: 'refresh', label: '刷新', icon: <RefreshCw size={14}/>, onClick: () => void dictListQuery.refetch() },\n { key: 'create', label: '新增字典', icon: <Plus size={14}/>, hidden: !hasPermission('system:dict:create'), onClick: dictModal.openCreate },\n ]}/>\n </Space>} search={{\n value: draftParams.keyword,\n onChange: setField('keyword'),\n placeholder: '名称/编码',\n onEnterPress: handleSearch,\n }} loading={dictListQuery.isLoading} footer={<Pagination size=\"small\" hoverShowPageSelect total={total} currentPage={page} pageSize={pageSize} pageSizeOpts={[10, 20, 50, 100]} showSizeChanger showTotal onPageChange={handleDictPageChange} onPageSizeChange={handleDictPageSizeChange}/>} rawBody>\n {dicts.length > 0 ? <CheckCard.Group className=\"dict-check-card-group\" value={selectedDict?.id} multiple={false}>\n {dicts.map(renderDictListItem)}\n </CheckCard.Group> : <div className=\"nav-list-panel__empty\">暂无字典</div>}\n </NavListPanel>);\n const operationColumn = useCrudOperationColumn<DictItem>({\n permissions: { edit: 'system:dict:item', remove: 'system:dict:item' },\n edit: openEditItem,\n remove: (row) => handleItemDelete(row.id),\n title: '确认删除此字典项?',\n extra: (row) => [\n {\n key: 'child',\n label: '子项',\n hidden: !hasPermission('system:dict:item'),\n onClick: () => openCreateChildItem(row),\n },\n ],\n width: 210,\n desktopInlineKeys: ['child', 'edit', 'delete'],\n });\n const itemColumns: ColumnProps<DictItem>[] = [\n { title: '标签', dataIndex: 'label', width: 160, render: (v: string, record: DictItem) => record.color ? <Tag color={tagColor(record.color)} size=\"small\">{v}</Tag> : renderEllipsis(v)\n },\n { title: '键值', dataIndex: 'value', width: 160, render: renderEllipsis },\n { title: '排序', dataIndex: 'sort', width: 70, align: 'center' },\n { title: '备注', dataIndex: 'remark', minWidth: 200, render: renderEllipsis },\n createdAtColumn,\n itemStatus.column(),\n operationColumn,\n ];\n const renderItemExpandButton = () => allRowKeys.length > 0 ? (<Button type=\"primary\" icon={isAllExpanded ? <ChevronsDownUp size={14}/> : <ChevronsUpDown size={14}/>} onClick={toggleExpandAll} disabled={!selectedDict}>\n {isAllExpanded ? '全部折叠' : '全部展开'}\n </Button>) : null;\n const dictDetail = (<>\n <MasterDetailLayout.Header>\n {selectedDict ? (<>\n <div className=\"dict-detail-title\">\n <BookOpen size={16}/>\n <span title={selectedDict.name}>{selectedDict.name}</span>\n </div>\n <Tag size=\"small\" color=\"blue\">{selectedDict.code}</Tag>\n <Switch size=\"small\" checked={selectedDict.status === 'enabled'} loading={togglingDictStatusId === selectedDict.id} disabled={!hasPermission('system:dict:update')} onChange={(checked: boolean) => void handleToggleDictStatus(selectedDict, checked ? 'enabled' : 'disabled')}/>\n </>) : (<span className=\"dict-detail-placeholder\">请选择字典</span>)}\n </MasterDetailLayout.Header>\n <MasterDetailLayout.Body>\n\n <ConfigurableTable searchConfig={buildTableSearch({\n keyword: ((<KeywordInput placeholder=\"标签/键值\" {...itemSearch.bindKeyword('keyword')} width={180} disabled={!selectedDict}/>)),\n filters: ((<StatusSelect items={statusItems} {...itemSearch.bind('status')} disabled={!selectedDict}/>)),\n onSearch: (itemSearch.handleSearch),\n onReset: (itemSearch.handleReset),\n create: (<CreateButton permission=\"system:dict:item\" onClick={() => openCreateItem()} disabled={!selectedDict}/>),\n actions: (renderItemExpandButton()),\n filterTitle: \"字典项筛选\",\n actionTitle: \"字典项操作\"\n })} bordered columns={itemColumns} dataSource={treeItems} rowKey=\"id\" loading={itemsQuery.isFetching} onRefresh={selectedDict ? () => void itemsQuery.refetch() : undefined} refreshLoading={itemsQuery.isFetching} pagination={false} size=\"small\" empty={selectedDict ? '暂无数据' : '请选择字典'} childrenRecordName=\"children\" expandedRowKeys={expandedRowKeys} onExpandedRowsChange={onExpandedRowsChange}/>\n </MasterDetailLayout.Body>\n </>);\n return (<div className=\"page-container page-container--stretch\">\n <MasterDetailLayout master={dictMaster} detail={dictDetail} defaultSize={300} minSize={260} maxSize={420} persistKey=\"dicts\" showDetail={!!selectedDict} onBack={clearSelectedDictionary} onResponsiveChange={setIsNarrowLayout} style={{ flex: 1, overflow: 'hidden' }}/>\n\n {/* 字典创建/编辑 Modal */}\n <EditFormModal modal={dictModal} width={480}>\n <Form.Input field=\"name\" label=\"字典名称\" placeholder=\"请输入字典名称\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入字典名称' }]}/>\n <Form.Input field=\"code\" label=\"字典编码\" placeholder=\"小写字母和下划线\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入字典编码' }]} validate={(value) => {\n const result = dictContract.create.input.shape.body.safeParse({ code: value });\n const issue = result.success ? undefined : result.error.issues.find(item => item.path[0] === 'code');\n return issue?.message ?? '';\n }}/>\n <Form.Input field=\"description\" label=\"描述\" placeholder=\"请输入描述\" style={{ width: '100%' }}/>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusOptions} placeholder=\"请选择状态\"/>\n </EditFormModal>\n\n {/* 字典项创建/编辑 Modal */}\n <EditFormModal modal={itemModal} width={600}>\n <Row gutter={16}>\n <Col span={12}>\n <Form.Input field=\"label\" label=\"标签\" placeholder=\"请输入标签\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入标签' }]}/>\n </Col>\n <Col span={12}>\n <Form.Input field=\"value\" label=\"键值\" placeholder=\"请输入键值\" style={{ width: '100%' }} rules={[{ required: true, message: '请输入键值' }]}/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={12}>\n <Form.InputNumber field=\"sort\" label=\"排序\" placeholder=\"请输入排序\" min={0} style={{ width: '100%' }}/>\n </Col>\n <Col span={12}>\n <Form.Select field=\"status\" label=\"状态\" style={{ width: '100%' }} optionList={statusOptions} placeholder=\"请选择状态\"/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={12}>\n <Form.Slot label={{ text: '父级' }}>\n <TreeSelect treeData={parentSelectorTreeData} value={itemParentId ?? 0} onChange={(val) => setItemParentId(val === 0 ? null : (val as number))} style={{ width: '100%' }} filterTreeNode expandAll/>\n </Form.Slot>\n </Col>\n <Col span={12}>\n <Form.Slot label={{ text: '颜色' }}>\n {(() => {\n const TAG_COLORS = ['amber', 'blue', 'cyan', 'green', 'grey', 'indigo', 'light-blue', 'light-green', 'lime', 'orange', 'pink', 'purple', 'red', 'teal', 'violet', 'yellow', 'white'];\n const COLOR_LABELS: Record<string, string> = {\n amber: '琥珀', blue: '蓝色', cyan: '青色', green: '绿色', grey: '灰色',\n indigo: '靛蓝', 'light-blue': '浅蓝', 'light-green': '浅绿', lime: '柠绿',\n orange: '橙色', pink: '粉色', purple: '紫色', red: '红色', teal: '蓝绿',\n violet: '紫罗兰', yellow: '黄色', white: '白色',\n };\n return (<Select value={itemColor ?? undefined} onChange={(val) => setItemColor((val as string) ?? null)} placeholder=\"无颜色\" showClear onClear={() => setItemColor(null)} style={{ width: '100%' }} renderSelectedItem={(option: {\n value?: unknown;\n label?: unknown;\n }) => (<Tag color={tagColor(option.value as string)} size=\"small\" style={{ margin: '2px 0' }}>\n {option.label as string}\n </Tag>)} renderOptionItem={({ selected, style, onClick, value, label }) => (<button type=\"button\" onClick={onClick} style={{\n ...style,\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n padding: '6px 12px',\n cursor: 'pointer',\n width: '100%',\n border: 'none',\n background: selected ? 'var(--arc-antd-color-primary-light-default)' : 'transparent',\n textAlign: 'left',\n }}>\n <Tag color={tagColor(value as string)} size=\"small\">{label as string}</Tag>\n </button>)}>\n {TAG_COLORS.map((c) => (<Select.Option key={c} value={c} label={COLOR_LABELS[c] ?? c}>\n <Tag color={tagColor(c)} size=\"small\">{COLOR_LABELS[c] ?? c}</Tag>\n </Select.Option>))}\n </Select>);\n })()}\n </Form.Slot>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={24}>\n <Form.Input field=\"remark\" label=\"备注\" placeholder=\"请输入备注\" style={{ width: '100%' }}/>\n </Col>\n </Row>\n\n <Row gutter={16}>\n <Col span={24}>\n <Form.Slot label={{ text: '元数据' }}>\n <JsonViewer key={metadataStr} ref={jsonViewerRef} value={metadataStr} height={200} width=\"100%\"/>\n </Form.Slot>\n </Col>\n </Row>\n </EditFormModal>\n </div>);\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{M as t,Mt as n,T as r,jt as i,m as a}from"./clipboard-dpqHdCyy.js";import{r as o}from"./feedback-B1UL2ETz.js";import{n as s,t as c}from"./arrow-left-CM8mgLml.js";import{n as l,t as u}from"./RelationPanel-
|
|
2
|
-
//# sourceMappingURL=EntityContextRuntime-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{M as t,Mt as n,T as r,jt as i,m as a}from"./clipboard-dpqHdCyy.js";import{r as o}from"./feedback-B1UL2ETz.js";import{n as s,t as c}from"./arrow-left-CM8mgLml.js";import{n as l,t as u}from"./RelationPanel-BsbfEDo2.js";import{createContext as d,useContext as f,useEffect as p,useRef as m,useState as h}from"react";import{Fragment as g,jsx as _,jsxs as v}from"react/jsx-runtime";import{useLocation as y,useNavigate as b}from"react-router-dom";import{useEntityAccessKey as x}from"@fudanda/admin-antd/core/hooks/queries/entity-relations";import{entityDetailRoute as S,entityTypeLabel as C}from"@fudanda/admin-antd/core/utils/entity-relations";import{EntityNavigationContext as w,EntityRelationViewStateContext as T,beginEntityRelationNavigation as E,captureEntityRelationScroll as D,entityRelationSourceUrl as O,getEntityRelationNavigation as k,restoreEntityRelationScroll as A,sameEntity as j,useEntityRelationNavigationSession as M}from"@fudanda/admin-antd/core/components/entity-relations/entity-navigation";function N({entityRef:e,showAnchor:t}){let r=y(),a=b(),o=JSON.stringify(x()),s=f(I),c=m(null),l=M(),d=s?.view??(l?.accessKey===o&&j(l.restore?.ref,e)?l.restore?.view:void 0),[C,k]=h(d?.tab??`relations`),[N,P]=h(()=>[...d?.expandedGroups??[]]),[L,R]=h();return p(()=>{if(d&&c.current)return k(d.tab),P([...d.expandedGroups]),A(c.current,d.scroll)},[d]),/* @__PURE__ */ v(g,{children:[/* @__PURE__ */ _(`div`,{ref:c,"data-entity-context":`${e.type}:${e.key}`,children:/* @__PURE__ */ _(w.Provider,{value:t=>{if(j(t,e)&&!s)return;let n=S(t),i={tab:C,expandedGroups:N,scroll:D(c.current)};n?(E({url:s?.sourceUrl??O(r,s?void 0:S(e)),locationKey:r.key,state:r.state,ref:e,kind:s?`sheet`:`detail`,view:i,sheetHistory:s?.history,pageScrollTop:document.querySelector(`.admin-content`)?.scrollTop??0},n,o,r.pathname),s?.onLeave(),a(n)):s?s.open(t,i):R(t)},children:/* @__PURE__ */ _(T.Provider,{value:{expandedGroups:N,setExpandedGroups:P},children:/* @__PURE__ */ v(n,{collapsible:`auto`,activeKey:C,onChange:k,lazyRender:!0,keepDOM:!1,children:[/* @__PURE__ */ _(i,{tab:`关联记录`,itemKey:`relations`,children:/* @__PURE__ */ _(u,{entityType:e.type,entityKey:e.key,enabled:C===`relations`,showAnchor:t})}),!1]})})})}),L&&/* @__PURE__ */ _(F,{entityRef:L,sourceUrl:O(r,S(e)),onClose:()=>R(void 0)})]})}function P({entityType:e,entityKey:t,showAnchor:n=!1}){let r=x();return t?/* @__PURE__ */ _(N,{entityRef:{type:e,key:t},showAnchor:n},`${e}:${t}:${JSON.stringify(r)}`):null}function F({entityRef:e,onClose:t,sourceUrl:n}){let i=JSON.stringify(x()),[s,l]=h(()=>{let t=k(),n=t?.accessKey===i?t.restore:void 0;return n?.kind===`sheet`&&j(n.ref,e)?n.sheetHistory??[e]:[e]}),u=s[s.length-1],d=m(/* @__PURE__ */ new Map);return/* @__PURE__ */ _(o,{title:/* @__PURE__ */ v(r,{children:[s.length>1&&/* @__PURE__ */ _(a,{size:`small`,theme:`borderless`,"aria-label":`返回上一个关联对象`,icon:/* @__PURE__ */ _(c,{size:16}),onClick:()=>l(e=>e.slice(0,-1))}),C(u.type),` · 关联信息`]}),visible:!0,onCancel:t,width:680,closeOnEsc:!0,children:/* @__PURE__ */ _(I.Provider,{value:{history:s,sourceUrl:n,view:d.current.get(`${u.type}:${u.key}`),onLeave:t,open:(e,t)=>{j(e,u)||(d.current.set(`${u.type}:${u.key}`,t),l(t=>[...t,e]))}},children:/* @__PURE__ */ _(P,{entityType:u.type,entityKey:u.key,showAnchor:!0})})})}var I;function L(){return(L=e((()=>{t(),s(),l(),I=d(null)})))()}export{P as n,L as r,F as t};
|
|
2
|
+
//# sourceMappingURL=EntityContextRuntime-CMhoj6qe.js.map
|
package/dist/chunks/{EntityContextRuntime-DbjyzCtY.js.map → EntityContextRuntime-CMhoj6qe.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EntityContextRuntime-DbjyzCtY.js","mappings":"wiCAgBA,SAASA,EAAqB,CAAE,YAAW,cAGxC,CACC,IAAMC,EAAWC,EAAY,EACvBC,EAAWC,EAAY,EACvBC,EAAY,KAAK,UAAUC,EAAmB,CAAC,EAC/CC,EAAQC,EAAWC,CAAkB,EACrCC,EAAOC,EAAuB,IAAI,EAClCC,EAAaC,EAAmC,EAChDC,EAAUP,GAAO,OAASK,GAAY,YAAcP,GAAaU,EAAWH,EAAW,SAAS,IAAKI,CAAS,EAC9GJ,EAAW,SAAS,KAAO,QAC3B,CAACK,EAAKC,GAAUC,EAASL,GAAS,KAAO,WAAW,EACpD,CAACM,EAAgBC,GAAqBF,MAAyB,CAAC,GAAGL,GAAS,gBAAkB,CAAC,CAAC,CAAC,EACjG,CAACQ,EAAaC,GAAkBJ,EAA6B,EA6BnE,OA5BAK,MAAgB,CACZ,GAAKV,GAAYJ,EAAK,QAItB,OAFAQ,EAAOJ,EAAQ,GAAG,EAClBO,EAAkB,CAAC,GAAGP,EAAQ,cAAc,CAAC,EACtCW,EAA4Bf,EAAK,QAASI,EAAQ,MAAM,CACnE,EAAG,CAACA,CAAO,CAAC,EAsBL,kBAAAY,EAAA,WAAE,kBAAC,MAAD,CAAK,IAAKhB,EAAM,sBAAqB,GAAGM,EAAU,KAAK,GAAGA,EAAU,MAC7E,2BAACW,EAAwB,SAAzB,CAAkC,MAtBpB,GAA4B,CACtC,GAAIZ,EAAWa,EAAKZ,CAAS,GAAK,CAACT,EAC/B,OACJ,IAAMsB,EAAQC,EAAkBF,CAAG,EAC7BG,EAAmC,CAAE,MAAK,iBAAgB,OAAQC,EAA4BtB,EAAK,OAAO,CAAE,EAC7GmB,GAOLI,EAA8B,CAC1B,IAAK1B,GAAO,WAAa2B,EAAwBjC,EAAUM,EAAQ,OAAYuB,EAAkBd,CAAS,CAAC,EAC3G,YAAaf,EAAS,IAAK,MAAOA,EAAS,MAAO,IAAKe,EAAW,KAAMT,EAAQ,QAAU,SAAU,OACpG,aAAcA,GAAO,QACrB,cAAe,SAAS,cAA2B,gBAAgB,CAAC,EAAE,WAAa,CACvF,EAAGsB,EAAOxB,EAAWJ,EAAS,QAAQ,EACtCM,GAAO,QAAQ,EACfJ,EAAS0B,CAAK,GAbNtB,EACAA,EAAM,KAAKqB,EAAKG,CAAI,EAEpBR,EAAeK,CAAG,CAW9B,EAGE,2BAACO,EAA+B,SAAhC,CAAyC,MAAO,CAAE,iBAAgB,mBAAkB,EAClF,2BAACC,EAAD,CAAM,YAAY,OAAO,UAAWnB,EAAK,SAAUC,EAAQ,cAAW,QAAS,GAA/E,UACE,kBAACmB,EAAD,CAAS,IAAI,OAAO,QAAQ,YAC1B,2BAACC,EAAD,CAAe,WAAYtB,EAAU,KAAM,UAAWA,EAAU,IAAK,QAASC,IAAQ,YAAyB,YAAY,EACpH,GACR,EACG,C,EACiC,EACT,EAC/B,GAAEK,GAAe,kBAACiB,EAAD,CAAoB,UAAWjB,EAAa,UAAWY,EAAwBjC,EAAU6B,EAAkBd,CAAS,CAAC,EAAG,YAAeO,EAAe,MAAS,CAAG,EAAI,GAC9L,CACA,SAAwBiB,EAAkB,CAAE,aAAY,YAAW,aAAa,IAI7E,CACC,IAAMC,EAASnC,EAAmB,EAGlC,OAFKoC,EAEE,kBAAC1C,EAAD,CAAmF,UAAW,CAAE,KAAM2C,EAAY,IAAKD,CAAU,EAAe,YAAY,EAAjI,GAAGC,EAAW,GAAGD,EAAU,GAAG,KAAK,UAAUD,CAAM,GAA8E,EADxJ,IAEf,CAEA,SAAgBF,EAAmB,CAAE,YAAW,UAAS,aAItD,CACC,IAAMlC,EAAY,KAAK,UAAUC,EAAmB,CAAC,EAC/C,CAACsC,EAASC,GAAc1B,MAA8C,CACxE,IAAMP,EAAakC,EAA4B,EACzChC,EAAUF,GAAY,YAAcP,EAAYO,EAAW,QAAU,OAC3E,OAAOE,GAAS,OAAS,SAAWC,EAAWD,EAAQ,IAAKE,CAAS,EAAIF,EAAQ,cAAgB,CAACE,CAAS,EAAI,CAACA,CAAS,CAC7H,CAAC,EACK+B,EAAUH,EAAQA,EAAQ,OAAS,GACnCI,EAAQrC,kBAAO,IAAI,GAAyC,EAClE,MAAO,kBAACsC,EAAD,CAAW,MAAO,kBAACC,EAAD,WACxBN,EAAQ,OAAS,GAAK,kBAACO,EAAD,CAAQ,KAAK,QAAQ,MAAM,aAAa,aAAW,YAAY,KAAM,kBAACC,EAAD,CAAW,KAAM,EAAI,GAAG,YAAeP,EAAY,GAASQ,EAAK,MAAM,EAAG,EAAE,CAAC,CAAG,GAC3KC,EAAgBP,EAAQ,IAAI,EAAE,SAC1B,IAAG,WAAQ,SAAUQ,EAAS,MAAO,IAAK,cAC/C,2BAAC9C,EAAmB,SAApB,CAA6B,MAAO,CAAE,UAAS,YAAW,KAAMuC,EAAM,QAAQ,IAAI,GAAGD,EAAQ,KAAK,GAAGA,EAAQ,KAAK,EAAG,QAASQ,EAAS,MAAO,EAAK,IAAS,CAC3IxC,EAAWa,EAAKmB,CAAO,IACxBC,EAAM,QAAQ,IAAI,GAAGD,EAAQ,KAAK,GAAGA,EAAQ,MAAOhB,CAAI,EACxDc,EAAY,GAAS,CAAC,GAAGQ,EAAMzB,CAAG,CAAC,EAE3C,CAAE,EACR,2BAACY,EAAD,CAAmB,WAAYO,EAAQ,KAAM,UAAWA,EAAQ,IAAK,aAAW,EACrD,EACpB,EACb,C,gDApGM,EAAqBS,EAMjB,IAAI,C","names":["EntityContextContent","location","useLocation","navigate","useNavigate","accessKey","useEntityAccessKey","sheet","useContext","EntitySheetContext","root","useRef","navigation","useEntityRelationNavigationSession","restore","sameEntity","entityRef","tab","setTab","useState","expandedGroups","setExpandedGroups","fallbackRef","setFallbackRef","useEffect","restoreEntityRelationScroll","_Fragment","EntityNavigationContext","ref","route","entityDetailRoute","view","captureEntityRelationScroll","beginEntityRelationNavigation","entityRelationSourceUrl","EntityRelationViewStateContext","Tabs","TabPane","RelationPanel","EntityContextSheet","EntityContextView","access","entityKey","entityType","history","setHistory","getEntityRelationNavigation","current","views","SideSheet","Space","Button","ArrowLeft","refs","entityTypeLabel","onClose","createContext"],"ignoreList":[],"sources":["../../src/components/entity-relations/EntityContextRuntime.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useRef, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { Button, SideSheet, Space, Tabs, TabPane } from \"@/ui\";\nimport { ArrowLeft } from 'lucide-react';\nimport { type CanonicalEntityRef, type CanonicalEntityType } from '@fudanda/shared/platform/entity-catalog';\nimport { useEntityAccessKey } from \"@fudanda/react-core/hooks/queries/entity-relations\";\nimport { entityDetailRoute, entityTypeLabel } from \"@fudanda/react-core/utils/entity-relations\";\nimport { beginEntityRelationNavigation, captureEntityRelationScroll, EntityNavigationContext, EntityRelationViewStateContext, entityRelationSourceUrl, getEntityRelationNavigation, restoreEntityRelationScroll, sameEntity, useEntityRelationNavigationSession, type EntityRelationViewSnapshot } from \"@fudanda/react-core/components/entity-relations/entity-navigation\";\nimport RelationPanel from \"@/components/entity-relations/RelationPanel\";\nconst EntitySheetContext = createContext<{\n history: readonly CanonicalEntityRef[];\n sourceUrl?: string;\n view?: EntityRelationViewSnapshot;\n onLeave: () => void;\n open: (ref: CanonicalEntityRef, view: EntityRelationViewSnapshot) => void;\n} | null>(null);\nfunction EntityContextContent({ entityRef, showAnchor }: {\n readonly entityRef: CanonicalEntityRef;\n readonly showAnchor: boolean;\n}) {\n const location = useLocation();\n const navigate = useNavigate();\n const accessKey = JSON.stringify(useEntityAccessKey());\n const sheet = useContext(EntitySheetContext);\n const root = useRef<HTMLDivElement>(null);\n const navigation = useEntityRelationNavigationSession();\n const restore = sheet?.view ?? (navigation?.accessKey === accessKey && sameEntity(navigation.restore?.ref, entityRef)\n ? navigation.restore?.view : undefined);\n const [tab, setTab] = useState(restore?.tab ?? 'relations');\n const [expandedGroups, setExpandedGroups] = useState<string[]>(() => [...restore?.expandedGroups ?? []]);\n const [fallbackRef, setFallbackRef] = useState<CanonicalEntityRef>();\n useEffect(() => {\n if (!restore || !root.current)\n return;\n setTab(restore.tab);\n setExpandedGroups([...restore.expandedGroups]);\n return restoreEntityRelationScroll(root.current, restore.scroll);\n }, [restore]);\n const open = (ref: CanonicalEntityRef) => {\n if (sameEntity(ref, entityRef) && !sheet)\n return;\n const route = entityDetailRoute(ref);\n const view: EntityRelationViewSnapshot = { tab, expandedGroups, scroll: captureEntityRelationScroll(root.current) };\n if (!route) {\n if (sheet)\n sheet.open(ref, view);\n else\n setFallbackRef(ref);\n return;\n }\n beginEntityRelationNavigation({\n url: sheet?.sourceUrl ?? entityRelationSourceUrl(location, sheet ? undefined : entityDetailRoute(entityRef)),\n locationKey: location.key, state: location.state, ref: entityRef, kind: sheet ? 'sheet' : 'detail', view,\n sheetHistory: sheet?.history,\n pageScrollTop: document.querySelector<HTMLElement>('.admin-content')?.scrollTop ?? 0,\n }, route, accessKey, location.pathname);\n sheet?.onLeave();\n navigate(route);\n };\n return <><div ref={root} data-entity-context={`${entityRef.type}:${entityRef.key}`}>\n <EntityNavigationContext.Provider value={open}>\n <EntityRelationViewStateContext.Provider value={{ expandedGroups, setExpandedGroups }}>\n <Tabs collapsible=\"auto\" activeKey={tab} onChange={setTab} lazyRender keepDOM={false}>\n <TabPane tab=\"关联记录\" itemKey=\"relations\">\n <RelationPanel entityType={entityRef.type} entityKey={entityRef.key} enabled={tab === 'relations'} showAnchor={showAnchor}/>\n </TabPane>\n {false}\n </Tabs>\n </EntityRelationViewStateContext.Provider>\n </EntityNavigationContext.Provider>\n </div>{fallbackRef && <EntityContextSheet entityRef={fallbackRef} sourceUrl={entityRelationSourceUrl(location, entityDetailRoute(entityRef))} onClose={() => setFallbackRef(undefined)}/>}</>;\n}\nexport default function EntityContextView({ entityType, entityKey, showAnchor = false }: {\n readonly entityType: CanonicalEntityType;\n readonly entityKey: string | undefined;\n readonly showAnchor?: boolean;\n}) {\n const access = useEntityAccessKey();\n if (!entityKey)\n return null;\n return <EntityContextContent key={`${entityType}:${entityKey}:${JSON.stringify(access)}`} entityRef={{ type: entityType, key: entityKey }} showAnchor={showAnchor}/>;\n}\n/** Both embedded views and the drawer share one deferred runtime. */\nexport function EntityContextSheet({ entityRef, onClose, sourceUrl }: {\n readonly entityRef: CanonicalEntityRef;\n readonly onClose: () => void;\n readonly sourceUrl?: string;\n}) {\n const accessKey = JSON.stringify(useEntityAccessKey());\n const [history, setHistory] = useState<readonly CanonicalEntityRef[]>(() => {\n const navigation = getEntityRelationNavigation();\n const restore = navigation?.accessKey === accessKey ? navigation.restore : undefined;\n return restore?.kind === 'sheet' && sameEntity(restore.ref, entityRef) ? restore.sheetHistory ?? [entityRef] : [entityRef];\n });\n const current = history[history.length - 1];\n const views = useRef(new Map<string, EntityRelationViewSnapshot>());\n return <SideSheet title={<Space>\n {history.length > 1 && <Button size=\"small\" theme=\"borderless\" aria-label=\"返回上一个关联对象\" icon={<ArrowLeft size={16}/>} onClick={() => setHistory((refs) => refs.slice(0, -1))}/>}\n {entityTypeLabel(current.type)} · 关联信息\n </Space>} visible onCancel={onClose} width={680} closeOnEsc>\n <EntitySheetContext.Provider value={{ history, sourceUrl, view: views.current.get(`${current.type}:${current.key}`), onLeave: onClose, open: (ref, view) => {\n if (!sameEntity(ref, current)) {\n views.current.set(`${current.type}:${current.key}`, view);\n setHistory((refs) => [...refs, ref]);\n }\n } }}>\n <EntityContextView entityType={current.type} entityKey={current.key} showAnchor/>\n </EntitySheetContext.Provider>\n </SideSheet>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"EntityContextRuntime-CMhoj6qe.js","mappings":"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","names":["EntityContextContent","location","useLocation","navigate","useNavigate","accessKey","useEntityAccessKey","sheet","useContext","EntitySheetContext","root","useRef","navigation","useEntityRelationNavigationSession","restore","sameEntity","entityRef","tab","setTab","useState","expandedGroups","setExpandedGroups","fallbackRef","setFallbackRef","useEffect","restoreEntityRelationScroll","_Fragment","EntityNavigationContext","ref","route","entityDetailRoute","view","captureEntityRelationScroll","beginEntityRelationNavigation","entityRelationSourceUrl","EntityRelationViewStateContext","Tabs","TabPane","RelationPanel","EntityContextSheet","EntityContextView","access","entityKey","entityType","history","setHistory","getEntityRelationNavigation","current","views","SideSheet","Space","Button","ArrowLeft","refs","entityTypeLabel","onClose","createContext"],"ignoreList":[],"sources":["../../src/components/entity-relations/EntityContextRuntime.tsx"],"sourcesContent":["import { createContext, useContext, useEffect, useRef, useState } from 'react';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport { Button, SideSheet, Space, Tabs, TabPane } from \"@/ui\";\nimport { ArrowLeft } from 'lucide-react';\nimport { type CanonicalEntityRef, type CanonicalEntityType } from '@fudanda/shared/platform/entity-catalog';\nimport { useEntityAccessKey } from \"@fudanda/react-core/hooks/queries/entity-relations\";\nimport { entityDetailRoute, entityTypeLabel } from \"@fudanda/react-core/utils/entity-relations\";\nimport { beginEntityRelationNavigation, captureEntityRelationScroll, EntityNavigationContext, EntityRelationViewStateContext, entityRelationSourceUrl, getEntityRelationNavigation, restoreEntityRelationScroll, sameEntity, useEntityRelationNavigationSession, type EntityRelationViewSnapshot } from \"@fudanda/react-core/components/entity-relations/entity-navigation\";\nimport RelationPanel from \"@/components/entity-relations/RelationPanel\";\nconst EntitySheetContext = createContext<{\n history: readonly CanonicalEntityRef[];\n sourceUrl?: string;\n view?: EntityRelationViewSnapshot;\n onLeave: () => void;\n open: (ref: CanonicalEntityRef, view: EntityRelationViewSnapshot) => void;\n} | null>(null);\nfunction EntityContextContent({ entityRef, showAnchor }: {\n readonly entityRef: CanonicalEntityRef;\n readonly showAnchor: boolean;\n}) {\n const location = useLocation();\n const navigate = useNavigate();\n const accessKey = JSON.stringify(useEntityAccessKey());\n const sheet = useContext(EntitySheetContext);\n const root = useRef<HTMLDivElement>(null);\n const navigation = useEntityRelationNavigationSession();\n const restore = sheet?.view ?? (navigation?.accessKey === accessKey && sameEntity(navigation.restore?.ref, entityRef)\n ? navigation.restore?.view : undefined);\n const [tab, setTab] = useState(restore?.tab ?? 'relations');\n const [expandedGroups, setExpandedGroups] = useState<string[]>(() => [...restore?.expandedGroups ?? []]);\n const [fallbackRef, setFallbackRef] = useState<CanonicalEntityRef>();\n useEffect(() => {\n if (!restore || !root.current)\n return;\n setTab(restore.tab);\n setExpandedGroups([...restore.expandedGroups]);\n return restoreEntityRelationScroll(root.current, restore.scroll);\n }, [restore]);\n const open = (ref: CanonicalEntityRef) => {\n if (sameEntity(ref, entityRef) && !sheet)\n return;\n const route = entityDetailRoute(ref);\n const view: EntityRelationViewSnapshot = { tab, expandedGroups, scroll: captureEntityRelationScroll(root.current) };\n if (!route) {\n if (sheet)\n sheet.open(ref, view);\n else\n setFallbackRef(ref);\n return;\n }\n beginEntityRelationNavigation({\n url: sheet?.sourceUrl ?? entityRelationSourceUrl(location, sheet ? undefined : entityDetailRoute(entityRef)),\n locationKey: location.key, state: location.state, ref: entityRef, kind: sheet ? 'sheet' : 'detail', view,\n sheetHistory: sheet?.history,\n pageScrollTop: document.querySelector<HTMLElement>('.admin-content')?.scrollTop ?? 0,\n }, route, accessKey, location.pathname);\n sheet?.onLeave();\n navigate(route);\n };\n return <><div ref={root} data-entity-context={`${entityRef.type}:${entityRef.key}`}>\n <EntityNavigationContext.Provider value={open}>\n <EntityRelationViewStateContext.Provider value={{ expandedGroups, setExpandedGroups }}>\n <Tabs collapsible=\"auto\" activeKey={tab} onChange={setTab} lazyRender keepDOM={false}>\n <TabPane tab=\"关联记录\" itemKey=\"relations\">\n <RelationPanel entityType={entityRef.type} entityKey={entityRef.key} enabled={tab === 'relations'} showAnchor={showAnchor}/>\n </TabPane>\n {false}\n </Tabs>\n </EntityRelationViewStateContext.Provider>\n </EntityNavigationContext.Provider>\n </div>{fallbackRef && <EntityContextSheet entityRef={fallbackRef} sourceUrl={entityRelationSourceUrl(location, entityDetailRoute(entityRef))} onClose={() => setFallbackRef(undefined)}/>}</>;\n}\nexport default function EntityContextView({ entityType, entityKey, showAnchor = false }: {\n readonly entityType: CanonicalEntityType;\n readonly entityKey: string | undefined;\n readonly showAnchor?: boolean;\n}) {\n const access = useEntityAccessKey();\n if (!entityKey)\n return null;\n return <EntityContextContent key={`${entityType}:${entityKey}:${JSON.stringify(access)}`} entityRef={{ type: entityType, key: entityKey }} showAnchor={showAnchor}/>;\n}\n/** Both embedded views and the drawer share one deferred runtime. */\nexport function EntityContextSheet({ entityRef, onClose, sourceUrl }: {\n readonly entityRef: CanonicalEntityRef;\n readonly onClose: () => void;\n readonly sourceUrl?: string;\n}) {\n const accessKey = JSON.stringify(useEntityAccessKey());\n const [history, setHistory] = useState<readonly CanonicalEntityRef[]>(() => {\n const navigation = getEntityRelationNavigation();\n const restore = navigation?.accessKey === accessKey ? navigation.restore : undefined;\n return restore?.kind === 'sheet' && sameEntity(restore.ref, entityRef) ? restore.sheetHistory ?? [entityRef] : [entityRef];\n });\n const current = history[history.length - 1];\n const views = useRef(new Map<string, EntityRelationViewSnapshot>());\n return <SideSheet title={<Space>\n {history.length > 1 && <Button size=\"small\" theme=\"borderless\" aria-label=\"返回上一个关联对象\" icon={<ArrowLeft size={16}/>} onClick={() => setHistory((refs) => refs.slice(0, -1))}/>}\n {entityTypeLabel(current.type)} · 关联信息\n </Space>} visible onCancel={onClose} width={680} closeOnEsc>\n <EntitySheetContext.Provider value={{ history, sourceUrl, view: views.current.get(`${current.type}:${current.key}`), onLeave: onClose, open: (ref, view) => {\n if (!sameEntity(ref, current)) {\n views.current.set(`${current.type}:${current.key}`, view);\n setHistory((refs) => [...refs, ref]);\n }\n } }}>\n <EntityContextView entityType={current.type} entityKey={current.key} showAnchor/>\n </EntitySheetContext.Provider>\n </SideSheet>;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,r as t,t as n}from"./EntityContextRuntime-CMhoj6qe.js";t();export{n as EntityContextSheet,e as default};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{D as t,M as n,T as r,m as i,y as a}from"./clipboard-dpqHdCyy.js";import{i as o}from"./feedback-B1UL2ETz.js";import{B as s,R as c,V as l,z as u}from"./App-
|
|
2
|
-
//# sourceMappingURL=ExportButton-
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Bruge11p.js";import{D as t,M as n,T as r,m as i,y as a}from"./clipboard-dpqHdCyy.js";import{i as o}from"./feedback-B1UL2ETz.js";import{B as s,R as c,V as l,z as u}from"./App-nh6_qOo8.js";import{useContext as d}from"react";import{jsx as f,jsxs as p}from"react/jsx-runtime";import{usePermission as m}from"@fudanda/admin-antd/core/hooks/usePermission";import{ToolbarSlotContext as h}from"@fudanda/admin-antd/core/components/toolbar-slot-context";import{useExportJobRunner as g}from"@fudanda/admin-antd/core/hooks/useExportJobRunner";function _(){return g(o)}function v(){return(v=e((()=>{n()})))()}function y({entity:e,query:n,resolveQuery:o,label:l=`导出`,formats:u=[`xlsx`,`csv`],raw:g=!1,watermark:v=!0,executionMode:y=`sync`,variant:b=`primary`,permission:x}){let S=_(),{hasPermission:C}=m(),w=d(h);if(x&&!C(x))return null;let T=b===`flat`||w===`mobile-actions`,E=T?`borderless`:void 0,D=`export-button${T?` export-button--flat`:``}`,O=async t=>{let r=o?await o(t):n??{};r!=null&&await S.runExport({entity:e,format:t,query:r,raw:g,watermark:v,executionMode:y})};if(u.length<=1){let e=u[0]??`xlsx`;return/* @__PURE__ */ f(i,{className:D,type:`primary`,theme:E,icon:/* @__PURE__ */ f(c,{size:14}),loading:S.isPending&&S.pendingFormat===e,onClick:()=>void O(e),children:l})}return T?/* @__PURE__ */ f(r,{vertical:!0,align:`start`,spacing:8,className:D,style:{width:`100%`},children:u.map(e=>/* @__PURE__ */ p(i,{className:`export-button__flat-item`,type:`primary`,theme:`borderless`,icon:/* @__PURE__ */ f(c,{size:14}),loading:S.isPending&&S.pendingFormat===e,onClick:()=>void O(e),children:[l,` `,e.toUpperCase()]},e))}):/* @__PURE__ */ f(`span`,{className:D,children:/* @__PURE__ */ p(t,{children:[/* @__PURE__ */ f(i,{className:`export-button__main`,type:`primary`,theme:E,icon:/* @__PURE__ */ f(c,{size:14}),loading:S.isPending&&S.pendingFormat===`xlsx`,onClick:()=>void O(`xlsx`),children:l}),/* @__PURE__ */ f(a,{trigger:`click`,position:`bottomRight`,clickToHide:!0,render:/* @__PURE__ */ f(a.Menu,{children:u.map(e=>/* @__PURE__ */ p(a.Item,{onClick:()=>void O(e),children:[`导出 `,e.toUpperCase()]},e))}),children:/* @__PURE__ */ f(i,{className:`export-button__trigger`,"aria-label":`选择${l}格式`,type:`primary`,theme:E,icon:/* @__PURE__ */ f(s,{size:14}),loading:S.isPending&&S.pendingFormat!==`xlsx`})})]})})}function b(){return(b=e((()=>{n(),l(),u(),v()})))()}export{b as n,y as t};
|
|
2
|
+
//# sourceMappingURL=ExportButton-DGxB2tcu.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExportButton-
|
|
1
|
+
{"version":3,"file":"ExportButton-DGxB2tcu.js","mappings":"wjBAEA,SAAgBA,GAAqB,CAAE,OAAOC,EAAyBC,CAAK,CAAG,C,wCCsB/E,SAAgBC,EAAa,CAAE,SAAQ,QAAO,eAAc,QAAQ,KAAM,UAAU,CAAC,OAAQ,KAAK,EAElG,MAAM,GAAO,YAAY,GAAM,gBAAgB,OAAQ,UAAU,UAAW,cAA4C,CACpH,IAAMC,EAAeJ,EAAmB,EAClC,CAAE,iBAAkBK,EAAc,EAClCC,EAAcC,EAAWC,CAAkB,EACjD,GAAIC,GAAc,CAACC,EAAcD,CAAU,EACvC,OAAO,KACX,IAAME,EAASC,IAAY,QAAUN,IAAgB,iBAC/CO,EAAcF,EAAS,aAAe,OACtCG,EAAgB,gBAAgBH,EAAS,uBAAyB,KAClEI,EAAY,KAAO,IAA4B,CACjD,IAAMC,EAAgBC,EAAe,MAAMA,EAAaC,CAAM,EAAKC,GAAS,CAAC,EACzEH,GAAiB,MAErB,MAAMZ,EAAa,UAAU,CACzB,SACA,SACA,MAAOY,EACP,MACA,YACA,eACJ,CAAC,CACL,EACA,GAAII,EAAQ,QAAU,EAAG,CACrB,IAAMF,EAASE,EAAQ,IAAM,OAC7B,MAAQ,kBAACC,EAAD,CAAQ,UAAWP,EAAe,KAAK,UAAU,MAAOD,EAAa,KAAM,kBAACS,EAAD,CAAU,KAAM,EAAI,GAAG,QAASlB,EAAa,WAAaA,EAAa,gBAAkBc,EAAQ,YAAe,KAAKH,EAAUG,CAAM,EACvN,SAAAK,CACK,EACV,CAQA,OAPIZ,EACQ,kBAACa,EAAD,CAAO,YAAS,MAAM,QAAQ,QAAS,EAAG,UAAWV,EAAe,MAAO,CAAE,MAAO,MAAO,EAClG,SAAAM,EAAQ,IAAK,GAAY,kBAACC,EAAD,CAAqB,UAAU,2BAA2B,KAAK,UAAU,MAAM,aAAa,KAAM,kBAACC,EAAD,CAAU,KAAM,EAAI,GAAG,QAASlB,EAAa,WAAaA,EAAa,gBAAkBc,EAAQ,YAAe,KAAKH,EAAUG,CAAM,EAAvO,UACrBK,EAAM,IAAEL,EAAO,YAAY,CACtB,CAF6B,EAAAA,CAE7B,CAAE,CACP,GAED,kBAAC,OAAD,CAAM,UAAWJ,EACvB,2BAACW,EAAD,WACE,kBAACJ,EAAD,CAAQ,UAAU,sBAAsB,KAAK,UAAU,MAAOR,EAAa,KAAM,kBAACS,EAAD,CAAU,KAAM,EAAI,GAAG,QAASlB,EAAa,WAAaA,EAAa,gBAAkB,OAAQ,YAAe,KAAKW,EAAU,MAAM,EACnN,SAAAQ,CACK,GACR,kBAACG,EAAD,CAAU,QAAQ,QAAQ,SAAS,cAAc,eAAY,OAAS,kBAACA,EAAS,KAAV,UAC/DN,EAAQ,IAAK,GAAY,kBAACM,EAAS,KAAV,CAA4B,YAAe,KAAKX,EAAUG,CAAM,EAAhE,UAAmE,MACrFA,EAAO,YAAY,CACV,CAF6B,EAAAA,CAE7B,CAAE,CACN,GACjB,2BAACG,EAAD,CAAQ,UAAU,yBAAyB,aAAY,KAAKE,EAAM,IAAK,KAAK,UAAU,MAAOV,EAAa,KAAM,kBAACc,EAAD,CAAa,KAAM,EAAI,GAAG,QAASvB,EAAa,WAAaA,EAAa,gBAAkB,MAAQ,EAC5M,EACM,GACd,EACV,C","names":["useExportJobRunner","useSharedExportJobRunner","Toast","ExportButton","exportRunner","usePermission","toolbarSlot","useContext","ToolbarSlotContext","permission","hasPermission","isFlat","variant","buttonTheme","rootClassName","runExport","resolvedQuery","resolveQuery","format","query","formats","Button","Download","label","Space","SplitButtonGroup","Dropdown","ChevronDown"],"ignoreList":[],"sources":["../../src/hooks/useExportJobRunner.ts","../../src/components/ExportButton.tsx"],"sourcesContent":["import { Toast } from '@/ui';\nimport { useExportJobRunner as useSharedExportJobRunner } from '@fudanda/react-core/hooks/useExportJobRunner';\nexport function useExportJobRunner() { return useSharedExportJobRunner(Toast); }\n","import { useContext } from 'react';\nimport { Button, Dropdown, Space, SplitButtonGroup } from \"@/ui\";\nimport { ChevronDown, Download } from 'lucide-react';\nimport type { Permission } from '@fudanda/shared/core';\nimport type { ExportJobRunOptions } from '@fudanda/react-core/hooks/useExportJobRunner';\ntype ExportJobFormat = ExportJobRunOptions['format'];\ntype ExportJobRequestMode = NonNullable<ExportJobRunOptions['executionMode']>;\nimport { ToolbarSlotContext } from \"@fudanda/react-core/components/toolbar-slot-context\";\nimport { useExportJobRunner } from \"@/hooks/useExportJobRunner\";\nimport { usePermission } from \"@fudanda/react-core/hooks/usePermission\";\ninterface ExportButtonProps {\n entity: string;\n query?: Record<string, unknown>;\n resolveQuery?: (format: ExportJobFormat) => Promise<Record<string, unknown> | null> | Record<string, unknown> | null;\n label?: string;\n formats?: ExportJobFormat[];\n raw?: boolean;\n watermark?: boolean;\n executionMode?: ExportJobRequestMode;\n /** `flat` 为逐格式平铺按钮;放进工具栏移动端「更多操作」菜单时自动切换,无需显式传 */\n variant?: 'primary' | 'flat';\n /** Optional capability gate; omitted for non-CMS/shared callers. */\n permission?: Permission;\n}\nexport function ExportButton({ entity, query, resolveQuery, label = '导出', formats = ['xlsx', 'csv'],\n// 安全默认:脱敏导出。明文导出需显式传 raw,且服务端校验 export-raw 权限\nraw = false, watermark = true, executionMode = 'sync', variant = 'primary', permission, }: Readonly<ExportButtonProps>) {\n const exportRunner = useExportJobRunner();\n const { hasPermission } = usePermission();\n const toolbarSlot = useContext(ToolbarSlotContext);\n if (permission && !hasPermission(permission))\n return null;\n const isFlat = variant === 'flat' || toolbarSlot === 'mobile-actions';\n const buttonTheme = isFlat ? 'borderless' : undefined;\n const rootClassName = `export-button${isFlat ? ' export-button--flat' : ''}`;\n const runExport = async (format: ExportJobFormat) => {\n const resolvedQuery = resolveQuery ? await resolveQuery(format) : (query ?? {});\n if (resolvedQuery == null)\n return;\n await exportRunner.runExport({\n entity,\n format,\n query: resolvedQuery,\n raw,\n watermark,\n executionMode,\n });\n };\n if (formats.length <= 1) {\n const format = formats[0] ?? 'xlsx';\n return (<Button className={rootClassName} type=\"primary\" theme={buttonTheme} icon={<Download size={14}/>} loading={exportRunner.isPending && exportRunner.pendingFormat === format} onClick={() => void runExport(format)}>\n {label}\n </Button>);\n }\n if (isFlat) {\n return (<Space vertical align=\"start\" spacing={8} className={rootClassName} style={{ width: '100%' }}>\n {formats.map((format) => (<Button key={format} className=\"export-button__flat-item\" type=\"primary\" theme=\"borderless\" icon={<Download size={14}/>} loading={exportRunner.isPending && exportRunner.pendingFormat === format} onClick={() => void runExport(format)}>\n {label} {format.toUpperCase()}\n </Button>))}\n </Space>);\n }\n return (<span className={rootClassName}>\n <SplitButtonGroup>\n <Button className=\"export-button__main\" type=\"primary\" theme={buttonTheme} icon={<Download size={14}/>} loading={exportRunner.isPending && exportRunner.pendingFormat === 'xlsx'} onClick={() => void runExport('xlsx')}>\n {label}\n </Button>\n <Dropdown trigger=\"click\" position=\"bottomRight\" clickToHide render={(<Dropdown.Menu>\n {formats.map((format) => (<Dropdown.Item key={format} onClick={() => void runExport(format)}>\n 导出 {format.toUpperCase()}\n </Dropdown.Item>))}\n </Dropdown.Menu>)}>\n <Button className=\"export-button__trigger\" aria-label={`选择${label}格式`} type=\"primary\" theme={buttonTheme} icon={<ChevronDown size={14}/>} loading={exportRunner.isPending && exportRunner.pendingFormat !== 'xlsx'}/>\n </Dropdown>\n </SplitButtonGroup>\n </span>);\n}\nexport default ExportButton;\n"]}
|