import 'package:ac_web/Api/AcApi.dart'; import 'package:ac_web/Api/Dtos/AgentDto.dart'; import 'package:ac_web/Pages/AgentDetails.dart'; import 'package:ac_web/Widgets/AgentStatusIndicator.dart'; import 'package:ac_web/Widgets/AgentTypeIcons.dart'; import 'package:ac_web/Widgets/AutoRefreshState.dart'; import 'package:flutter/material.dart'; /// Fetches all agents from the AgentsController and lists them with a colored /// status indicator in front of their name. class AgentAvailabilityColumn extends StatefulWidget{ const AgentAvailabilityColumn({super.key}); @override State createState() => _AgentAvailabilityColumnState(); } class _AgentAvailabilityColumnState extends State with AutoRefreshState { late Future> mAgentsFuture; @override void initState() { super.initState(); mAgentsFuture = AcApi.instance.agents.getAgents(); } /// Reload triggered by the user. Shows the loading indicator again because /// the user asked for the request and should see that it is running. void ReloadAgents(){ setState(() { mAgentsFuture = AcApi.instance.agents.getAgents(); }); } /// Automatic reload. The agents that are already on screen stay visible /// while the request runs, the future is only replaced once it succeeded. @override Future RefreshData() async { final List agents = await AcApi.instance.agents.getAgents(); if (!mounted) { return; } setState(() { mAgentsFuture = Future>.value(agents); }); } @override Widget build(BuildContext context) { return FutureBuilder>( future: mAgentsFuture, builder: (context, snapshot) { // Not `connectionState`: a refresh puts the builder back into the // waiting state although the previous agents are still available, and // those should stay on screen instead of flashing a spinner. if (!snapshot.hasData && !snapshot.hasError) { return const Center(child: CircularProgressIndicator()); } if (snapshot.hasError && !snapshot.hasData) { return Center(child: Text('Could not load agents: ${snapshot.error}')); } // The list of agents fetched from the AgentsController. final List agents = snapshot.data ?? []; return _buildList(agents); }, ); } Widget _buildList(List agents) { if (agents.isEmpty) { return const Center(child: Text("No agents available")); } return RefreshIndicator( onRefresh: () async => ReloadAgents(), child: ListView.builder( padding: const EdgeInsets.all(8), itemCount: agents.length, itemBuilder: (context, index) { final AgentDto agent = agents[index]; return ListTile( leading: AgentStatusIndicator(status: agent.status), title: Text(agent.name), subtitle: Text("${agent.type.displayName} - ${agent.status.displayName}"), trailing: Icon(agent.type.icon), onTap: () => _openAgent(agent), ); }, ), ); } /// Opens a new page that shows all details of the given agent. void _openAgent(AgentDto agent) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => AgentDetails(agent: agent), ), ); } }