feat(agents): implement grid/list view toggle and enhance filters
- Added grid and list view modes to AgentTypeList with user preference management. - Enhanced filtering with category selection alongside existing search and status filters. - Updated AgentTypeDetail with category badges and improved layout. - Added unit tests for grid/list views and category filtering in AgentTypeList. - Introduced `@radix-ui/react-toggle-group` for view mode toggle in AgentTypeList.
This commit is contained in:
84
frontend/src/components/ui/dynamic-icon.tsx
Normal file
84
frontend/src/components/ui/dynamic-icon.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* DynamicIcon Component
|
||||
*
|
||||
* Renders Lucide icons dynamically by name string.
|
||||
* Useful when icon names come from data (e.g., database).
|
||||
*/
|
||||
|
||||
import * as LucideIcons from 'lucide-react';
|
||||
import type { LucideProps } from 'lucide-react';
|
||||
|
||||
/**
|
||||
* Map of icon names to their components.
|
||||
* Uses kebab-case names (e.g., 'clipboard-check') as keys.
|
||||
*/
|
||||
const iconMap: Record<string, React.ComponentType<LucideProps>> = {
|
||||
// Development
|
||||
'clipboard-check': LucideIcons.ClipboardCheck,
|
||||
briefcase: LucideIcons.Briefcase,
|
||||
'file-text': LucideIcons.FileText,
|
||||
'git-branch': LucideIcons.GitBranch,
|
||||
code: LucideIcons.Code,
|
||||
server: LucideIcons.Server,
|
||||
layout: LucideIcons.Layout,
|
||||
smartphone: LucideIcons.Smartphone,
|
||||
// Design
|
||||
palette: LucideIcons.Palette,
|
||||
search: LucideIcons.Search,
|
||||
// Quality
|
||||
shield: LucideIcons.Shield,
|
||||
'shield-check': LucideIcons.ShieldCheck,
|
||||
// Operations
|
||||
settings: LucideIcons.Settings,
|
||||
'settings-2': LucideIcons.Settings2,
|
||||
// AI/ML
|
||||
brain: LucideIcons.Brain,
|
||||
microscope: LucideIcons.Microscope,
|
||||
eye: LucideIcons.Eye,
|
||||
'message-square': LucideIcons.MessageSquare,
|
||||
// Data
|
||||
'bar-chart': LucideIcons.BarChart,
|
||||
database: LucideIcons.Database,
|
||||
// Leadership
|
||||
users: LucideIcons.Users,
|
||||
target: LucideIcons.Target,
|
||||
// Domain Expert
|
||||
calculator: LucideIcons.Calculator,
|
||||
'heart-pulse': LucideIcons.HeartPulse,
|
||||
'flask-conical': LucideIcons.FlaskConical,
|
||||
lightbulb: LucideIcons.Lightbulb,
|
||||
'book-open': LucideIcons.BookOpen,
|
||||
// Generic
|
||||
bot: LucideIcons.Bot,
|
||||
cpu: LucideIcons.Cpu,
|
||||
};
|
||||
|
||||
interface DynamicIconProps extends Omit<LucideProps, 'name'> {
|
||||
/** Icon name in kebab-case (e.g., 'clipboard-check', 'bot') */
|
||||
name: string | null | undefined;
|
||||
/** Fallback icon name if the specified icon is not found */
|
||||
fallback?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a Lucide icon dynamically by name.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <DynamicIcon name="clipboard-check" className="h-5 w-5" />
|
||||
* <DynamicIcon name={agent.icon} fallback="bot" />
|
||||
* ```
|
||||
*/
|
||||
export function DynamicIcon({ name, fallback = 'bot', ...props }: DynamicIconProps) {
|
||||
const iconName = name || fallback;
|
||||
const IconComponent = iconMap[iconName] || iconMap[fallback] || LucideIcons.Bot;
|
||||
|
||||
return <IconComponent {...props} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available icon names for validation or display
|
||||
*/
|
||||
export function getAvailableIconNames(): string[] {
|
||||
return Object.keys(iconMap);
|
||||
}
|
||||
Reference in New Issue
Block a user