diff --git a/src/app/_components/InstalledScriptsTab.tsx b/src/app/_components/InstalledScriptsTab.tsx index cd06c89..fd43668 100644 --- a/src/app/_components/InstalledScriptsTab.tsx +++ b/src/app/_components/InstalledScriptsTab.tsx @@ -26,6 +26,8 @@ export function InstalledScriptsTab() { const [searchTerm, setSearchTerm] = useState(''); const [statusFilter, setStatusFilter] = useState<'all' | 'success' | 'failed' | 'in_progress'>('all'); const [serverFilter, setServerFilter] = useState('all'); + const [sortField, setSortField] = useState<'script_name' | 'container_id' | 'server_name' | 'status' | 'installation_date'>('script_name'); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc'); const [updatingScript, setUpdatingScript] = useState<{ id: number; containerId: string; server?: any } | null>(null); const [editingScriptId, setEditingScriptId] = useState(null); const [editFormData, setEditFormData] = useState<{ script_name: string; container_id: string }>({ script_name: '', container_id: '' }); @@ -154,20 +156,58 @@ export function InstalledScriptsTab() { } }, [scripts.length, serversData?.servers, cleanupMutation]); - // Filter scripts based on search and filters - const filteredScripts = scripts.filter((script: InstalledScript) => { - const matchesSearch = script.script_name.toLowerCase().includes(searchTerm.toLowerCase()) || - (script.container_id?.includes(searchTerm) ?? false) || - (script.server_name?.toLowerCase().includes(searchTerm.toLowerCase()) ?? false); - - const matchesStatus = statusFilter === 'all' || script.status === statusFilter; - - const matchesServer = serverFilter === 'all' || - (serverFilter === 'local' && !script.server_name) || - (script.server_name === serverFilter); - - return matchesSearch && matchesStatus && matchesServer; - }); + // Filter and sort scripts + const filteredScripts = scripts + .filter((script: InstalledScript) => { + const matchesSearch = script.script_name.toLowerCase().includes(searchTerm.toLowerCase()) || + (script.container_id?.includes(searchTerm) ?? false) || + (script.server_name?.toLowerCase().includes(searchTerm.toLowerCase()) ?? false); + + const matchesStatus = statusFilter === 'all' || script.status === statusFilter; + + const matchesServer = serverFilter === 'all' || + (serverFilter === 'local' && !script.server_name) || + (script.server_name === serverFilter); + + return matchesSearch && matchesStatus && matchesServer; + }) + .sort((a: InstalledScript, b: InstalledScript) => { + let aValue: any; + let bValue: any; + + switch (sortField) { + case 'script_name': + aValue = a.script_name.toLowerCase(); + bValue = b.script_name.toLowerCase(); + break; + case 'container_id': + aValue = a.container_id ?? ''; + bValue = b.container_id ?? ''; + break; + case 'server_name': + aValue = a.server_name ?? 'Local'; + bValue = b.server_name ?? 'Local'; + break; + case 'status': + aValue = a.status; + bValue = b.status; + break; + case 'installation_date': + aValue = new Date(a.installation_date).getTime(); + bValue = new Date(b.installation_date).getTime(); + break; + default: + return 0; + } + + if (aValue < bValue) { + return sortDirection === 'asc' ? -1 : 1; + } + if (aValue > bValue) { + return sortDirection === 'asc' ? 1 : -1; + } + return 0; + }); // Get unique servers for filter const uniqueServers: string[] = []; @@ -298,6 +338,15 @@ export function InstalledScriptsTab() { setAutoDetectServerId(''); }; + const handleSort = (field: 'script_name' | 'container_id' | 'server_name' | 'status' | 'installation_date') => { + if (sortField === field) { + setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); + } else { + setSortField(field); + setSortDirection('asc'); + } + }; + const formatDate = (dateString: string) => { return new Date(dateString).toLocaleString(); @@ -652,20 +701,70 @@ export function InstalledScriptsTab() { - - - - -
- Script Name + handleSort('script_name')} + > +
+ Script Name + {sortField === 'script_name' && ( + + {sortDirection === 'asc' ? '↑' : '↓'} + + )} +
- Container ID + handleSort('container_id')} + > +
+ Container ID + {sortField === 'container_id' && ( + + {sortDirection === 'asc' ? '↑' : '↓'} + + )} +
- Server + handleSort('server_name')} + > +
+ Server + {sortField === 'server_name' && ( + + {sortDirection === 'asc' ? '↑' : '↓'} + + )} +
- Status + handleSort('status')} + > +
+ Status + {sortField === 'status' && ( + + {sortDirection === 'asc' ? '↑' : '↓'} + + )} +
- Installation Date + handleSort('installation_date')} + > +
+ Installation Date + {sortField === 'installation_date' && ( + + {sortDirection === 'asc' ? '↑' : '↓'} + + )} +
Actions