mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 22:17:20 +00:00
fix(shared): support file-based agents and recursive commands
This commit is contained in:
1 parent
77a236490d
commit
346fa5fcda
3 files changed
+351
-61
No files matched your search
+33
-5
@@ -1,16 +1,31 @@
|
||||
import { useState } from 'react';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
||||
import { useSharedItems, useSharedSummary } from '@/hooks/use-shared';
|
||||
import { FileText, Sparkles, Bot, AlertTriangle } from 'lucide-react';
|
||||
import { FileText, Sparkles, Bot, AlertTriangle, Search } from 'lucide-react';
|
||||
|
||||
type TabType = 'commands' | 'skills' | 'agents';
|
||||
|
||||
export function SharedPage() {
|
||||
const [tab, setTab] = useState<TabType>('commands');
|
||||
const [query, setQuery] = useState('');
|
||||
const { data: summary } = useSharedSummary();
|
||||
const { data: items, isLoading } = useSharedItems(tab);
|
||||
const normalizedQuery = query.trim().toLowerCase();
|
||||
const filteredItems = useMemo(() => {
|
||||
const allItems = items?.items ?? [];
|
||||
if (!normalizedQuery) {
|
||||
return allItems;
|
||||
}
|
||||
|
||||
return allItems.filter((item) =>
|
||||
[item.name, item.description, item.path].some((value) =>
|
||||
value.toLowerCase().includes(normalizedQuery)
|
||||
)
|
||||
);
|
||||
}, [items, normalizedQuery]);
|
||||
|
||||
const tabs: { id: TabType; label: string; icon: typeof FileText; count: number }[] = [
|
||||
{ id: 'commands', label: 'Commands', icon: FileText, count: summary?.commands ?? 0 },
|
||||
@@ -44,7 +59,10 @@ export function SharedPage() {
|
||||
key={t.id}
|
||||
variant={tab === t.id ? 'default' : 'ghost'}
|
||||
size="sm"
|
||||
onClick={() => setTab(t.id)}
|
||||
onClick={() => {
|
||||
setTab(t.id);
|
||||
setQuery('');
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
<t.icon className="w-4 h-4" />
|
||||
@@ -53,15 +71,25 @@ export function SharedPage() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="relative max-w-md">
|
||||
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
|
||||
<Input
|
||||
value={query}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
placeholder={`Filter ${tab} by name, description, or path`}
|
||||
className="pl-9"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="mt-4">
|
||||
{isLoading ? (
|
||||
<div className="text-muted-foreground">Loading...</div>
|
||||
) : items?.items.length === 0 ? (
|
||||
) : filteredItems.length === 0 ? (
|
||||
<div className="text-muted-foreground">No {tab} found</div>
|
||||
) : (
|
||||
<div className="grid gap-3">
|
||||
{items?.items.map((item) => (
|
||||
{filteredItems.map((item) => (
|
||||
<Card key={item.name}>
|
||||
<CardContent>
|
||||
<div className="font-medium">{item.name}</div>
|
||||
|
||||
Reference in new issue
Block a user