From 9341cb71280f718dcf39d93b53cb7c865ad17d5e Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 9 May 2026 14:32:13 +0100 Subject: [PATCH] Enhance consoles API with pagination and count functionality - Added CountRequestBuilder for consoles by letter and year to support counting items. - Updated PrototypesRequestBuilder to include pagination parameters (skip, take). - Modified ConsolesController to handle pagination in GetConsolesByLetterAsync and GetConsolesByYearAsync methods. - Implemented new count endpoints for consoles by letter and year in ConsolesController. - Enhanced Search.razor and Search.razor.cs to support infinite scrolling and display total counts. - Updated ConsolesService to include pagination and count methods for consoles and prototypes. - Added necessary using directives and cleaned up code for better readability. --- .../Item/Count/CountRequestBuilder.cs | 91 +++++++++ .../ByLetter/Item/WithCItemRequestBuilder.cs | 30 ++- .../ByYear/Item/Count/CountRequestBuilder.cs | 91 +++++++++ .../ByYear/Item/WithYearItemRequestBuilder.cs | 30 ++- .../Consoles/ConsolesRequestBuilder.cs | 24 ++- .../Prototypes/Count/CountRequestBuilder.cs | 91 +++++++++ .../Prototypes/PrototypesRequestBuilder.cs | 30 ++- Marechai.ApiClient/kiota-lock.json | 2 +- .../Controllers/ConsolesController.cs | 175 ++++++++++++------ Marechai/Pages/Consoles/Search.razor | 28 ++- Marechai/Pages/Consoles/Search.razor.cs | 166 ++++++++++++++--- Marechai/Services/ConsolesService.cs | 80 +++++++- 12 files changed, 708 insertions(+), 130 deletions(-) create mode 100644 Marechai.ApiClient/Consoles/ByLetter/Item/Count/CountRequestBuilder.cs create mode 100644 Marechai.ApiClient/Consoles/ByYear/Item/Count/CountRequestBuilder.cs create mode 100644 Marechai.ApiClient/Consoles/Prototypes/Count/CountRequestBuilder.cs diff --git a/Marechai.ApiClient/Consoles/ByLetter/Item/Count/CountRequestBuilder.cs b/Marechai.ApiClient/Consoles/ByLetter/Item/Count/CountRequestBuilder.cs new file mode 100644 index 00000000..ac0ef32d --- /dev/null +++ b/Marechai.ApiClient/Consoles/ByLetter/Item/Count/CountRequestBuilder.cs @@ -0,0 +1,91 @@ +// +#pragma warning disable CS0618 +using Marechai.ApiClient.Models; +using Microsoft.Kiota.Abstractions.Extensions; +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using System; +namespace Marechai.ApiClient.Consoles.ByLetter.Item.Count +{ + /// + /// Builds and executes requests for operations under \consoles\by-letter\{c}\count + /// + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilder : BaseRequestBuilder + { + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public CountRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}/count", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public CountRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}/count", rawUrl) + { + } + /// A + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. + /// When receiving a 400 status code +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + { +#nullable restore +#else + public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> + { + { "400", global::Marechai.ApiClient.Models.ProblemDetails.CreateFromDiscriminatorValue }, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false); + } + /// A + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + { +#endif + var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); + requestInfo.Configure(requestConfiguration); + requestInfo.Headers.TryAdd("Accept", "text/plain;q=0.9"); + return requestInfo; + } + /// + /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored. + /// + /// A + /// The raw URL to use for the request builder. + public global::Marechai.ApiClient.Consoles.ByLetter.Item.Count.CountRequestBuilder WithUrl(string rawUrl) + { + return new global::Marechai.ApiClient.Consoles.ByLetter.Item.Count.CountRequestBuilder(rawUrl, RequestAdapter); + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilderGetRequestConfiguration : RequestConfiguration + { + } + } +} +#pragma warning restore CS0618 diff --git a/Marechai.ApiClient/Consoles/ByLetter/Item/WithCItemRequestBuilder.cs b/Marechai.ApiClient/Consoles/ByLetter/Item/WithCItemRequestBuilder.cs index 7b9c3be1..cb57619a 100644 --- a/Marechai.ApiClient/Consoles/ByLetter/Item/WithCItemRequestBuilder.cs +++ b/Marechai.ApiClient/Consoles/ByLetter/Item/WithCItemRequestBuilder.cs @@ -1,5 +1,6 @@ // #pragma warning disable CS0618 +using Marechai.ApiClient.Consoles.ByLetter.Item.Count; using Marechai.ApiClient.Models; using Microsoft.Kiota.Abstractions.Extensions; using Microsoft.Kiota.Abstractions.Serialization; @@ -17,12 +18,17 @@ namespace Marechai.ApiClient.Consoles.ByLetter.Item [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] public partial class WithCItemRequestBuilder : BaseRequestBuilder { + /// The count property + public global::Marechai.ApiClient.Consoles.ByLetter.Item.Count.CountRequestBuilder Count + { + get => new global::Marechai.ApiClient.Consoles.ByLetter.Item.Count.CountRequestBuilder(PathParameters, RequestAdapter); + } /// /// Instantiates a new and sets the default values. /// /// Path parameters for the request /// The request adapter to use to execute the requests. - public WithCItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}", pathParameters) + public WithCItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}{?skip*,take*}", pathParameters) { } /// @@ -30,7 +36,7 @@ namespace Marechai.ApiClient.Consoles.ByLetter.Item /// /// The raw URL to use for the request builder. /// The request adapter to use to execute the requests. - public WithCItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}", rawUrl) + public WithCItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-letter/{c}{?skip*,take*}", rawUrl) { } /// A List<global::Marechai.ApiClient.Models.MachineDto> @@ -39,11 +45,11 @@ namespace Marechai.ApiClient.Consoles.ByLetter.Item /// When receiving a 400 status code #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) { #nullable restore #else - public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) { #endif var requestInfo = ToGetRequestInformation(requestConfiguration); @@ -58,11 +64,11 @@ namespace Marechai.ApiClient.Consoles.ByLetter.Item /// Configuration for the request such as headers, query parameters, and middleware options. #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) { #nullable restore #else - public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) { #endif var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); @@ -79,12 +85,22 @@ namespace Marechai.ApiClient.Consoles.ByLetter.Item { return new global::Marechai.ApiClient.Consoles.ByLetter.Item.WithCItemRequestBuilder(rawUrl, RequestAdapter); } + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + #pragma warning disable CS1591 + public partial class WithCItemRequestBuilderGetQueryParameters + #pragma warning restore CS1591 + { + [QueryParameter("skip")] + public int? Skip { get; set; } + [QueryParameter("take")] + public int? Take { get; set; } + } /// /// Configuration for the request such as headers, query parameters, and middleware options. /// [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] - public partial class WithCItemRequestBuilderGetRequestConfiguration : RequestConfiguration + public partial class WithCItemRequestBuilderGetRequestConfiguration : RequestConfiguration { } } diff --git a/Marechai.ApiClient/Consoles/ByYear/Item/Count/CountRequestBuilder.cs b/Marechai.ApiClient/Consoles/ByYear/Item/Count/CountRequestBuilder.cs new file mode 100644 index 00000000..ca47692a --- /dev/null +++ b/Marechai.ApiClient/Consoles/ByYear/Item/Count/CountRequestBuilder.cs @@ -0,0 +1,91 @@ +// +#pragma warning disable CS0618 +using Marechai.ApiClient.Models; +using Microsoft.Kiota.Abstractions.Extensions; +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using System; +namespace Marechai.ApiClient.Consoles.ByYear.Item.Count +{ + /// + /// Builds and executes requests for operations under \consoles\by-year\{year}\count + /// + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilder : BaseRequestBuilder + { + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public CountRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}/count", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public CountRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}/count", rawUrl) + { + } + /// A + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. + /// When receiving a 400 status code +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + { +#nullable restore +#else + public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> + { + { "400", global::Marechai.ApiClient.Models.ProblemDetails.CreateFromDiscriminatorValue }, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false); + } + /// A + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + { +#endif + var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); + requestInfo.Configure(requestConfiguration); + requestInfo.Headers.TryAdd("Accept", "text/plain;q=0.9"); + return requestInfo; + } + /// + /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored. + /// + /// A + /// The raw URL to use for the request builder. + public global::Marechai.ApiClient.Consoles.ByYear.Item.Count.CountRequestBuilder WithUrl(string rawUrl) + { + return new global::Marechai.ApiClient.Consoles.ByYear.Item.Count.CountRequestBuilder(rawUrl, RequestAdapter); + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilderGetRequestConfiguration : RequestConfiguration + { + } + } +} +#pragma warning restore CS0618 diff --git a/Marechai.ApiClient/Consoles/ByYear/Item/WithYearItemRequestBuilder.cs b/Marechai.ApiClient/Consoles/ByYear/Item/WithYearItemRequestBuilder.cs index eeb493da..e7b9f0f5 100644 --- a/Marechai.ApiClient/Consoles/ByYear/Item/WithYearItemRequestBuilder.cs +++ b/Marechai.ApiClient/Consoles/ByYear/Item/WithYearItemRequestBuilder.cs @@ -1,5 +1,6 @@ // #pragma warning disable CS0618 +using Marechai.ApiClient.Consoles.ByYear.Item.Count; using Marechai.ApiClient.Models; using Microsoft.Kiota.Abstractions.Extensions; using Microsoft.Kiota.Abstractions.Serialization; @@ -17,12 +18,17 @@ namespace Marechai.ApiClient.Consoles.ByYear.Item [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] public partial class WithYearItemRequestBuilder : BaseRequestBuilder { + /// The count property + public global::Marechai.ApiClient.Consoles.ByYear.Item.Count.CountRequestBuilder Count + { + get => new global::Marechai.ApiClient.Consoles.ByYear.Item.Count.CountRequestBuilder(PathParameters, RequestAdapter); + } /// /// Instantiates a new and sets the default values. /// /// Path parameters for the request /// The request adapter to use to execute the requests. - public WithYearItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}", pathParameters) + public WithYearItemRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}{?skip*,take*}", pathParameters) { } /// @@ -30,7 +36,7 @@ namespace Marechai.ApiClient.Consoles.ByYear.Item /// /// The raw URL to use for the request builder. /// The request adapter to use to execute the requests. - public WithYearItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}", rawUrl) + public WithYearItemRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/by-year/{year}{?skip*,take*}", rawUrl) { } /// A List<global::Marechai.ApiClient.Models.MachineDto> @@ -39,11 +45,11 @@ namespace Marechai.ApiClient.Consoles.ByYear.Item /// When receiving a 400 status code #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) { #nullable restore #else - public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) { #endif var requestInfo = ToGetRequestInformation(requestConfiguration); @@ -58,11 +64,11 @@ namespace Marechai.ApiClient.Consoles.ByYear.Item /// Configuration for the request such as headers, query parameters, and middleware options. #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) { #nullable restore #else - public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) { #endif var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); @@ -79,12 +85,22 @@ namespace Marechai.ApiClient.Consoles.ByYear.Item { return new global::Marechai.ApiClient.Consoles.ByYear.Item.WithYearItemRequestBuilder(rawUrl, RequestAdapter); } + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + #pragma warning disable CS1591 + public partial class WithYearItemRequestBuilderGetQueryParameters + #pragma warning restore CS1591 + { + [QueryParameter("skip")] + public int? Skip { get; set; } + [QueryParameter("take")] + public int? Take { get; set; } + } /// /// Configuration for the request such as headers, query parameters, and middleware options. /// [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] - public partial class WithYearItemRequestBuilderGetRequestConfiguration : RequestConfiguration + public partial class WithYearItemRequestBuilderGetRequestConfiguration : RequestConfiguration { } } diff --git a/Marechai.ApiClient/Consoles/ConsolesRequestBuilder.cs b/Marechai.ApiClient/Consoles/ConsolesRequestBuilder.cs index af8be6d8..245c5efe 100644 --- a/Marechai.ApiClient/Consoles/ConsolesRequestBuilder.cs +++ b/Marechai.ApiClient/Consoles/ConsolesRequestBuilder.cs @@ -64,7 +64,7 @@ namespace Marechai.ApiClient.Consoles /// /// Path parameters for the request /// The request adapter to use to execute the requests. - public ConsolesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles", pathParameters) + public ConsolesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles{?skip*,take*}", pathParameters) { } /// @@ -72,7 +72,7 @@ namespace Marechai.ApiClient.Consoles /// /// The raw URL to use for the request builder. /// The request adapter to use to execute the requests. - public ConsolesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles", rawUrl) + public ConsolesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles{?skip*,take*}", rawUrl) { } /// A List<global::Marechai.ApiClient.Models.MachineDto> @@ -81,11 +81,11 @@ namespace Marechai.ApiClient.Consoles /// When receiving a 400 status code #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) { #nullable restore #else - public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) { #endif var requestInfo = ToGetRequestInformation(requestConfiguration); @@ -100,11 +100,11 @@ namespace Marechai.ApiClient.Consoles /// Configuration for the request such as headers, query parameters, and middleware options. #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) { #nullable restore #else - public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) { #endif var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); @@ -121,12 +121,22 @@ namespace Marechai.ApiClient.Consoles { return new global::Marechai.ApiClient.Consoles.ConsolesRequestBuilder(rawUrl, RequestAdapter); } + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + #pragma warning disable CS1591 + public partial class ConsolesRequestBuilderGetQueryParameters + #pragma warning restore CS1591 + { + [QueryParameter("skip")] + public int? Skip { get; set; } + [QueryParameter("take")] + public int? Take { get; set; } + } /// /// Configuration for the request such as headers, query parameters, and middleware options. /// [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] - public partial class ConsolesRequestBuilderGetRequestConfiguration : RequestConfiguration + public partial class ConsolesRequestBuilderGetRequestConfiguration : RequestConfiguration { } } diff --git a/Marechai.ApiClient/Consoles/Prototypes/Count/CountRequestBuilder.cs b/Marechai.ApiClient/Consoles/Prototypes/Count/CountRequestBuilder.cs new file mode 100644 index 00000000..d2a1445e --- /dev/null +++ b/Marechai.ApiClient/Consoles/Prototypes/Count/CountRequestBuilder.cs @@ -0,0 +1,91 @@ +// +#pragma warning disable CS0618 +using Marechai.ApiClient.Models; +using Microsoft.Kiota.Abstractions.Extensions; +using Microsoft.Kiota.Abstractions.Serialization; +using Microsoft.Kiota.Abstractions; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using System.Threading; +using System; +namespace Marechai.ApiClient.Consoles.Prototypes.Count +{ + /// + /// Builds and executes requests for operations under \consoles\prototypes\count + /// + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilder : BaseRequestBuilder + { + /// + /// Instantiates a new and sets the default values. + /// + /// Path parameters for the request + /// The request adapter to use to execute the requests. + public CountRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes/count", pathParameters) + { + } + /// + /// Instantiates a new and sets the default values. + /// + /// The raw URL to use for the request builder. + /// The request adapter to use to execute the requests. + public CountRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes/count", rawUrl) + { + } + /// A + /// Cancellation token to use when cancelling requests + /// Configuration for the request such as headers, query parameters, and middleware options. + /// When receiving a 400 status code +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public async Task GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + { +#nullable restore +#else + public async Task GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + { +#endif + var requestInfo = ToGetRequestInformation(requestConfiguration); + var errorMapping = new Dictionary> + { + { "400", global::Marechai.ApiClient.Models.ProblemDetails.CreateFromDiscriminatorValue }, + }; + return await RequestAdapter.SendPrimitiveAsync(requestInfo, errorMapping, cancellationToken).ConfigureAwait(false); + } + /// A + /// Configuration for the request such as headers, query parameters, and middleware options. +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER +#nullable enable + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + { +#nullable restore +#else + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + { +#endif + var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); + requestInfo.Configure(requestConfiguration); + requestInfo.Headers.TryAdd("Accept", "text/plain;q=0.9"); + return requestInfo; + } + /// + /// Returns a request builder with the provided arbitrary URL. Using this method means any other path or query parameters are ignored. + /// + /// A + /// The raw URL to use for the request builder. + public global::Marechai.ApiClient.Consoles.Prototypes.Count.CountRequestBuilder WithUrl(string rawUrl) + { + return new global::Marechai.ApiClient.Consoles.Prototypes.Count.CountRequestBuilder(rawUrl, RequestAdapter); + } + /// + /// Configuration for the request such as headers, query parameters, and middleware options. + /// + [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + public partial class CountRequestBuilderGetRequestConfiguration : RequestConfiguration + { + } + } +} +#pragma warning restore CS0618 diff --git a/Marechai.ApiClient/Consoles/Prototypes/PrototypesRequestBuilder.cs b/Marechai.ApiClient/Consoles/Prototypes/PrototypesRequestBuilder.cs index 7a745f54..67dfe511 100644 --- a/Marechai.ApiClient/Consoles/Prototypes/PrototypesRequestBuilder.cs +++ b/Marechai.ApiClient/Consoles/Prototypes/PrototypesRequestBuilder.cs @@ -1,5 +1,6 @@ // #pragma warning disable CS0618 +using Marechai.ApiClient.Consoles.Prototypes.Count; using Marechai.ApiClient.Models; using Microsoft.Kiota.Abstractions.Extensions; using Microsoft.Kiota.Abstractions.Serialization; @@ -17,12 +18,17 @@ namespace Marechai.ApiClient.Consoles.Prototypes [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] public partial class PrototypesRequestBuilder : BaseRequestBuilder { + /// The count property + public global::Marechai.ApiClient.Consoles.Prototypes.Count.CountRequestBuilder Count + { + get => new global::Marechai.ApiClient.Consoles.Prototypes.Count.CountRequestBuilder(PathParameters, RequestAdapter); + } /// /// Instantiates a new and sets the default values. /// /// Path parameters for the request /// The request adapter to use to execute the requests. - public PrototypesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes", pathParameters) + public PrototypesRequestBuilder(Dictionary pathParameters, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes{?skip*,take*}", pathParameters) { } /// @@ -30,7 +36,7 @@ namespace Marechai.ApiClient.Consoles.Prototypes /// /// The raw URL to use for the request builder. /// The request adapter to use to execute the requests. - public PrototypesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes", rawUrl) + public PrototypesRequestBuilder(string rawUrl, IRequestAdapter requestAdapter) : base(requestAdapter, "{+baseurl}/consoles/prototypes{?skip*,take*}", rawUrl) { } /// A List<global::Marechai.ApiClient.Models.MachineDto> @@ -39,11 +45,11 @@ namespace Marechai.ApiClient.Consoles.Prototypes /// When receiving a 400 status code #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task?> GetAsync(Action>? requestConfiguration = default, CancellationToken cancellationToken = default) { #nullable restore #else - public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) + public async Task> GetAsync(Action> requestConfiguration = default, CancellationToken cancellationToken = default) { #endif var requestInfo = ToGetRequestInformation(requestConfiguration); @@ -58,11 +64,11 @@ namespace Marechai.ApiClient.Consoles.Prototypes /// Configuration for the request such as headers, query parameters, and middleware options. #if NETSTANDARD2_1_OR_GREATER || NETCOREAPP3_1_OR_GREATER #nullable enable - public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action>? requestConfiguration = default) { #nullable restore #else - public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) + public RequestInformation ToGetRequestInformation(Action> requestConfiguration = default) { #endif var requestInfo = new RequestInformation(Method.GET, UrlTemplate, PathParameters); @@ -79,12 +85,22 @@ namespace Marechai.ApiClient.Consoles.Prototypes { return new global::Marechai.ApiClient.Consoles.Prototypes.PrototypesRequestBuilder(rawUrl, RequestAdapter); } + [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] + #pragma warning disable CS1591 + public partial class PrototypesRequestBuilderGetQueryParameters + #pragma warning restore CS1591 + { + [QueryParameter("skip")] + public int? Skip { get; set; } + [QueryParameter("take")] + public int? Take { get; set; } + } /// /// Configuration for the request such as headers, query parameters, and middleware options. /// [Obsolete("This class is deprecated. Please use the generic RequestConfiguration class generated by the generator.")] [global::System.CodeDom.Compiler.GeneratedCode("Kiota", "1.0.0")] - public partial class PrototypesRequestBuilderGetRequestConfiguration : RequestConfiguration + public partial class PrototypesRequestBuilderGetRequestConfiguration : RequestConfiguration { } } diff --git a/Marechai.ApiClient/kiota-lock.json b/Marechai.ApiClient/kiota-lock.json index 9461f787..545589ed 100644 --- a/Marechai.ApiClient/kiota-lock.json +++ b/Marechai.ApiClient/kiota-lock.json @@ -1,5 +1,5 @@ { - "descriptionHash": "DE8F8DE43202CD0088961BD423206A3DD0A796459AA0CBC25F38B876E309CA69E68277197810ABC0C9EE80930AC13381BB614334CF9677C87DCB8241BE192BA8", + "descriptionHash": "610A3BFE8E80FF8A221159EF3848C28F0B4A93F9AC132A014EBD8412519DE129511884F7D649B8706719C61F9581450DBE293CFDB8B1BD0EA0D159B5D021151A", "descriptionLocation": "../../../../../tmp/openapi.json", "lockFileVersion": "1.0.0", "kiotaVersion": "1.31.1", diff --git a/Marechai.Server/Controllers/ConsolesController.cs b/Marechai.Server/Controllers/ConsolesController.cs index d3f68449..1caa3ac3 100644 --- a/Marechai.Server/Controllers/ConsolesController.cs +++ b/Marechai.Server/Controllers/ConsolesController.cs @@ -25,6 +25,7 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Marechai.Data; using Marechai.Data.Dtos; @@ -52,7 +53,7 @@ public class ConsolesController(MarechaiContext context) : ControllerBase [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task GetMinimumYearAsync() => await context.Machines .Where(t => t.Type == MachineType.Console && - t.Introduced.HasValue && + t.Introduced.HasValue && !t.Prototype) .MinAsync(t => (int?)t.Introduced.Value.Year) ?? 0; @@ -62,7 +63,7 @@ public class ConsolesController(MarechaiContext context) : ControllerBase [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task GetMaximumYearAsync() => await context.Machines .Where(t => t.Type == MachineType.Console && - t.Introduced.HasValue && + t.Introduced.HasValue && !t.Prototype) .MaxAsync(t => (int?)t.Introduced.Value.Year) ?? 0; @@ -70,75 +71,135 @@ public class ConsolesController(MarechaiContext context) : ControllerBase [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public Task> GetConsolesByLetterAsync(char c) => context.Machines.Include(m => m.Company) - .Where(m => - m.Type == MachineType.Console && - EF.Functions.Like(m.Name, $"{c}%")) - .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) - .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)) - .Select(m => new MachineDto - { - Id = m.Id, - Name = m.Name, - Company = m.Company.Name, - Introduced = m.Introduced - }) - .ToListAsync(); + public Task> GetConsolesByLetterAsync(char c, [FromQuery] int? skip = null, + [FromQuery] int? take = null, + CancellationToken cancellationToken = default) + { + IQueryable ordered = context.Machines.Include(m => m.Company) + .Where(m => m.Type == MachineType.Console && + EF.Functions.Like(m.Name, $"{c}%")) + .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) + .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)); + + if(skip.HasValue) ordered = ordered.Skip(skip.Value); + if(take.HasValue) ordered = ordered.Take(take.Value); + + return ordered.Select(m => new MachineDto + { + Id = m.Id, + Name = m.Name, + Company = m.Company.Name, + Introduced = m.Introduced + }) + .ToListAsync(cancellationToken); + } + + [HttpGet("by-letter/{c}/count")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public Task GetConsolesByLetterCountAsync(char c, CancellationToken cancellationToken = default) => + context.Machines + .Where(m => m.Type == MachineType.Console && EF.Functions.Like(m.Name, $"{c}%")) + .CountAsync(cancellationToken); [HttpGet("by-year/{year:int}")] [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public Task> GetConsolesByYearAsync(int year) => context.Machines.Include(m => m.Company) - .Where(m => - m.Type == MachineType.Console && - m.Introduced != null && - m.Introduced.Value.Year == year) - .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) - .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)) - .Select(m => new MachineDto - { - Id = m.Id, - Name = m.Name, - Company = m.Company.Name, - Introduced = m.Introduced - }) - .ToListAsync(); + public Task> GetConsolesByYearAsync(int year, [FromQuery] int? skip = null, + [FromQuery] int? take = null, + CancellationToken cancellationToken = default) + { + IQueryable ordered = context.Machines.Include(m => m.Company) + .Where(m => m.Type == MachineType.Console && + m.Introduced != null && + m.Introduced.Value.Year == year) + .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) + .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)); + + if(skip.HasValue) ordered = ordered.Skip(skip.Value); + if(take.HasValue) ordered = ordered.Take(take.Value); + + return ordered.Select(m => new MachineDto + { + Id = m.Id, + Name = m.Name, + Company = m.Company.Name, + Introduced = m.Introduced + }) + .ToListAsync(cancellationToken); + } + + [HttpGet("by-year/{year:int}/count")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public Task GetConsolesByYearCountAsync(int year, CancellationToken cancellationToken = default) => + context.Machines + .Where(m => m.Type == MachineType.Console && + m.Introduced != null && + m.Introduced.Value.Year == year) + .CountAsync(cancellationToken); [HttpGet] [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public Task> GetConsolesAsync() => context.Machines.Include(m => m.Company) - .Where(m => m.Type == MachineType.Console) - .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) - .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)) - .Select(m => new MachineDto - { - Id = m.Id, - Name = m.Name, - Company = m.Company.Name, - Introduced = m.Introduced - }) - .ToListAsync(); + public Task> GetConsolesAsync([FromQuery] int? skip = null, [FromQuery] int? take = null, + CancellationToken cancellationToken = default) + { + IQueryable ordered = context.Machines.Include(m => m.Company) + .Where(m => m.Type == MachineType.Console) + .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) + .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)); + + if(skip.HasValue) ordered = ordered.Skip(skip.Value); + if(take.HasValue) ordered = ordered.Take(take.Value); + + return ordered.Select(m => new MachineDto + { + Id = m.Id, + Name = m.Name, + Company = m.Company.Name, + Introduced = m.Introduced + }) + .ToListAsync(cancellationToken); + } [HttpGet("prototypes")] [AllowAnonymous] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] - public Task> GetPrototypesAsync() => context.Machines.Include(m => m.Company) - .Where(m => m.Type == MachineType.Console && - m.Prototype) - .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) - .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)) - .Select(m => new MachineDto - { - Id = m.Id, - Name = m.Name, - Company = m.Company.Name, - Prototype = m.Prototype - }) - .ToListAsync(); + public Task> GetPrototypesAsync([FromQuery] int? skip = null, [FromQuery] int? take = null, + CancellationToken cancellationToken = default) + { + IQueryable ordered = context.Machines.Include(m => m.Company) + .Where(m => m.Type == MachineType.Console && m.Prototype) + .OrderBy(m => MarechaiContext.NaturalSortKey(m.Company.Name)) + .ThenBy(m => MarechaiContext.NaturalSortKey(m.Name)); + + if(skip.HasValue) ordered = ordered.Skip(skip.Value); + if(take.HasValue) ordered = ordered.Take(take.Value); + + return ordered.Select(m => new MachineDto + { + Id = m.Id, + Name = m.Name, + Company = m.Company.Name, + Prototype = m.Prototype + }) + .ToListAsync(cancellationToken); + } + + [HttpGet("prototypes/count")] + [AllowAnonymous] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public Task GetPrototypesCountAsync(CancellationToken cancellationToken = default) => + context.Machines + .Where(m => m.Type == MachineType.Console && m.Prototype) + .CountAsync(cancellationToken); [HttpGet("companies")] [AllowAnonymous] @@ -179,4 +240,4 @@ public class ConsolesController(MarechaiContext context) : ControllerBase Name = co.Name }) .ToListAsync(); -} \ No newline at end of file +} diff --git a/Marechai/Pages/Consoles/Search.razor b/Marechai/Pages/Consoles/Search.razor index 1d5fe330..858040f2 100644 --- a/Marechai/Pages/Consoles/Search.razor +++ b/Marechai/Pages/Consoles/Search.razor @@ -32,7 +32,7 @@ @inherits OwningComponentBase @inject IStringLocalizer L -@if(_consoles is null) +@if(!_initialized) {
@@ -56,17 +56,25 @@ } -@if(_consoles?.Count > 0) +@if(_total > 0) { - @string.Format(L["{0} videogame consoles found in the database."], _consoles.Count) - - @foreach(MachineDto console in _consoles) + @string.Format(L["{0} videogame consoles found in the database."], _total) +
+ + + + @console.Company @console.Name + + + +
+ @if(_loadingMore) { - - @console.Company @console.Name - +
+ +
} - +
} else { @@ -78,4 +86,4 @@ else { @L["There are no videogame consoles found introduced this year."] } -} \ No newline at end of file +} diff --git a/Marechai/Pages/Consoles/Search.razor.cs b/Marechai/Pages/Consoles/Search.razor.cs index bfd0a6d1..e09ca448 100644 --- a/Marechai/Pages/Consoles/Search.razor.cs +++ b/Marechai/Pages/Consoles/Search.razor.cs @@ -23,21 +23,33 @@ // Copyright © 2003-2026 Natalia Portillo *******************************************************************************/ +using System; using System.Collections.Generic; using System.Threading.Tasks; using Marechai.ApiClient.Models; using Microsoft.AspNetCore.Components; +using Microsoft.JSInterop; namespace Marechai.Pages.Consoles; -public partial class Search +public partial class Search : IAsyncDisposable { - char? _character; - List _consoles; - bool _loaded; - bool _showPrototypes; - string _lastStartingCharacter; - int? _lastYear; + const int _pageSize = 100; + readonly string _sentinelId = $"consoles-search-sentinel-{Guid.NewGuid():N}"; + readonly string _scrollerId = $"consoles-search-scroll-{Guid.NewGuid():N}"; + readonly List _consoles = []; + char? _character; + bool _initialized; + bool _loadingMore; + bool _observerRegistered; + bool _showPrototypes; + string _lastStartingCharacter; + int? _lastYear; + int _total; + DotNetObjectReference _selfRef; + + [Inject] + IJSRuntime JS { get; set; } [Parameter] public int? Year { get; set; } @@ -45,30 +57,29 @@ public partial class Search [Parameter] public string StartingCharacter { get; set; } + bool HasMore => _consoles.Count < _total; + protected override void OnParametersSet() { if(Year == _lastYear && StartingCharacter == _lastStartingCharacter) return; _lastYear = Year; _lastStartingCharacter = StartingCharacter; - _loaded = false; + _initialized = false; } protected override async Task OnAfterRenderAsync(bool firstRender) { - if(_loaded) return; - - _character = null; - _showPrototypes = false; - - if(StartingCharacter == "prototypes") + if(!_initialized) { - _showPrototypes = true; - _consoles = await Service.GetPrototypesAsync(); - } - else - { - if(!string.IsNullOrWhiteSpace(StartingCharacter) && StartingCharacter.Length == 1) + _character = null; + _showPrototypes = false; + _total = 0; + _consoles.Clear(); + + if(StartingCharacter == "prototypes") + _showPrototypes = true; + else if(!string.IsNullOrWhiteSpace(StartingCharacter) && StartingCharacter.Length == 1) { _character = StartingCharacter[0]; @@ -79,14 +90,117 @@ public partial class Search if(_character < '0' || _character > '9' && _character < 'A' || _character > 'Z') _character = null; } - if(_character.HasValue) _consoles = await Service.GetConsolesByLetterAsync(_character.Value); + // Stop the previous observer (if any) before swapping in a new + // batch — the sentinel/scroller IDs are stable per page instance, + // but a route-parameter change forces a fresh data load and the + // observer must be re-armed once the new sentinel has rendered. + await UnobserveAsync(); - if(Year.HasValue && _consoles is null) _consoles = await Service.GetConsolesByYearAsync(Year.Value); + // Fetch the total count + first page in parallel so the page is + // fully painted in one round-trip pair. + Task countTask = GetCurrentCountAsync(); + Task> firstPageTask = FetchBatchAsync(0, _pageSize); - _consoles ??= await Service.GetConsolesAsync(); + await Task.WhenAll(countTask, firstPageTask); + + _total = countTask.Result; + _consoles.AddRange(firstPageTask.Result); + _initialized = true; + + StateHasChanged(); + return; } - _loaded = true; - StateHasChanged(); + // Register the IntersectionObserver once the sentinel has been + // rendered. The observer keeps the same target reference, so this is + // a one-shot until UnobserveAsync clears the flag. + if(!_observerRegistered && HasMore) + { + _selfRef ??= DotNetObjectReference.Create(this); + + try + { + await JS.InvokeVoidAsync("marechaiInfiniteScroll.observe", _sentinelId, _selfRef, $"#{_scrollerId}", + "200px"); + _observerRegistered = true; + } + catch(JSDisconnectedException) + { + // Circuit gone — nothing to do. + } + } } -} \ No newline at end of file + + /// + /// Invoked by the IntersectionObserver in infinite-scroll.js when the + /// sentinel scrolls into view. Loads the next page, appends it to the + /// in-memory list, and re-renders. + /// + [JSInvokable] + public async Task OnSentinelVisibleAsync() + { + if(_loadingMore || !HasMore) return; + + _loadingMore = true; + StateHasChanged(); + + try + { + List next = await FetchBatchAsync(_consoles.Count, _pageSize); + _consoles.AddRange(next); + + // If the very last page just arrived, stop the observer so it + // doesn't keep firing as the user scrolls past the new tail. + if(!HasMore) await UnobserveAsync(); + } + finally + { + _loadingMore = false; + StateHasChanged(); + } + } + + Task GetCurrentCountAsync() + { + if(_showPrototypes) return Service.GetPrototypesCountAsync(); + + if(_character.HasValue) return Service.GetConsolesByLetterCountAsync(_character.Value); + + if(Year.HasValue) return Service.GetConsolesByYearCountAsync(Year.Value); + + return Service.GetConsolesCountAsync(); + } + + Task> FetchBatchAsync(int skip, int take) + { + if(_showPrototypes) return Service.GetPrototypesAsync(skip, take); + + if(_character.HasValue) return Service.GetConsolesByLetterAsync(_character.Value, skip, take); + + if(Year.HasValue) return Service.GetConsolesByYearAsync(Year.Value, skip, take); + + return Service.GetConsolesAsync(skip, take); + } + + async Task UnobserveAsync() + { + if(!_observerRegistered) return; + + try + { + await JS.InvokeVoidAsync("marechaiInfiniteScroll.unobserve", _sentinelId); + } + catch(JSDisconnectedException) + { + // Circuit gone; nothing to do. + } + + _observerRegistered = false; + } + + public async ValueTask DisposeAsync() + { + await UnobserveAsync(); + _selfRef?.Dispose(); + } +} diff --git a/Marechai/Services/ConsolesService.cs b/Marechai/Services/ConsolesService.cs index ffbc32c2..d8ad6780 100644 --- a/Marechai/Services/ConsolesService.cs +++ b/Marechai/Services/ConsolesService.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Marechai.ApiClient.Models; @@ -74,11 +75,16 @@ public class ConsolesService(Marechai.ApiClient.Client client) } } - public async Task> GetConsolesByLetterAsync(char c) + public async Task> GetConsolesByLetterAsync(char c, int? skip = null, int? take = null, + CancellationToken cancellationToken = default) { try { - List machines = await client.Consoles.ByLetter[c.ToString()].GetAsync(); + List machines = await client.Consoles.ByLetter[c.ToString()].GetAsync(config => + { + if(skip.HasValue) config.QueryParameters.Skip = skip.Value; + if(take.HasValue) config.QueryParameters.Take = take.Value; + }, cancellationToken); return machines ?? []; } @@ -88,11 +94,31 @@ public class ConsolesService(Marechai.ApiClient.Client client) } } - public async Task> GetConsolesByYearAsync(int year) + public async Task GetConsolesByLetterCountAsync(char c, CancellationToken cancellationToken = default) { try { - List machines = await client.Consoles.ByYear[year].GetAsync(); + int? count = await client.Consoles.ByLetter[c.ToString()].Count + .GetAsync(cancellationToken: cancellationToken); + + return count ?? 0; + } + catch + { + return 0; + } + } + + public async Task> GetConsolesByYearAsync(int year, int? skip = null, int? take = null, + CancellationToken cancellationToken = default) + { + try + { + List machines = await client.Consoles.ByYear[year].GetAsync(config => + { + if(skip.HasValue) config.QueryParameters.Skip = skip.Value; + if(take.HasValue) config.QueryParameters.Take = take.Value; + }, cancellationToken); return machines ?? []; } @@ -102,11 +128,30 @@ public class ConsolesService(Marechai.ApiClient.Client client) } } - public async Task> GetConsolesAsync() + public async Task GetConsolesByYearCountAsync(int year, CancellationToken cancellationToken = default) { try { - List machines = await client.Consoles.GetAsync(); + int? count = await client.Consoles.ByYear[year].Count.GetAsync(cancellationToken: cancellationToken); + + return count ?? 0; + } + catch + { + return 0; + } + } + + public async Task> GetConsolesAsync(int? skip = null, int? take = null, + CancellationToken cancellationToken = default) + { + try + { + List machines = await client.Consoles.GetAsync(config => + { + if(skip.HasValue) config.QueryParameters.Skip = skip.Value; + if(take.HasValue) config.QueryParameters.Take = take.Value; + }, cancellationToken); return machines ?? []; } @@ -116,11 +161,16 @@ public class ConsolesService(Marechai.ApiClient.Client client) } } - public async Task> GetPrototypesAsync() + public async Task> GetPrototypesAsync(int? skip = null, int? take = null, + CancellationToken cancellationToken = default) { try { - List machines = await client.Consoles.Prototypes.GetAsync(); + List machines = await client.Consoles.Prototypes.GetAsync(config => + { + if(skip.HasValue) config.QueryParameters.Skip = skip.Value; + if(take.HasValue) config.QueryParameters.Take = take.Value; + }, cancellationToken); return machines ?? []; } @@ -130,6 +180,20 @@ public class ConsolesService(Marechai.ApiClient.Client client) } } + public async Task GetPrototypesCountAsync(CancellationToken cancellationToken = default) + { + try + { + int? count = await client.Consoles.Prototypes.Count.GetAsync(cancellationToken: cancellationToken); + + return count ?? 0; + } + catch + { + return 0; + } + } + public async Task> GetCompaniesAsync() { try