refactor(frontend): split 7 oversized pages into feature co-location
Per guide ch.7 page split pattern (skeleton orchestrates, private components live in features/<domain>/): - InstancePage 1716->328, UsersPage 1309->240, TicketsPage 1076->195, TicketDetailPage 911->287, QueriesPage 883->479, LdapConfigPage 860->393, WorkflowPage 852->194 - new feature modules: datasource/ rbac/ ticket/ query/ system/ldap/ governance/workflow/ (components + hooks + types + utils) - stable keys replace index keys in dynamic lists; polling intervals and toast call sites preserved 1:1 (verified by agents) - filter/pagination state moved to URL query via new useQueryState hook (Instance/Users/Tickets/AuditLogs pages): refresh/share/back-button restore state; composite updates applied atomically - permission pure functions extracted to lib/permissions.ts (used by useAuth + useLogin); page-size audit: 0 pages over 700-line budget
This commit is contained in:
1 parent
ac563d1c5e
commit
ac498c7ba2
92 files changed
+8224
-6146
No files matched your search
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 批量操作条:选中计数、全选/取消全选切换、批量删除按钮。
|
||||
* 必需 props:selectedCount/total 计数、canDelete 权限、onSelectAll/onBatchDelete 回调;deleting 可选(默认 false)。
|
||||
* 已知限制:仅应在 selectedCount > 0 时由父级渲染,空态展示逻辑不在组件内。
|
||||
*/
|
||||
import { Trash2, Loader2 } from 'lucide-react';
|
||||
|
||||
interface InstanceBatchBarProps {
|
||||
selectedCount: number;
|
||||
total: number;
|
||||
canDelete: boolean;
|
||||
deleting: boolean;
|
||||
onSelectAll: () => void;
|
||||
onBatchDelete: () => void;
|
||||
}
|
||||
|
||||
export function InstanceBatchBar({
|
||||
selectedCount,
|
||||
total,
|
||||
canDelete,
|
||||
deleting,
|
||||
onSelectAll,
|
||||
onBatchDelete,
|
||||
}: InstanceBatchBarProps) {
|
||||
return (
|
||||
<div className="flex items-center justify-between p-3 bg-blue-500/5 border border-blue-500/20 rounded-lg">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-sm text-blue-400 font-medium">已选择 {selectedCount} 个实例</span>
|
||||
<button
|
||||
onClick={onSelectAll}
|
||||
className="text-xs text-[var(--dg-text-muted)] hover:text-blue-400 transition-colors"
|
||||
>
|
||||
{selectedCount === total ? '取消全选' : '全选'}
|
||||
</button>
|
||||
</div>
|
||||
{canDelete && (
|
||||
<button
|
||||
onClick={onBatchDelete}
|
||||
disabled={deleting}
|
||||
className="flex items-center gap-1.5 px-3 py-1.5 text-xs font-medium bg-red-500/15 text-red-400 border border-red-500/30 rounded-md hover:bg-red-500/25 transition-all disabled:opacity-50"
|
||||
>
|
||||
{deleting ? <Loader2 className="w-3 h-3 animate-spin" /> : <Trash2 className="w-3 h-3" />}
|
||||
{deleting ? '删除中...' : '批量删除'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user