@fudanda/admin-antd 2.20261109.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.
Files changed (97) hide show
  1. package/dist/chunks/ApiTokensPage-w3JGRNQC.js +2 -0
  2. package/dist/chunks/ApiTokensPage-w3JGRNQC.js.map +1 -0
  3. package/dist/chunks/{App-CfQx7jWq.js → App-nh6_qOo8.js} +5 -5
  4. package/dist/chunks/{App-CfQx7jWq.js.map → App-nh6_qOo8.js.map} +1 -1
  5. package/dist/chunks/{AppModal-CVoUC2t3.js → AppModal-CEouaU03.js} +2 -2
  6. package/dist/chunks/{AppModal-CVoUC2t3.js.map → AppModal-CEouaU03.js.map} +1 -1
  7. package/dist/chunks/{ArcBaseAdmin-DQyddbFC.js → ArcBaseAdmin-CX7fQz4x.js} +2 -2
  8. package/dist/chunks/{ArcBaseAdmin-DQyddbFC.js.map → ArcBaseAdmin-CX7fQz4x.js.map} +1 -1
  9. package/dist/chunks/{DepartmentsPage-CQx53QGE.js → DepartmentsPage-BdD9VfDI.js} +2 -2
  10. package/dist/chunks/{DepartmentsPage-CQx53QGE.js.map → DepartmentsPage-BdD9VfDI.js.map} +1 -1
  11. package/dist/chunks/{DictsPage-BGnamkWk.js → DictsPage-fxBdV1-3.js} +2 -2
  12. package/dist/chunks/{DictsPage-BGnamkWk.js.map → DictsPage-fxBdV1-3.js.map} +1 -1
  13. package/dist/chunks/{EntityContextRuntime-CbzeMNXR.js → EntityContextRuntime-CMhoj6qe.js} +2 -2
  14. package/dist/chunks/{EntityContextRuntime-CbzeMNXR.js.map → EntityContextRuntime-CMhoj6qe.js.map} +1 -1
  15. package/dist/chunks/EntityContextRuntime-Dc89ZSnM.js +1 -0
  16. package/dist/chunks/{ExportButton-sMPAV2hd.js → ExportButton-DGxB2tcu.js} +2 -2
  17. package/dist/chunks/{ExportButton-sMPAV2hd.js.map → ExportButton-DGxB2tcu.js.map} +1 -1
  18. package/dist/chunks/{FileViewerPreviewPanel-Rti7pUhU.js → FileViewerPreviewPanel-BMZ7FdKV.js} +3 -3
  19. package/dist/chunks/{FileViewerPreviewPanel-Rti7pUhU.js.map → FileViewerPreviewPanel-BMZ7FdKV.js.map} +1 -1
  20. package/dist/chunks/{FilesPage-D_iYsUwl.js → FilesPage-DrgWELKy.js} +3 -3
  21. package/dist/chunks/{FilesPage-D_iYsUwl.js.map → FilesPage-DrgWELKy.js.map} +1 -1
  22. package/dist/chunks/{IdentitySecurityPage-rDYX5ksX.js → IdentitySecurityPage-BjTKvr-O.js} +2 -2
  23. package/dist/chunks/{IdentitySecurityPage-rDYX5ksX.js.map → IdentitySecurityPage-BjTKvr-O.js.map} +1 -1
  24. package/dist/chunks/{LogStatsScaffold-CMIz4z0a.js → LogStatsScaffold-DaB0JeAN.js} +2 -2
  25. package/dist/chunks/{LogStatsScaffold-CMIz4z0a.js.map → LogStatsScaffold-DaB0JeAN.js.map} +1 -1
  26. package/dist/chunks/{LoginLogsPage-Bv5pPJb2.js → LoginLogsPage-VmYC7i6q.js} +2 -2
  27. package/dist/chunks/{LoginLogsPage-Bv5pPJb2.js.map → LoginLogsPage-VmYC7i6q.js.map} +1 -1
  28. package/dist/chunks/{LoginLogsTable-DYcTx2oR.js → LoginLogsTable-CULcc_e8.js} +2 -2
  29. package/dist/chunks/{LoginLogsTable-DYcTx2oR.js.map → LoginLogsTable-CULcc_e8.js.map} +1 -1
  30. package/dist/chunks/{MarkdownPreviewPanel-lqs6AsoN.js → MarkdownPreviewPanel-CBcPc7Wv.js} +2 -2
  31. package/dist/chunks/{MarkdownPreviewPanel-lqs6AsoN.js.map → MarkdownPreviewPanel-CBcPc7Wv.js.map} +1 -1
  32. package/dist/chunks/{MasterDetailLayout-B5uqvh98.js → MasterDetailLayout-ByIBpmkZ.js} +2 -2
  33. package/dist/chunks/{MasterDetailLayout-B5uqvh98.js.map → MasterDetailLayout-ByIBpmkZ.js.map} +1 -1
  34. package/dist/chunks/{McpSettingsPage-Cdej9Evi.js → McpSettingsPage-C5V_rj2V.js} +2 -2
  35. package/dist/chunks/{McpSettingsPage-Cdej9Evi.js.map → McpSettingsPage-C5V_rj2V.js.map} +1 -1
  36. package/dist/chunks/{MemberAssignmentSheet-AKvLbbYW.js → MemberAssignmentSheet-DL0fg1Yf.js} +2 -2
  37. package/dist/chunks/{MemberAssignmentSheet-AKvLbbYW.js.map → MemberAssignmentSheet-DL0fg1Yf.js.map} +1 -1
  38. package/dist/chunks/{MenuCommandPalette-ia0pSIFg.js → MenuCommandPalette-C2PvK3Gh.js} +2 -2
  39. package/dist/chunks/{MenuCommandPalette-ia0pSIFg.js.map → MenuCommandPalette-C2PvK3Gh.js.map} +1 -1
  40. package/dist/chunks/{MenusPage-Bh55bvKH.js → MenusPage-Bytd1HlW.js} +2 -2
  41. package/dist/chunks/{MenusPage-Bh55bvKH.js.map → MenusPage-Bytd1HlW.js.map} +1 -1
  42. package/dist/chunks/{MonacoPreviewPanel-CT_sjf7Z.js → MonacoPreviewPanel-BZrNIcFZ.js} +2 -2
  43. package/dist/chunks/{MonacoPreviewPanel-CT_sjf7Z.js.map → MonacoPreviewPanel-BZrNIcFZ.js.map} +1 -1
  44. package/dist/chunks/{NavListPanel-DMIUMh7q.js → NavListPanel-zwUDIYSP.js} +2 -2
  45. package/dist/chunks/{NavListPanel-DMIUMh7q.js.map → NavListPanel-zwUDIYSP.js.map} +1 -1
  46. package/dist/chunks/{OperationLogsPage-7XVfmhxP.js → OperationLogsPage-D2BQdGNp.js} +2 -2
  47. package/dist/chunks/{OperationLogsPage-7XVfmhxP.js.map → OperationLogsPage-D2BQdGNp.js.map} +1 -1
  48. package/dist/chunks/{OperationLogsTable-gp-WZxiF.js → OperationLogsTable-DaaON4QR.js} +3 -3
  49. package/dist/chunks/{OperationLogsTable-gp-WZxiF.js.map → OperationLogsTable-DaaON4QR.js.map} +1 -1
  50. package/dist/chunks/{PDFPreviewPanel-CyfhyWav.js → PDFPreviewPanel-CMmnWBKW.js} +3 -3
  51. package/dist/chunks/{PDFPreviewPanel-CyfhyWav.js.map → PDFPreviewPanel-CMmnWBKW.js.map} +1 -1
  52. package/dist/chunks/{PositionsPage-Bwua1vNV.js → PositionsPage-CBZITssT.js} +2 -2
  53. package/dist/chunks/{PositionsPage-Bwua1vNV.js.map → PositionsPage-CBZITssT.js.map} +1 -1
  54. package/dist/chunks/{PreferencesSheetBody-C80D3dOM.js → PreferencesSheetBody-B0poTPEA.js} +2 -2
  55. package/dist/chunks/{PreferencesSheetBody-C80D3dOM.js.map → PreferencesSheetBody-B0poTPEA.js.map} +1 -1
  56. package/dist/chunks/{ProfilePage-DeTw-59a.js → ProfilePage-DLhacdWt.js} +2 -2
  57. package/dist/chunks/{ProfilePage-DeTw-59a.js.map → ProfilePage-DLhacdWt.js.map} +1 -1
  58. package/dist/chunks/{ProjectInfoPage-Bqn3gfXa.js → ProjectInfoPage-CJpGxpu5.js} +2 -2
  59. package/dist/chunks/{ProjectInfoPage-Bqn3gfXa.js.map → ProjectInfoPage-CJpGxpu5.js.map} +1 -1
  60. package/dist/chunks/{RelationPanel-Bio-ig-l.js → RelationPanel-BsbfEDo2.js} +2 -2
  61. package/dist/chunks/{RelationPanel-Bio-ig-l.js.map → RelationPanel-BsbfEDo2.js.map} +1 -1
  62. package/dist/chunks/{RolesPage-fwUSs2HR.js → RolesPage-46dzdiah.js} +2 -2
  63. package/dist/chunks/{RolesPage-fwUSs2HR.js.map → RolesPage-46dzdiah.js.map} +1 -1
  64. package/dist/chunks/{SessionConflictModal-Dw4opoNP.js → SessionConflictModal-Bm38eExL.js} +2 -2
  65. package/dist/chunks/{SessionConflictModal-Dw4opoNP.js.map → SessionConflictModal-Bm38eExL.js.map} +1 -1
  66. package/dist/chunks/SettingModuleDetail-BjxUJeH5.js +17 -0
  67. package/dist/chunks/SettingModuleDetail-BjxUJeH5.js.map +1 -0
  68. package/dist/chunks/{SettingsPage-Cy5-q-P6.js → SettingsPage-C32Vuizm.js} +2 -2
  69. package/dist/chunks/{SettingsPage-Cy5-q-P6.js.map → SettingsPage-C32Vuizm.js.map} +1 -1
  70. package/dist/chunks/{StatCard-BROG4NSp.js → StatCard-CRPfkSBY.js} +2 -2
  71. package/dist/chunks/{StatCard-BROG4NSp.js.map → StatCard-CRPfkSBY.js.map} +1 -1
  72. package/dist/chunks/{UserGroupsPage-CsTBkUPy.js → UserGroupsPage-08G5MdGm.js} +2 -2
  73. package/dist/chunks/{UserGroupsPage-CsTBkUPy.js.map → UserGroupsPage-08G5MdGm.js.map} +1 -1
  74. package/dist/chunks/{UserLogsPanels-3u8Z93YU.js → UserLogsPanels-nbIrMym9.js} +2 -2
  75. package/dist/chunks/{UserLogsPanels-3u8Z93YU.js.map → UserLogsPanels-nbIrMym9.js.map} +1 -1
  76. package/dist/chunks/{UserTransferSelect-ChLj4EkS.js → UserTransferSelect-C8betaWG.js} +2 -2
  77. package/dist/chunks/{UserTransferSelect-ChLj4EkS.js.map → UserTransferSelect-C8betaWG.js.map} +1 -1
  78. package/dist/chunks/{UsersPage-CfNnQJi4.js → UsersPage-BjTiNEqF.js} +2 -2
  79. package/dist/chunks/{UsersPage-CfNnQJi4.js.map → UsersPage-BjTiNEqF.js.map} +1 -1
  80. package/dist/chunks/{browser-BKLM0ThC-D0TgzKTC.js → browser-BKLM0ThC-Cp7Gi4-F.js} +1 -1
  81. package/dist/chunks/{code-BkkeN2fd.js → code-LswxAr98.js} +1 -1
  82. package/dist/chunks/{direct-engine-m32m22nx.js → direct-engine-Dv_6v4sx.js} +1 -1
  83. package/dist/chunks/{html-BGNWR_Bp.js → html-BokjxlLb.js} +1 -1
  84. package/dist/chunks/{line-CsTeuEcK.js → line-Bqh6atHH.js} +1 -1
  85. package/dist/chunks/{lrc-D6gjnGZ5.js → lrc-T5e1svZG.js} +1 -1
  86. package/dist/chunks/{markdown-BglUe9j8.js → markdown-BpWokN1s.js} +1 -1
  87. package/dist/chunks/{patch-C97Yl3jr.js → patch-BYVX5C9G.js} +1 -1
  88. package/dist/chunks/{worker-engine-B7_3qQVS.js → worker-engine-CtUAeI4G.js} +1 -1
  89. package/dist/index.js +1 -1
  90. package/dist/{src-DAkFn9SG.js → src-D6UlLiVN.js} +2 -2
  91. package/dist/{src-DAkFn9SG.js.map → src-D6UlLiVN.js.map} +1 -1
  92. package/package.json +9 -9
  93. package/dist/chunks/ApiTokensPage-DiRMgViD.js +0 -2
  94. package/dist/chunks/ApiTokensPage-DiRMgViD.js.map +0 -1
  95. package/dist/chunks/EntityContextRuntime-C9q95WDf.js +0 -1
  96. package/dist/chunks/SettingModuleDetail-I9CSJ-fh.js +0 -17
  97. package/dist/chunks/SettingModuleDetail-I9CSJ-fh.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"DictsPage-BGnamkWk.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":";;;;;;;IASMA,EAAa,CACjB,KAAM,YACN,KAAM,GACN,KAAM,CACJ,CAAC,OAAQ,CAAE,EAAG,WAAY,IAAK,QAAS,CAAC,EACzC,CACE,OACA,CACE,EAAG,8IACH,IAAK,QACP,CACF,CACF,CACF,EACAC,EAAW,KACL,GAAWC,EAAiBF,CAAU,C;;;;;;;ICftC,EAAa,CACjB,KAAM,SACN,KAAM,GACN,KAAM,CACJ,CACE,OACA,CACE,EAAG,mIACH,IAAK,QACP,CACF,EACA,CAAC,OAAQ,CAAE,EAAG,YAAa,IAAK,QAAS,CAAC,CAC5C,CACF,EACAA,EAAW,KACL,GAASE,EAAiBF,CAAU,C,OCrB1C,SAAgBG,GAAoD,EAAwB,GAAGC,EAAsD,CACjJ,OAAOC,IAAO,OAAY,KAAOD,EAAQ,KAAK,GAAUE,GAAQ,KAAOD,CAAE,GAAK,IAClF,CAEA,eAAsBE,GAAiD,EAAY,EAAmC,EAMtE,CAC5C,IAAMC,MAAsB,CAAEC,EAAU,aAAa,EAAGC,EAAK,gBAAgB,CAAG,EAChFF,EAAc,EAEd,IAAMF,EAAS,MAAMI,EAAK,KAAKL,EAAII,EAAU,MAAM,EAEnD,GADAD,EAAc,EACV,CAACF,GAAUA,EAAO,KAAOD,EAAI,MAAU,MAAM,cAAc,EAC/DK,EAAK,OAAOJ,CAAM,EAClB,IAAMK,EAAW,KAAK,IAAI,EAAI,IAC9B,KAAO,CAACD,EAAK,YAAYL,CAAE,GAAG,CAE1B,GADAG,EAAc,EACV,KAAK,IAAI,GAAKG,EAAU,MAAU,MAAM,UAAU,EACtD,MAAM,IAAI,QAAQ,GAAW,WAAWC,EAAS,EAAE,CAAC,CACxD,CAEA,OADAJ,EAAc,EACP,CAAE,OAAQ,WAAY,IAAG,CACpC,CCvBA,SAAgBK,GAAa,CAAE,OAAM,SAAQ,WAAU,SAKpD,CACC,IAAMC,MAAeC,EAASC,CAAI,EAClC,MAAO,kBAACC,GAAD,CACH,UAAU,kBACV,MAAOD,EAAK,GACZ,QAASE,EACT,QAASJ,EACT,MAAOE,EAAK,SAAW,WAAa,CAAE,QAAS,GAAK,EAAI,OACxD,MAAO,kBAAC,SAAD,CACH,KAAK,SACL,UAAU,0BACV,aAAY,GAAGA,EAAK,KAAK,GAAGA,EAAK,OACjC,eAAcE,EAAS,OAAS,OAChC,QAAS,GAAS,CAAEC,EAAM,gBAAgB,EAAGL,EAAO,CAAG,EACzD,SAAAE,EAAK,IAAa,GACpB,SAAU,kBAAC,OAAD,CAAM,UAAU,wBAAyB,SAAAA,EAAK,IAAW,GACnE,YAAa,kBAAC,OAAD,CAAM,UAAU,wBAAhB,UACT,kBAACI,EAAD,CAAc,MAAOJ,EAAK,SAAY,GACrCA,EAAK,SAAW,YAAc,kBAACK,EAAD,CAAK,KAAK,QAAQ,MAAM,OAAO,aAAO,EACnE,C,GACN,MAAOC,IAAU,OAAY,OAAY,kBAAC,OAAD,CAAM,QAAS,GAASH,EAAM,gBAAgB,EAAI,SAAAG,CAAY,EAC1G,EACL,C,4CCOA,SAASC,GAAuB,EAAwB,EAAmB,EAAmB,CAC1F,OAAOC,EAAkBlB,GAAQ,OAAQD,EAAIoB,CAAO,CACxD,CACA,SAAwBC,GAAY,CAChC,GAAM,CAAE,iBAAkBC,GAAc,EAElCC,EAAgBC,EAAY,IAAI,EAEhC,CAACC,EAAOC,GAAYC,EAAiB,CAAC,CAAC,EACvC,CAAE,OAAM,YAAU,UAAS,eAAa,eAAa,YAAU,mBAAiB,iBAAkBC,GAErG,CAAE,SAAU,CAAE,QAAS,EAAG,EAAG,QAASC,GAAS,KAAM,CAAC,EAEnDC,EAAcC,GAAe,CAC/B,QAASC,GAAgB,OAC7B,CAAC,EAGK,CAACC,EAAiBC,GAAsBC,GAAqB,MAAM,EACnE,CAACC,EAAoBC,GAAyBV,EAAsB,IAAI,EACxEW,EAAoBd,EAAO,CAAC,EAC5B,CAACe,EAAcC,GAAmBb,EAAwB,IAAI,EAC9D,CAACc,EAAWC,GAAgBf,EAAwB,IAAI,EAExD,CAACgB,EAAaC,GAAkBjB,EAAiB,IAAI,EACrD,CAAE,MAAOkB,GAAa,QAASC,GAAkBC,GAAa,eAAe,EAC7EC,EAAY,GAAkBC,EAG9B,CAACC,EAAgBC,IAAqBxB,EAAS,EAAK,EAEpDyB,EAAgBC,GAAY,CAC9B,OACA,YACA,GAAGvB,CACP,CAAC,EACKwB,EAAQF,EAAc,MAAM,OAAS,EAIrCG,EAAatB,IAAoB,KAAiC,OAA1B,OAAOA,CAAe,EAC9DuB,EAAkBD,IAAe,QAAa,OAAO,UAAUA,CAAU,GAAKA,EAAa,EAC3FE,EAAaD,EAAkB/B,EAAM,KAAM,GAAMiC,EAAE,KAAOH,CAAU,GAAK,KAAO,KAChFI,EAAe7D,GAA0ByD,EAAYnB,CAAkB,EACvEwB,GAAoBC,GAAcN,EAAYC,GAAmB,CAACC,GAAc,CAACE,CAAY,EAE7FG,EADehE,GAA0ByD,EAAYE,EAAYE,EAAcC,GAAkB,IAClF,IAAiBV,EAAiB,KAAOzB,EAAM,IAAM,MACpEsC,GAAevC,EAA2BsC,GAAc,EAAE,EAC1DE,GAAkBxC,EAA2BsC,GAAc,EAAE,EACnE,GAAa,QAAUA,GAAc,GACrCG,MAAgB,CAAE,GAAgB,QAAUH,GAAc,EAAI,EAAG,CAACA,GAAc,EAAE,CAAC,EACnFG,MAAgB,CACR7B,GAAsBH,IAAoB,OAAOG,EAAmB,EAAE,GAAGC,EAAsB,IAAI,CAC3G,EAAG,CAACD,EAAoBH,CAAe,CAAC,EACxC,IAAMiC,MAAgC,CAAE,EAAkB,UAAW7B,EAAsB,IAAI,EAAGH,EAAmB,IAAI,CAAG,EAC5H+B,MAAgB,CACRhC,IAAoB,OAEpB,CAACuB,GAAmB,CAACC,GAAc,CAACE,GAAgBC,GAAkB,UACtE1B,EAAmB,IAAI,CAC/B,EAAG,CAACD,EAAiBuB,EAAiBC,EAAYE,EAAcC,GAAkB,QAAS1B,CAAkB,CAAC,EAC9G,IAAMiC,EAAaC,GAAiBN,GAAc,EAAE,EAC9CO,EAAQC,MAAcH,EAAW,MAAQ,CAAC,EAAG,CAACA,EAAW,IAAI,CAAC,EAE9DI,EAAa3C,GAAgC,CAAE,SAAU4C,GAAmB,QAAS3C,GAAS,MAAMiC,GAAc,EAAE,CAAE,CAAC,EACvHW,GAAmBC,GAAY,EAC/BC,EAAYC,GAA6C,CAC3D,WAAY,KACZ,KAAMC,GAAiBJ,GAAkB,CAAE,OAAQK,EAAa,OAAO,MAAM,MAAM,KAAM,OAAQA,EAAa,OAAO,MAAM,MAAM,IAAK,CAAC,EACvI,UAAWjB,GACX,SAAU,CAAE,OAAQ,SAAU,EAC9B,SAAU,IAAS,CAAE,KAAMlD,EAAK,KAAM,KAAMA,EAAK,KAAM,YAAaA,EAAK,YAAa,OAAQA,EAAK,MAAO,GAC1G,YAAa,EAAQ,CAAE,cAAe,CAAE,GAAGoE,EAAQ,YAAaA,EAAO,aAAe,OAAW,GAAIC,EAAU,CAAE,YAAaD,EAAO,YAAc,CAAC,EAAI,CAAC,aAAa,CAAE,EAAI,CAAC,CAAG,EACpL,CAAC,EACKE,EAA2BP,GAAY,EACvCQ,EAAqBC,GAAe,EACpCC,EAAqBC,GAAkB,EACvCC,GAAqBC,GAAkB,EACvCC,GAA2BD,GAAkB,EAC7CE,GAAqBC,GAAkB,EACvCC,GAAuBV,EAAyB,UAAaA,EAAyB,WAAW,IAAM,KAAQ,KAG/GW,EAAYhB,GAAmH,CACjI,WAAY,MACZ,KAAM,CACF,aAAc,CAAE,KAAI,aACXd,GACD+B,GAAY,YAAY,EACrB7F,IAAO,OACRoF,EAAmB,YAAY,CAAE,OAAQ,CAAE,GAAItB,EAAa,EAAG,EAAG,KAAMgB,EAAa,WAAW,MAAM,MAAM,KAAK,MAAMC,CAAM,CAAE,CAAC,EAChIO,GAAmB,YAAY,CAAE,OAAQ,CAAE,GAAIxB,EAAa,GAAI,OAAQ9D,CAAG,EAAG,KAAM8E,EAAa,WAAW,MAAM,MAAM,KAAK,MAAMC,CAAM,CAAE,CAAC,GAEtJ,UAAWK,EAAmB,WAAaE,GAAmB,SAClE,EACA,UAAWpE,GACX,SAAU,CAAE,OAAQ,UAAW,KAAM,CAAE,EACvC,SAAW,IAAU,CAAE,MAAO4E,EAAK,MAAO,MAAOA,EAAK,MAAO,KAAMA,EAAK,KAAM,OAAQA,EAAK,OAAQ,OAAQA,EAAK,QAAU,MAAU,GACpI,YAAa,EAAQ,CAAE,aAAc,CACjC,IAAIC,EACEC,GAAezE,EAAc,SAAS,SAAS,GAAKoB,EAAA,CAAa,KAAK,EAC5E,GAAIqD,GAAeA,IAAgB,KAC/B,GAAI,CACA,EAAW,KAAK,MAAMA,CAAW,CACrC,MACM,CACFC,GAAM,MAAM,sBAAsB,EAClCJ,GAAY,CAChB,CAGJ,IAAMK,EAAU,CAAE,GAAGnB,EAAQ,SAAUxC,GAAgB,OAAW,MAAOE,GAAa,OAAW,OAAQsC,EAAO,QAAU,OAAW,UAAS,EAC9I,OAAOC,EACDF,EAAa,WAAW,MAAM,MAAM,KAAK,MAAM,CAAE,GAAGoB,EAAS,YAAa,CAAC,GAAI3D,GAAgB,KAAO,CAAC,UAAU,EAAI,CAAC,EAAI,GAAKE,EAAwB,CAAC,EAAb,CAAC,OAAO,EAAS,GAAKsC,EAAO,OAAsB,CAAC,EAAd,CAAC,QAAQ,EAAS,GAAIgB,IAAa,OAAY,CAAC,UAAU,EAAI,CAAC,CAAE,CAAE,CAAC,EACrPjB,EAAa,WAAW,MAAM,MAAM,KAAK,MAAMoB,CAAO,CAChE,EACA,WAAY,EAChB,CAAC,EACKC,EAAcP,EAAU,QACxBQ,GAAgB5E,EAAO,EAAK,EAClC,GAAc,QAAUmD,EAAU,SAAWiB,EAAU,SAAWjB,EAAU,YAAY,SAAWiB,EAAU,YAAY,SAClHnB,GAAiB,WAAaW,EAAmB,WAAaE,GAAmB,WAAaJ,EAAmB,WAAaO,GAAmB,WACjJR,EAAyB,WAAaO,GAAyB,UACtEa,GAA6B,CAAE,SAAU,QAAS,MAAO,KAAM,WAAY,cAAe,gBAAe,MAAO1B,EAC5G,KAAMG,EAAa,KAAM,OAAQA,EAAa,OAAQ,OAAQA,EAAa,OAAO,MAAM,MAAM,KAAM,OAAQA,EAAa,OAAO,MAAM,MAAM,KAC5I,OAAQ,CAAC,KAAM,OAAQ,OAAQ,cAAe,SAAU,YAAa,WAAW,EAAG,QAAShD,EAC5F,OAAQ,GAAMoD,EAAmB,YAAY,CAAClF,CAAE,CAAC,EAAG,UAAWkE,EAC/D,WAAYoC,EAAc,kBAAkB,EAAI,CAAC,CAAE,KAAM,8BAA+B,YAAa,cAAe,KAAM,OAAQ,YAAa,CAAE,KAAM,SAAU,WAAY,CAAE,GAAI,CAAE,KAAM,UAAW,QAAS,CAAE,CAAE,EAAG,SAAU,CAAC,IAAI,EAAG,qBAAsB,EAAM,EAChQ,MAAO,GAASC,GAAS,CAAE,GAAIC,GAAS,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAMC,CAAK,EAAG,QAAS,MAAO,EAAO,IAAc,CACtH,IAAMzG,EAAMyG,EAAyB,GAC/BC,EAAW,EAAEpE,EAAkB,QACrC,OAAOpC,GAAuBF,EAAII,EAAW,CACzC,MAAO,EAAU,IAAWuG,GAAI7B,EAAa,OAAQ,CAAE,OAAQ,CAAE,GAAI8B,CAAS,CAAE,EAAG,CAAE,SAAQ,OAAQ,EAAK,CAAC,EAC3G,oBAAuB,CACnB,GAAItE,EAAkB,UAAYoE,EAAU,MAAU,MAAM,SAAS,EACrE,GAAIN,GAAc,QAAS,MAAU,MAAM,sBAAsB,CACrE,EACA,OAAQ,GAAU,CAAE/D,EAAsBpC,CAAM,EAAGiC,EAAmB,OAAOjC,EAAO,EAAE,CAAC,CAAG,EAC1F,YAAa,GAAY8D,GAAa,UAAY6C,GAAY5C,GAAgB,UAAY4C,CAC9F,CAAC,CACL,CAAE,CAAC,EAAI,CAAC,CAAE,CAAC,EACnBP,GAA6B,CAAE,SAAU,aAAc,MAAO,MAAO,WAAY,cAAe,gBAAe,MAAOT,EAClH,YAAa,CAAE,KAAM,mBAAoB,OAAQ,mBAAoB,OAAQ,mBAAoB,OAAQ,kBAAmB,EAC5H,KAAMd,EAAa,MAAO,OAAQA,EAAa,WAAY,OAAQA,EAAa,WAAW,MAAM,MAAM,KAAM,OAAQA,EAAa,WAAW,MAAM,MAAM,KACzJ,OAAQ,CAAC,KAAM,SAAU,WAAY,QAAS,QAAS,OAAQ,SAAU,QAAS,SAAU,WAAY,YAAa,WAAW,EAChI,MAAOhB,GAAc,GAAI,SAAU,CAACA,EAAc,QAAS,CAAE,GAAGS,EAAW,eAAgB,EAC3F,OAAQ,IAAW,CAAE,GAAIT,GAAc,GAAI,GAAI+C,IAAW,OAAY,CAAC,EAAI,CAAE,QAAO,CAAG,GACvF,gBAAmB,CAAE,GAAI,CAAC/C,GAAgBC,GAAa,UAAYD,EAAa,GAAI,MAAU,MAAM,aAAa,CAAG,EACpH,OAAQ,GAAU2B,GAAmB,YAAY,CAAE,OAAQ,CAAE,GAAI3B,EAAc,GAAI,QAAO,CAAE,CAAC,EAC7F,aAAc,EAAQ,CAAE,YAAa,EAAM,CAACgD,GAAU,aAAc/B,IAAQvC,EAAgBuC,EAAO,UAAsB,IAAI,GAAO,CAAC+B,GAAU,UAAW/B,IAAQrC,EAAaqC,EAAO,OAAmB,IAAI,GAAO,CAAC+B,GAAU,aAAc/B,IAAQnC,EAAemC,EAAO,SAAW,KAAK,UAAUA,EAAO,SAAU,KAAM,CAAC,EAAI,IAAI,CAAG,CAAE,CAAC,EAC/Ud,MAAgB,CACPb,EAAc,MAEnB1B,EAAS0B,EAAc,KAAK,IAAI,CACpC,EAAG,CAACA,EAAc,IAAI,CAAC,EAEvB,IAAM2D,GAAwBvF,EAAsB,IAAI,EAExDyC,MAAgB,CACPkC,IAEL3D,EAAgB2D,EAAY,UAAY,IAAI,EAC5CzD,EAAayD,EAAY,OAAS,IAAI,EACtCvD,EAAeuD,EAAY,SAAW,KAAK,UAAUA,EAAY,SAAU,KAAM,CAAC,EAAI,IAAI,EAC9F,EAAG,CAACA,CAAW,CAAC,EAChB,IAAMa,GAAwB,GAAqB,CAC/CC,EAAQC,CAAQ,CACpB,EACMC,GAA4B,GAAyB,CACvDF,EAAQ,CAAC,EACTG,GAAYC,CAAY,CAC5B,EACMC,GAAc,GAAe,CAC3BxD,GAAc,KAAOnD,EAAK,KAC9B,EAAkB,UAClB0B,EAAsB,IAAI,EAC1BH,EAAmB,OAAOvB,EAAK,EAAE,CAAC,EAClC4D,EAAW,YAAY,EAC3B,EACMgD,EAAgBjD,MAAc,CAChC,GAAM,CAAE,QAASkD,EAAa,OAAQC,GAAqBlD,EAAW,gBAQtE,OAPaF,EAAM,OAAQ,GAGvB,EAFImD,GAAe,CAAC1B,EAAK,MAAM,SAAS0B,CAAW,GAAK,CAAC1B,EAAK,MAAM,SAAS0B,CAAW,GAEpFC,GAAoB3B,EAAK,SAAW2B,EAIrC,CACX,EAAG,CAACpD,EAAOE,EAAW,eAAe,CAAC,EAEhCmD,GAAYpD,MAAc,CAC5B,IAAMqD,EAAc,IAAI,IAAIJ,EAAc,IAAK,GAAMK,EAAE,EAAE,CAAC,EACpDC,EAAiB,GAA2BN,EAC7C,OAAQ,GAAMO,EAAE,WAAa9H,CAAE,CAAC,CAChC,IAAK,GAAM,CACZ,IAAM+H,EAAgBF,EAAcC,EAAE,EAAE,EACxC,OAAOC,EAAc,OAAS,EAAI,CAAE,GAAGD,EAAG,SAAUC,CAAc,EAAID,CAC1E,CAAC,EACD,OAAOP,EACF,OAAQ,GAAM,CAACK,EAAE,UAAY,CAACD,EAAY,IAAIC,EAAE,QAAQ,CAAC,CAAC,CAC1D,IAAK,GAAS,CACf,IAAMI,EAAWH,EAAc/B,EAAK,EAAE,EACtC,OAAOkC,EAAS,OAAS,EAAI,CAAE,GAAGlC,EAAM,UAAS,EAAIA,CACzD,CAAC,CACL,EAAG,CAACyB,CAAa,CAAC,EACZ,CAAE,mBAAiB,sBAAoB,cAAY,iBAAe,mBAAiB,yBAA0BU,GAAiBP,EAAS,EAC7IzD,MAAgB,CACPH,GAAgBK,EAAW,OAAS,QAErC4C,GAAsB,UAAYjD,EAAa,KAEnD,GAAsB,QAAUA,EAAa,GAC7CoE,GAAmBC,EAAU,EACjC,EAAG,CAACrE,EAAcK,EAAW,KAAMgE,GAAYD,EAAkB,CAAC,EAElE,IAAME,GAAoB9D,MAAc,CACpC,GAAI,CAAC6B,EACD,sBAAO,IAAI,IACf,IAAMkC,kBAAS,IAAI,IAAY,CAAClC,EAAY,EAAE,CAAC,EACzCmC,EAAkB,GAAe,CACnCjE,EAAM,OAAQ,GAAMuD,EAAE,WAAa5H,CAAE,CAAC,CAAC,QAAS,GAAU,CACtDqI,EAAO,IAAIE,EAAM,EAAE,EACnBD,EAAeC,EAAM,EAAE,CAC3B,CAAC,CACL,EAEA,OADAD,EAAenC,EAAY,EAAE,EACtBkC,CACX,EAAG,CAAClC,EAAa9B,CAAK,CAAC,EAEjBmE,GAAyBlE,MAAc,CAQzC,IAAMmE,EAAa,GAAqCpE,EACnD,OAAQ,IAAOuD,EAAE,UAAY,QAAUc,CAAQ,CAAC,CAChD,IAAK,IAAU,CAChB,MAAO5C,EAAK,MACZ,MAAOA,EAAK,GACZ,IAAK,OAAOA,EAAK,EAAE,EACnB,SAAUsC,GAAkB,IAAItC,EAAK,EAAE,EACvC,SAAU2C,EAAU3C,EAAK,EAAE,CAC/B,EAAE,EACF,MAAO,CACH,CAAE,MAAO,SAAU,MAAO,EAAG,IAAK,GAAI,EACtC,GAAG2C,EAAU,IAAI,CACrB,CACJ,EAAG,CAACpE,EAAO+D,EAAiB,CAAC,EAEvBO,GAAgB,GAAc,CAChChE,EAAU,SAASiE,CAAG,CAC1B,EACMC,GAAmB,KAAO,IAAe,CAC3C,MAAM3D,EAAmB,YAAY,CAAClF,CAAE,CAAC,EACzCiG,GAAM,QAAQ,MAAM,EAChBhE,IAAoB,OAAOjC,CAAE,GAC7BkE,EAAwB,CAEhC,EAEM4E,GAAmB,KAAO,IAAe,CACtChF,GAEL,MAAM2B,GAAmB,YAAY,CAAE,OAAQ,CAAE,GAAI3B,EAAa,GAAI,OAAQ9D,CAAG,CAAE,CAAC,CACxF,EACM+I,IAAkB,EAA0B,OAAS,CACvDvG,EAAgBkG,CAAQ,EACxBhG,EAAa,IAAI,EACjBE,EAAe,IAAI,EACnBgD,EAAU,WAAW,CACzB,EACMoD,GAAuB,GAAkBD,GAAeH,EAAI,EAAE,EAC9DK,GAAgB,GAAkB,CAC/BnF,IAELtB,EAAgBoG,EAAI,UAAY,IAAI,EACpClG,EAAakG,EAAI,OAAS,IAAI,EAC9BhG,EAAegG,EAAI,SAAW,KAAK,UAAUA,EAAI,SAAU,KAAM,CAAC,EAAI,IAAI,EAC1EhD,EAAU,SAASgD,CAAG,EAC1B,EACMM,GAAaC,GAA0B,CACzC,QAAS,EAAM,IACNrF,EAEE0B,GAAyB,YAAY,CAAE,OAAQ,CAAE,GAAI1B,EAAa,GAAI,OAAQgC,EAAK,EAAG,EAAG,KAAM,CAAE,OAAQ1E,EAAU,UAAY,UAAW,CAAE,CAAC,EADzI,QAAQ,QAAQ,EAG/B,eAAiB,IAAU,CAAE,OAAQ,GAAM,MAAO,WAAW0E,EAAK,MAAM,IAAK,OAAQ,MAAO,GAC5F,SAAU,CAAChC,GAAgB,CAACwC,EAAc,kBAAkB,CAChE,CAAC,EACK8C,GAAyB,MAAO,EAAY,IAAsC,EAChFC,IAAc,YAKT,MAJmBC,GAAmB,CACvC,MAAO,UAAU3I,EAAK,KAAK,IAC3B,OAAQ,MACZ,CAAC,KAIL,MAAMsE,EAAyB,YAAY,CAAE,GAAItE,EAAK,GAAI,OAAQ,CAAE,OAAQ0I,CAAU,CAAE,CAAC,EACzFpD,GAAM,QAAQoD,IAAc,UAAY,MAAQ,KAAK,EACzD,EAiBME,GAAc,kBAACC,GAAD,CAAc,MAAM,OAAO,YAAa,kBAACC,GAAD,CAAO,QAAS,EAAhB,UACtD,kBAACC,GAAD,CAAc,OAAO,eAAe,MAAO5H,CAAa,GACxD,kBAAC6H,GAAD,CAAoB,MAAO,CACrB,CAAE,IAAK,UAAW,MAAO,KAAM,KAAM,kBAACC,GAAD,CAAW,KAAM,EAAI,GAAG,YAAe,KAAKxG,EAAc,QAAQ,CAAE,EACzG,CAAE,IAAK,SAAU,MAAO,OAAQ,KAAM,kBAACyG,GAAD,CAAM,KAAM,EAAI,GAAG,OAAQ,CAACvD,EAAc,oBAAoB,EAAG,QAAS3B,EAAU,UAAW,CACzI,CAAG,EACA,C,GAAG,OAAQ,CACd,MAAOmF,GAAY,QACnB,SAAUC,GAAS,SAAS,EAC5B,YAAa,QACb,aAAcC,EAClB,EAAG,QAAS5G,EAAc,UAAW,OAAQ,kBAAC6G,GAAD,CAAY,KAAK,QAAQ,uBAA2B,QAAO,YAAaC,EAAgB,YAAU,aAAc,CAAC,GAAI,GAAI,GAAI,GAAG,EAAG,mBAAgB,aAAU,aAAclD,GAAsB,iBAAkBG,EAA0B,GAAG,WAC1R,SAAA1F,EAAM,OAAS,EAAI,kBAACb,GAAU,MAAX,CAAiB,UAAU,wBAAwB,MAAOkD,GAAc,GAAI,SAAU,GACvG,SAAArC,EAAM,IA7Ba,GAAe,CACvC,IAAMZ,EAASiD,GAAc,KAAOnD,EAAK,GACzC,MAAQ,kBAACH,GAAD,CAAkC,OAAc,SAAQ,SAAU8G,GAAY,MAAO,kBAACqC,GAAD,CAAoB,MAAO,CAC5G,CAAE,IAAK,OAAQ,MAAO,KAAM,KAAM,kBAACQ,GAAD,CAAQ,KAAM,EAAI,GAAG,OAAQ,CAAC7D,EAAc,oBAAoB,EAAG,YAAe,KAAKqC,GAAahI,CAAI,CAAE,EAC5I,CACI,IAAK,SAAU,MAAO,KAAM,KAAM,kBAACyJ,GAAD,CAAQ,KAAM,EAAI,GAAG,OAAQ,GAAM,OAAQ,CAAC9D,EAAc,oBAAoB,EAChH,YAAe,CACX+D,GAAc,CACV,MAAO,WACP,QAAS,kBACT,SAAYxB,GAAiBlI,EAAK,EAAE,CACxC,CAAC,CACL,CACJ,CACJ,CAAG,EAAG,EAZaA,EAAK,EAYlB,CAClB,CAcqC,CACd,GAAI,kBAAC,MAAD,CAAK,UAAU,wBAAwB,eAAS,EACzD,GACZ2J,GAAkBC,GAAiC,CACrD,YAAa,CAAE,KAAM,mBAAoB,OAAQ,kBAAmB,EACpE,KAAMtB,GACN,OAAS,GAAQH,GAAiBF,EAAI,EAAE,EACxC,MAAO,YACP,MAAQ,GAAQ,CACZ,CACI,IAAK,QACL,MAAO,KACP,OAAQ,CAACtC,EAAc,kBAAkB,EACzC,YAAe0C,GAAoBJ,CAAG,CAC1C,CACJ,EACA,MAAO,IACP,kBAAmB,CAAC,QAAS,OAAQ,QAAQ,CACjD,CAAC,EACK4B,GAAuC,CACzC,CAAE,MAAO,KAAM,UAAW,QAAS,MAAO,IAAK,QAAS,EAAW,IAAqBvK,EAAO,MAAQ,kBAACe,EAAD,CAAK,MAAOgC,EAAS/C,EAAO,KAAK,EAAG,KAAK,QAAS,SAAAwK,CAAO,GAAIC,EAAeD,CAAC,CACpL,EACA,CAAE,MAAO,KAAM,UAAW,QAAS,MAAO,IAAK,OAAQC,CAAe,EACtE,CAAE,MAAO,KAAM,UAAW,OAAQ,MAAO,GAAI,MAAO,QAAS,EAC7D,CAAE,MAAO,KAAM,UAAW,SAAU,SAAU,IAAK,OAAQA,CAAe,EAC1EC,GACAzB,GAAW,OAAO,EAClBoB,EACJ,EACMM,OAA+BzC,GAAW,OAAS,EAAK,kBAAC0C,GAAD,CAAQ,KAAK,UAAU,KAAsBC,EAAhBC,GAAiBC,GAA8BC,GAA/B,CAAgB,KAAM,EAAI,CAA8B,EAAG,QAASC,GAAiB,SAAU,CAACpH,EACxM,SAAAiH,GAAgB,OAAS,MACpB,GAAK,KACPI,GAAc,kBAAAC,GAAA,WAClB,kBAACC,EAAmB,OAApB,UACGvH,EAAgB,kBAAAsH,GAAA,WACb,kBAAC,MAAD,CAAK,UAAU,oBAAf,UACE,kBAACE,GAAD,CAAU,KAAM,EAAI,GACpB,kBAAC,OAAD,CAAM,MAAOxH,EAAa,KAAO,SAAAA,EAAa,IAAW,EACtD,C,GACL,kBAAC9C,EAAD,CAAK,KAAK,QAAQ,MAAM,OAAQ,SAAA8C,EAAa,IAAU,GACvD,kBAACyH,GAAD,CAAQ,KAAK,QAAQ,QAASzH,EAAa,SAAW,UAAW,QAAS6B,KAAyB7B,EAAa,GAAI,SAAU,CAACwC,EAAc,oBAAoB,EAAG,SAAW,GAAqB,KAAK8C,GAAuBtF,EAAc0H,EAAU,UAAY,UAAU,CAAG,EACjR,IAAM,kBAAC,OAAD,CAAM,UAAU,0BAA0B,gBAAW,EACtC,GAC3B,kBAACH,EAAmB,KAApB,UAEE,kBAACI,GAAD,CAAmB,aAAcC,GAAiB,CAC9C,QAAW,kBAACC,GAAD,CAAc,YAAY,QAAQ,GAAIpH,EAAW,YAAY,SAAS,EAAG,MAAO,IAAK,SAAU,CAACT,CAAc,GACzH,QAAW,kBAAC8H,GAAD,CAAc,MAAO/I,GAAa,GAAI0B,EAAW,KAAK,QAAQ,EAAG,SAAU,CAACT,CAAc,GACrG,SAAWS,EAAW,aACtB,QAAUA,EAAW,YACrB,OAAS,kBAACsH,GAAD,CAAc,WAAW,mBAAmB,YAAe9C,GAAe,EAAG,SAAU,CAACjF,CAAc,GAC/G,QAAU8G,GAAuB,EACjC,YAAa,QACb,YAAa,OACjB,CAAC,EAAG,YAAS,QAASJ,GAAa,WAAY9C,GAAW,OAAO,KAAK,QAASvD,EAAW,WAAY,UAAWL,MAAqB,KAAKK,EAAW,QAAQ,EAAI,OAAW,eAAgBA,EAAW,WAAY,WAAY,GAAO,KAAK,QAAQ,MAAOL,EAAe,OAAS,QAAS,mBAAmB,WAA4B,mBAAuC,uBAAsB,EACjX,EACzB,IACF,MAAQ,kBAAC,MAAD,CAAK,UAAU,yCAAf,UACN,kBAACuH,EAAD,CAAoB,OAAQ9B,GAAY,OAAQ4B,GAAY,YAAa,IAAK,QAAS,IAAK,QAAS,IAAK,WAAW,QAAQ,WAAY,CAAC,CAACrH,EAAc,OAAQI,EAAyB,mBAAoBf,GAAmB,MAAO,CAAE,KAAM,EAAG,SAAU,QAAS,CAAG,GAGzQ,kBAAC2I,GAAD,CAAe,MAAOnH,EAAW,MAAO,IAAxC,UACE,kBAACoH,EAAK,MAAN,CAAY,MAAM,OAAO,MAAM,OAAO,YAAY,UAAU,MAAO,CAAE,MAAO,MAAO,EAAG,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,SAAU,CAAC,CAAG,GACvI,kBAACA,EAAK,MAAN,CAAY,MAAM,OAAO,MAAM,OAAO,YAAY,WAAW,MAAO,CAAE,MAAO,MAAO,EAAG,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,SAAU,CAAC,EAAG,SAAW,GAAU,CACzJ,IAAM1D,EAASvD,EAAa,OAAO,MAAM,MAAM,KAAK,UAAU,CAAE,KAAMkH,CAAM,CAAC,EAE7E,OADc3D,EAAO,QAAU,OAAYA,EAAO,MAAM,OAAO,KAAK,GAAQvC,EAAK,KAAK,KAAO,MAAM,IACrF,SAAW,EAC7B,CAAG,GACH,kBAACiG,EAAK,MAAN,CAAY,MAAM,cAAc,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAE,MAAO,MAAO,CAAG,GACzF,kBAACA,EAAK,OAAN,CAAa,MAAM,SAAS,MAAM,KAAK,MAAO,CAAE,MAAO,MAAO,EAAG,WAAYjJ,EAAe,YAAY,OAAQ,EACnG,C,GAGf,kBAACgJ,GAAD,CAAe,MAAOlG,EAAW,MAAO,IAAxC,UACE,kBAACqG,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,MAAN,CAAY,MAAM,QAAQ,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAE,MAAO,MAAO,EAAG,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,CAAG,EAC/H,GACL,kBAACG,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,MAAN,CAAY,MAAM,QAAQ,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAE,MAAO,MAAO,EAAG,MAAO,CAAC,CAAE,SAAU,GAAM,QAAS,OAAQ,CAAC,CAAG,EAC/H,EACF,C,GAEL,kBAACE,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,YAAN,CAAkB,MAAM,OAAO,MAAM,KAAK,YAAY,QAAQ,IAAK,EAAG,MAAO,CAAE,MAAO,MAAO,CAAG,EAC7F,GACL,kBAACG,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,OAAN,CAAa,MAAM,SAAS,MAAM,KAAK,MAAO,CAAE,MAAO,MAAO,EAAG,WAAYjJ,EAAe,YAAY,OAAQ,EAC7G,EACF,C,GAEL,kBAACmJ,EAAD,CAAK,OAAQ,GAAb,UACE,kBAACC,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,KAAN,CAAW,MAAO,CAAE,KAAM,IAAK,EAC7B,2BAACI,EAAD,CAAY,SAAU3D,GAAwB,MAAOjG,GAAgB,EAAG,SAAW,GAAQC,EAAgB4J,IAAQ,EAAI,KAAQA,CAAc,EAAG,MAAO,CAAE,MAAO,MAAO,EAAG,kBAAe,YAAU,EAC1L,EACR,GACL,kBAACF,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,KAAN,CAAW,MAAO,CAAE,KAAM,IAAK,EACrB,eACV,IAAMM,EAAa,CAAC,QAAS,OAAQ,OAAQ,QAAS,OAAQ,SAAU,aAAc,cAAe,OAAQ,SAAU,OAAQ,SAAU,MAAO,OAAQ,SAAU,SAAU,OAAO,EAC7KC,EAAuC,CACzC,MAAO,KAAM,KAAM,KAAM,KAAM,KAAM,MAAO,KAAM,KAAM,KACxD,OAAQ,KAAM,aAAc,KAAM,cAAe,KAAM,KAAM,KAC7D,OAAQ,KAAM,KAAM,KAAM,OAAQ,KAAM,IAAK,KAAM,KAAM,KACzD,OAAQ,MAAO,OAAQ,KAAM,MAAO,IACxC,EACA,MAAQ,kBAACC,GAAD,CAAQ,MAAO9J,GAAa,OAAW,SAAW,GAAQC,EAAc0J,GAAkB,IAAI,EAAG,YAAY,MAAM,aAAU,YAAe1J,EAAa,IAAI,EAAG,MAAO,CAAE,MAAO,MAAO,EAAG,mBAAqB,GAG5M,kBAAC1B,EAAD,CAAK,MAAOgC,EAASwJ,EAAO,KAAe,EAAG,KAAK,QAAQ,MAAO,CAAE,OAAQ,OAAQ,EAClF,SAAAA,EAAO,KACL,GAAI,kBAAmB,CAAE,WAAU,QAAO,UAAS,QAAO,WAAa,kBAAC,SAAD,CAAQ,KAAK,SAAkB,UAAS,MAAO,CACzH,GAAGC,EACH,QAAS,OACT,WAAY,SACZ,IAAK,EACL,QAAS,WACT,OAAQ,UACR,MAAO,OACP,OAAQ,OACR,WAAYC,EAAW,8CAAgD,cACvE,UAAW,MACf,EACI,2BAAC1L,EAAD,CAAK,MAAOgC,EAASgJ,CAAe,EAAG,KAAK,QAAS,SAAAW,CAAqB,EACpE,GACT,SAAAN,EAAW,IAAK,GAAO,kBAACE,GAAO,OAAR,CAAuB,MAAOzE,EAAG,MAAOwE,EAAaxE,IAAMA,EAC/E,2BAAC9G,EAAD,CAAK,MAAOgC,EAAS8E,CAAC,EAAG,KAAK,QAAS,SAAAwE,EAAaxE,IAAMA,CAAO,EACpD,EAF2BA,CAE3B,CAAE,CACb,EAClB,GAAG,CACY,EACR,EACF,C,GAEL,kBAACmE,EAAD,CAAK,OAAQ,GACX,2BAACC,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,MAAN,CAAY,MAAM,SAAS,MAAM,KAAK,YAAY,QAAQ,MAAO,CAAE,MAAO,MAAO,CAAG,EACjF,EACF,GAEL,kBAACE,EAAD,CAAK,OAAQ,GACX,2BAACC,EAAD,CAAK,KAAM,GACT,2BAACH,EAAK,KAAN,CAAW,MAAO,CAAE,KAAM,KAAM,EAC9B,2BAACa,EAAD,CAA8B,IAAKrL,EAAe,MAAOoB,EAAa,OAAQ,IAAK,MAAM,MAAO,EAA/EA,CAA+E,CACvF,EACR,EACF,EACQ,C,EACZ,C,EACT,C,6IAveM,GAAsC,CAAE,QAAS,GAAI,OAAQ,MAAU,C","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-Bio-ig-l.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-CbzeMNXR.js.map
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
@@ -1 +1 @@
1
- {"version":3,"file":"EntityContextRuntime-CbzeMNXR.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"]}
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-CfQx7jWq.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-sMPAV2hd.js.map
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-sMPAV2hd.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"]}
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"]}