diff --git a/src/Managing.Api/Controllers/DataController.cs b/src/Managing.Api/Controllers/DataController.cs index d6d78a7..502ba63 100644 --- a/src/Managing.Api/Controllers/DataController.cs +++ b/src/Managing.Api/Controllers/DataController.cs @@ -672,6 +672,7 @@ public class DataController : ControllerBase /// Number of items per page (defaults to 10, max 100) /// Field to sort by (TotalPnL, PnLLast24h, TotalROI, ROILast24h, Wins, Losses, AverageWinRate, ActiveStrategiesCount, TotalVolume, VolumeLast24h) /// Sort order - "asc" or "desc" (defaults to "desc") + /// Optional comma-separated list of agent names to filter by /// A paginated list of agent summaries sorted by the specified field [HttpGet("GetAgentIndexPaginated")] public async Task> GetAgentIndexPaginated( @@ -679,7 +680,8 @@ public class DataController : ControllerBase int page = 1, int pageSize = 10, string sortBy = "TotalPnL", - string sortOrder = "desc") + string sortOrder = "desc", + string? agentNames = null) { // Validate time filter var validTimeFilters = new[] { "24H", "3D", "1W", "1M", "1Y", "Total" }; @@ -706,13 +708,24 @@ public class DataController : ControllerBase } // Validate sort by field - var validSortFields = new[] { "TotalPnL", "PnLLast24h", "TotalROI", "ROILast24h", "Wins", "Losses", "AverageWinRate", "ActiveStrategiesCount", "TotalVolume", "VolumeLast24h" }; + var validSortFields = new[] + { + "TotalPnL", "PnLLast24h", "TotalROI", "ROILast24h", "Wins", "Losses", "AverageWinRate", + "ActiveStrategiesCount", "TotalVolume", "VolumeLast24h" + }; if (!validSortFields.Contains(sortBy)) { sortBy = "TotalPnL"; // Default to TotalPnL if invalid } - string cacheKey = $"AgentIndex_{timeFilter}"; + // Create cache key that includes agent names filter + var agentNamesForCache = !string.IsNullOrWhiteSpace(agentNames) + ? string.Join("_", agentNames.Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(name => name.Trim()) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .OrderBy(name => name)) + : "all"; + string cacheKey = $"AgentIndex_{timeFilter}_{agentNamesForCache}"; // Check if the agent index is already cached var cachedIndex = _cacheService.GetValue(cacheKey); @@ -792,10 +805,26 @@ public class DataController : ControllerBase _cacheService.SaveValue(cacheKey, agentIndex, TimeSpan.FromMinutes(5)); } + // Apply agent name filtering if specified + if (!string.IsNullOrWhiteSpace(agentNames)) + { + var agentNameList = agentNames.Split(',', StringSplitOptions.RemoveEmptyEntries) + .Select(name => name.Trim()) + .Where(name => !string.IsNullOrWhiteSpace(name)) + .ToList(); + + if (agentNameList.Any()) + { + allAgentSummaries = allAgentSummaries + .Where(agent => agentNameList.Contains(agent.AgentName, StringComparer.OrdinalIgnoreCase)) + .ToList(); + } + } + // Apply sorting var sortedSummaries = sortBy switch { - "TotalPnL" => sortOrder == "desc" + "TotalPnL" => sortOrder == "desc" ? allAgentSummaries.OrderByDescending(a => a.TotalPnL) : allAgentSummaries.OrderBy(a => a.TotalPnL), "PnLLast24h" => sortOrder == "desc" @@ -850,7 +879,8 @@ public class DataController : ControllerBase HasPreviousPage = page > 1, TimeFilter = timeFilter, SortBy = sortBy, - SortOrder = sortOrder + SortOrder = sortOrder, + FilteredAgentNames = agentNames }; return Ok(response); @@ -906,8 +936,8 @@ public class DataController : ControllerBase /// Retrieves an array of online agent names /// /// An array of online agent names - [HttpGet("GetAgentStatuses")] - public async Task>> GetAgentStatuses() + [HttpGet("GetOnlineAgent")] + public async Task>> GetOnlineAgent() { const string cacheKey = "OnlineAgentNames"; diff --git a/src/Managing.Api/Models/Responses/PaginatedAgentIndexResponse.cs b/src/Managing.Api/Models/Responses/PaginatedAgentIndexResponse.cs index 7332e3b..54978d9 100644 --- a/src/Managing.Api/Models/Responses/PaginatedAgentIndexResponse.cs +++ b/src/Managing.Api/Models/Responses/PaginatedAgentIndexResponse.cs @@ -54,4 +54,9 @@ public class PaginatedAgentIndexResponse /// Sort order (asc or desc) /// public string SortOrder { get; set; } = "desc"; + + /// + /// Comma-separated list of agent names used for filtering (if any) + /// + public string? FilteredAgentNames { get; set; } } \ No newline at end of file diff --git a/src/Managing.WebApp/src/generated/ManagingApi.ts b/src/Managing.WebApp/src/generated/ManagingApi.ts index 56f9d6a..d064c03 100644 --- a/src/Managing.WebApp/src/generated/ManagingApi.ts +++ b/src/Managing.WebApp/src/generated/ManagingApi.ts @@ -1919,7 +1919,7 @@ export class DataClient extends AuthorizedApiBase { return Promise.resolve(null as any); } - data_GetAgentIndexPaginated(timeFilter: string | null | undefined, page: number | undefined, pageSize: number | undefined, sortBy: string | null | undefined, sortOrder: string | null | undefined): Promise { + data_GetAgentIndexPaginated(timeFilter: string | null | undefined, page: number | undefined, pageSize: number | undefined, sortBy: string | null | undefined, sortOrder: string | null | undefined, agentNames: string | null | undefined): Promise { let url_ = this.baseUrl + "/Data/GetAgentIndexPaginated?"; if (timeFilter !== undefined && timeFilter !== null) url_ += "timeFilter=" + encodeURIComponent("" + timeFilter) + "&"; @@ -1935,6 +1935,8 @@ export class DataClient extends AuthorizedApiBase { url_ += "sortBy=" + encodeURIComponent("" + sortBy) + "&"; if (sortOrder !== undefined && sortOrder !== null) url_ += "sortOrder=" + encodeURIComponent("" + sortOrder) + "&"; + if (agentNames !== undefined && agentNames !== null) + url_ += "agentNames=" + encodeURIComponent("" + agentNames) + "&"; url_ = url_.replace(/[?&]$/, ""); let options_: RequestInit = { @@ -2060,8 +2062,8 @@ export class DataClient extends AuthorizedApiBase { return Promise.resolve(null as any); } - data_GetAgentStatuses(): Promise { - let url_ = this.baseUrl + "/Data/GetAgentStatuses"; + data_GetOnlineAgent(): Promise { + let url_ = this.baseUrl + "/Data/GetOnlineAgent"; url_ = url_.replace(/[?&]$/, ""); let options_: RequestInit = { @@ -2074,17 +2076,17 @@ export class DataClient extends AuthorizedApiBase { return this.transformOptions(options_).then(transformedOptions_ => { return this.http.fetch(url_, transformedOptions_); }).then((_response: Response) => { - return this.processData_GetAgentStatuses(_response); + return this.processData_GetOnlineAgent(_response); }); } - protected processData_GetAgentStatuses(response: Response): Promise { + protected processData_GetOnlineAgent(response: Response): Promise { const status = response.status; let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); }; if (status === 200) { return response.text().then((_responseText) => { let result200: any = null; - result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as AgentStatusResponse[]; + result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as string[]; return result200; }); } else if (status !== 200 && status !== 204) { @@ -2092,7 +2094,7 @@ export class DataClient extends AuthorizedApiBase { return throwException("An unexpected server error occurred.", status, _responseText, _headers); }); } - return Promise.resolve(null as any); + return Promise.resolve(null as any); } } @@ -4509,6 +4511,7 @@ export interface PaginatedAgentIndexResponse { timeFilter?: string | null; sortBy?: string | null; sortOrder?: string | null; + filteredAgentNames?: string | null; } export interface AgentBalanceHistory { @@ -4533,16 +4536,6 @@ export interface BestAgentsResponse { totalPages?: number; } -export interface AgentStatusResponse { - agentName?: string | null; - status?: AgentStatus; -} - -export enum AgentStatus { - Offline = "Offline", - Online = "Online", -} - export interface ScenarioViewModel { name: string; indicators: IndicatorViewModel[]; diff --git a/src/Managing.WebApp/src/generated/ManagingApiTypes.ts b/src/Managing.WebApp/src/generated/ManagingApiTypes.ts index e59240c..e20fb70 100644 --- a/src/Managing.WebApp/src/generated/ManagingApiTypes.ts +++ b/src/Managing.WebApp/src/generated/ManagingApiTypes.ts @@ -999,6 +999,7 @@ export interface PaginatedAgentIndexResponse { timeFilter?: string | null; sortBy?: string | null; sortOrder?: string | null; + filteredAgentNames?: string | null; } export interface AgentBalanceHistory { @@ -1023,16 +1024,6 @@ export interface BestAgentsResponse { totalPages?: number; } -export interface AgentStatusResponse { - agentName?: string | null; - status?: AgentStatus; -} - -export enum AgentStatus { - Offline = "Offline", - Online = "Online", -} - export interface ScenarioViewModel { name: string; indicators: IndicatorViewModel[];