# Migration Guide: Old List Pages → Unified Action Pattern ## Before (Manual Pattern) ```tsx const getCurrentPermissions = useCurrentPermissions(); let toolBarRender = (action: any) => { return getCurrentPermissions({ export: , }); }; let tableRender = (item: any, action: any) => { let permissions = getCurrentPermissions({ view: , update: , }); let permissionsSpace = getCurrentPermissions({ delete: { key: '1', label: }, }); let Others = ( ); return [...permissions, ...[Others]]; }; toolBarRender={(action) => [toolBarRender(action)]} // ... MyColumns.Option({ render: (_, item, index, action) => ( <>{tableRender(item, action)} ), }) ``` ## After (Unified Pattern) ```tsx import { MyTableActions, MyToolBarActions } from '@/common'; toolBarRender={(action) => [ , }} />, ]} MyColumns.Option({ render: (_, item, index, action) => ( , update: , delete: , }} maxVisible={2} /> ), }) ``` ## Steps 1. Remove `useCurrentPermissions` import if it is no longer needed elsewhere. 2. Remove `toolBarRender` local function; replace `toolBarRender` prop with `MyToolBarActions`. 3. Remove `tableRender` local function and any `permissionsSpace` / `Others` / `Dropdown` boilerplate. 4. Replace `MyColumns.Option` render body with `MyTableActions`. 5. Tune `maxVisible` based on design needs (default `3`). ## Special Case: Link in Column Render If a column (e.g., "名称") renders a clickable `AssetInfo` link that should also be permission-controlled: ```tsx const getCurrentPermissions = useCurrentPermissions(); const hasInfo = getCurrentPermissions({ info: true }).length > 0; { title: '名称', dataIndex: 'name', render: (_, item: any) => { if (!hasInfo) return item?.name; return ; }, } ``` Note: `useCurrentPermissions` may still be imported for this use case.