Add agentNames to the endpoint index
This commit is contained in:
@@ -672,6 +672,7 @@ public class DataController : ControllerBase
|
|||||||
/// <param name="pageSize">Number of items per page (defaults to 10, max 100)</param>
|
/// <param name="pageSize">Number of items per page (defaults to 10, max 100)</param>
|
||||||
/// <param name="sortBy">Field to sort by (TotalPnL, PnLLast24h, TotalROI, ROILast24h, Wins, Losses, AverageWinRate, ActiveStrategiesCount, TotalVolume, VolumeLast24h)</param>
|
/// <param name="sortBy">Field to sort by (TotalPnL, PnLLast24h, TotalROI, ROILast24h, Wins, Losses, AverageWinRate, ActiveStrategiesCount, TotalVolume, VolumeLast24h)</param>
|
||||||
/// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
|
/// <param name="sortOrder">Sort order - "asc" or "desc" (defaults to "desc")</param>
|
||||||
|
/// <param name="agentNames">Optional comma-separated list of agent names to filter by</param>
|
||||||
/// <returns>A paginated list of agent summaries sorted by the specified field</returns>
|
/// <returns>A paginated list of agent summaries sorted by the specified field</returns>
|
||||||
[HttpGet("GetAgentIndexPaginated")]
|
[HttpGet("GetAgentIndexPaginated")]
|
||||||
public async Task<ActionResult<PaginatedAgentIndexResponse>> GetAgentIndexPaginated(
|
public async Task<ActionResult<PaginatedAgentIndexResponse>> GetAgentIndexPaginated(
|
||||||
@@ -679,7 +680,8 @@ public class DataController : ControllerBase
|
|||||||
int page = 1,
|
int page = 1,
|
||||||
int pageSize = 10,
|
int pageSize = 10,
|
||||||
string sortBy = "TotalPnL",
|
string sortBy = "TotalPnL",
|
||||||
string sortOrder = "desc")
|
string sortOrder = "desc",
|
||||||
|
string? agentNames = null)
|
||||||
{
|
{
|
||||||
// Validate time filter
|
// Validate time filter
|
||||||
var validTimeFilters = new[] { "24H", "3D", "1W", "1M", "1Y", "Total" };
|
var validTimeFilters = new[] { "24H", "3D", "1W", "1M", "1Y", "Total" };
|
||||||
@@ -706,13 +708,24 @@ public class DataController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate sort by field
|
// 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))
|
if (!validSortFields.Contains(sortBy))
|
||||||
{
|
{
|
||||||
sortBy = "TotalPnL"; // Default to TotalPnL if invalid
|
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
|
// Check if the agent index is already cached
|
||||||
var cachedIndex = _cacheService.GetValue<AgentIndexViewModel>(cacheKey);
|
var cachedIndex = _cacheService.GetValue<AgentIndexViewModel>(cacheKey);
|
||||||
@@ -792,10 +805,26 @@ public class DataController : ControllerBase
|
|||||||
_cacheService.SaveValue(cacheKey, agentIndex, TimeSpan.FromMinutes(5));
|
_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
|
// Apply sorting
|
||||||
var sortedSummaries = sortBy switch
|
var sortedSummaries = sortBy switch
|
||||||
{
|
{
|
||||||
"TotalPnL" => sortOrder == "desc"
|
"TotalPnL" => sortOrder == "desc"
|
||||||
? allAgentSummaries.OrderByDescending(a => a.TotalPnL)
|
? allAgentSummaries.OrderByDescending(a => a.TotalPnL)
|
||||||
: allAgentSummaries.OrderBy(a => a.TotalPnL),
|
: allAgentSummaries.OrderBy(a => a.TotalPnL),
|
||||||
"PnLLast24h" => sortOrder == "desc"
|
"PnLLast24h" => sortOrder == "desc"
|
||||||
@@ -850,7 +879,8 @@ public class DataController : ControllerBase
|
|||||||
HasPreviousPage = page > 1,
|
HasPreviousPage = page > 1,
|
||||||
TimeFilter = timeFilter,
|
TimeFilter = timeFilter,
|
||||||
SortBy = sortBy,
|
SortBy = sortBy,
|
||||||
SortOrder = sortOrder
|
SortOrder = sortOrder,
|
||||||
|
FilteredAgentNames = agentNames
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
@@ -906,8 +936,8 @@ public class DataController : ControllerBase
|
|||||||
/// Retrieves an array of online agent names
|
/// Retrieves an array of online agent names
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>An array of online agent names</returns>
|
/// <returns>An array of online agent names</returns>
|
||||||
[HttpGet("GetAgentStatuses")]
|
[HttpGet("GetOnlineAgent")]
|
||||||
public async Task<ActionResult<List<string>>> GetAgentStatuses()
|
public async Task<ActionResult<List<string>>> GetOnlineAgent()
|
||||||
{
|
{
|
||||||
const string cacheKey = "OnlineAgentNames";
|
const string cacheKey = "OnlineAgentNames";
|
||||||
|
|
||||||
|
|||||||
@@ -54,4 +54,9 @@ public class PaginatedAgentIndexResponse
|
|||||||
/// Sort order (asc or desc)
|
/// Sort order (asc or desc)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SortOrder { get; set; } = "desc";
|
public string SortOrder { get; set; } = "desc";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Comma-separated list of agent names used for filtering (if any)
|
||||||
|
/// </summary>
|
||||||
|
public string? FilteredAgentNames { get; set; }
|
||||||
}
|
}
|
||||||
@@ -1919,7 +1919,7 @@ export class DataClient extends AuthorizedApiBase {
|
|||||||
return Promise.resolve<AgentIndexViewModel>(null as any);
|
return Promise.resolve<AgentIndexViewModel>(null as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_GetAgentIndexPaginated(timeFilter: string | null | undefined, page: number | undefined, pageSize: number | undefined, sortBy: string | null | undefined, sortOrder: string | null | undefined): Promise<PaginatedAgentIndexResponse> {
|
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<PaginatedAgentIndexResponse> {
|
||||||
let url_ = this.baseUrl + "/Data/GetAgentIndexPaginated?";
|
let url_ = this.baseUrl + "/Data/GetAgentIndexPaginated?";
|
||||||
if (timeFilter !== undefined && timeFilter !== null)
|
if (timeFilter !== undefined && timeFilter !== null)
|
||||||
url_ += "timeFilter=" + encodeURIComponent("" + timeFilter) + "&";
|
url_ += "timeFilter=" + encodeURIComponent("" + timeFilter) + "&";
|
||||||
@@ -1935,6 +1935,8 @@ export class DataClient extends AuthorizedApiBase {
|
|||||||
url_ += "sortBy=" + encodeURIComponent("" + sortBy) + "&";
|
url_ += "sortBy=" + encodeURIComponent("" + sortBy) + "&";
|
||||||
if (sortOrder !== undefined && sortOrder !== null)
|
if (sortOrder !== undefined && sortOrder !== null)
|
||||||
url_ += "sortOrder=" + encodeURIComponent("" + sortOrder) + "&";
|
url_ += "sortOrder=" + encodeURIComponent("" + sortOrder) + "&";
|
||||||
|
if (agentNames !== undefined && agentNames !== null)
|
||||||
|
url_ += "agentNames=" + encodeURIComponent("" + agentNames) + "&";
|
||||||
url_ = url_.replace(/[?&]$/, "");
|
url_ = url_.replace(/[?&]$/, "");
|
||||||
|
|
||||||
let options_: RequestInit = {
|
let options_: RequestInit = {
|
||||||
@@ -2060,8 +2062,8 @@ export class DataClient extends AuthorizedApiBase {
|
|||||||
return Promise.resolve<BestAgentsResponse>(null as any);
|
return Promise.resolve<BestAgentsResponse>(null as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
data_GetAgentStatuses(): Promise<AgentStatusResponse[]> {
|
data_GetOnlineAgent(): Promise<string[]> {
|
||||||
let url_ = this.baseUrl + "/Data/GetAgentStatuses";
|
let url_ = this.baseUrl + "/Data/GetOnlineAgent";
|
||||||
url_ = url_.replace(/[?&]$/, "");
|
url_ = url_.replace(/[?&]$/, "");
|
||||||
|
|
||||||
let options_: RequestInit = {
|
let options_: RequestInit = {
|
||||||
@@ -2074,17 +2076,17 @@ export class DataClient extends AuthorizedApiBase {
|
|||||||
return this.transformOptions(options_).then(transformedOptions_ => {
|
return this.transformOptions(options_).then(transformedOptions_ => {
|
||||||
return this.http.fetch(url_, transformedOptions_);
|
return this.http.fetch(url_, transformedOptions_);
|
||||||
}).then((_response: Response) => {
|
}).then((_response: Response) => {
|
||||||
return this.processData_GetAgentStatuses(_response);
|
return this.processData_GetOnlineAgent(_response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected processData_GetAgentStatuses(response: Response): Promise<AgentStatusResponse[]> {
|
protected processData_GetOnlineAgent(response: Response): Promise<string[]> {
|
||||||
const status = response.status;
|
const status = response.status;
|
||||||
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
||||||
if (status === 200) {
|
if (status === 200) {
|
||||||
return response.text().then((_responseText) => {
|
return response.text().then((_responseText) => {
|
||||||
let result200: any = null;
|
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;
|
return result200;
|
||||||
});
|
});
|
||||||
} else if (status !== 200 && status !== 204) {
|
} 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 throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Promise.resolve<AgentStatusResponse[]>(null as any);
|
return Promise.resolve<string[]>(null as any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4509,6 +4511,7 @@ export interface PaginatedAgentIndexResponse {
|
|||||||
timeFilter?: string | null;
|
timeFilter?: string | null;
|
||||||
sortBy?: string | null;
|
sortBy?: string | null;
|
||||||
sortOrder?: string | null;
|
sortOrder?: string | null;
|
||||||
|
filteredAgentNames?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalanceHistory {
|
export interface AgentBalanceHistory {
|
||||||
@@ -4533,16 +4536,6 @@ export interface BestAgentsResponse {
|
|||||||
totalPages?: number;
|
totalPages?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentStatusResponse {
|
|
||||||
agentName?: string | null;
|
|
||||||
status?: AgentStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AgentStatus {
|
|
||||||
Offline = "Offline",
|
|
||||||
Online = "Online",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScenarioViewModel {
|
export interface ScenarioViewModel {
|
||||||
name: string;
|
name: string;
|
||||||
indicators: IndicatorViewModel[];
|
indicators: IndicatorViewModel[];
|
||||||
|
|||||||
@@ -999,6 +999,7 @@ export interface PaginatedAgentIndexResponse {
|
|||||||
timeFilter?: string | null;
|
timeFilter?: string | null;
|
||||||
sortBy?: string | null;
|
sortBy?: string | null;
|
||||||
sortOrder?: string | null;
|
sortOrder?: string | null;
|
||||||
|
filteredAgentNames?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentBalanceHistory {
|
export interface AgentBalanceHistory {
|
||||||
@@ -1023,16 +1024,6 @@ export interface BestAgentsResponse {
|
|||||||
totalPages?: number;
|
totalPages?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AgentStatusResponse {
|
|
||||||
agentName?: string | null;
|
|
||||||
status?: AgentStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AgentStatus {
|
|
||||||
Offline = "Offline",
|
|
||||||
Online = "Online",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ScenarioViewModel {
|
export interface ScenarioViewModel {
|
||||||
name: string;
|
name: string;
|
||||||
indicators: IndicatorViewModel[];
|
indicators: IndicatorViewModel[];
|
||||||
|
|||||||
Reference in New Issue
Block a user