diff --git a/backend/LfClassicData/DataServiceKernel.cs b/backend/LfClassicData/DataServiceKernel.cs index 3d67e729e..196e87253 100644 --- a/backend/LfClassicData/DataServiceKernel.cs +++ b/backend/LfClassicData/DataServiceKernel.cs @@ -1,9 +1,4 @@ using LfClassicData.Configuration; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -48,42 +43,4 @@ public static MongoClientSettings BuildMongoClientSettings(IServiceProvider prov cb.Subscribe(new DiagnosticsActivityEventSubscriber(new() { CaptureCommandText = true })); return mongoSettings; } - - public static IEndpointConventionBuilder MapLfClassicApi(this IEndpointRouteBuilder builder) - { - var group = builder.MapGroup("/api/lfclassic/{projectCode}"); - group.MapGet("/writingSystems", - (string projectCode, [FromServices] ILexboxApiProvider provider) => - { - var api = provider.GetProjectApi(projectCode); - return api.GetWritingSystems(); - }); - group.MapGet("/entries", - (string projectCode, - [FromServices] ILexboxApiProvider provider, - int count = 1000, - int offset = 0 - ) => - { - var api = provider.GetProjectApi(projectCode); - return api.GetEntries(new QueryOptions(SortOptions.Default, null, count, offset)); - }); - group.MapGet("/entries/{search}", - (string projectCode, - [FromServices] ILexboxApiProvider provider, - string search, - int count = 1000, - int offset = 0) => - { - var api = provider.GetProjectApi(projectCode); - return api.SearchEntries(search, new QueryOptions(SortOptions.Default, null, count, offset)); - }); - group.MapGet("/entry/{id:Guid}", - (string projectCode, Guid id, [FromServices] ILexboxApiProvider provider) => - { - var api = provider.GetProjectApi(projectCode); - return api.GetEntry(id); - }); - return group; - } } diff --git a/backend/LfClassicData/LfClassicRoutes.cs b/backend/LfClassicData/LfClassicRoutes.cs new file mode 100644 index 000000000..c52ee01fc --- /dev/null +++ b/backend/LfClassicData/LfClassicRoutes.cs @@ -0,0 +1,81 @@ +using System.Text.Json; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Routing; +using MiniLcm; + +namespace LfClassicData; + +public static class LfClassicRoutes +{ + public static IEndpointConventionBuilder MapLfClassicApi(this IEndpointRouteBuilder builder) + { + var group = builder.MapGroup("/api/lfclassic/{projectCode}"); + group.MapGet("/writingSystems", + ([FromRoute] string projectCode, [FromServices] ILexboxApiProvider provider) => + { + var api = provider.GetProjectApi(projectCode); + return api.GetWritingSystems(); + }); + group.MapGet("/entries", + ([FromRoute] string projectCode, + [FromServices] ILexboxApiProvider provider, + [AsParameters] ClassicQueryOptions options + ) => + { + var api = provider.GetProjectApi(projectCode); + return api.GetEntries(options.ToQueryOptions()); + }); + group.MapGet("/entries/{search}", + ([FromRoute] string projectCode, + [FromServices] ILexboxApiProvider provider, + [FromRoute] string search, + [AsParameters] ClassicQueryOptions options) => + { + var api = provider.GetProjectApi(projectCode); + return api.SearchEntries(search, options.ToQueryOptions()); + }); + group.MapGet("/entry/{id:Guid}", + ([FromRoute] string projectCode, Guid id, [FromServices] ILexboxApiProvider provider) => + { + var api = provider.GetProjectApi(projectCode); + return api.GetEntry(id); + }); + return group; + } + + private class ClassicQueryOptions + { + public QueryOptions ToQueryOptions() + { + ExemplarOptions? exemplarOptions = string.IsNullOrEmpty(ExemplarValue) || ExemplarWritingSystem is null + ? null + : new (ExemplarValue, ExemplarWritingSystem.Value); + var sortField = Enum.TryParse(SortField, true, out var field) ? field : SortOptions.Default.Field; + return new QueryOptions(new SortOptions(sortField, + SortWritingSystem ?? SortOptions.Default.WritingSystem, + Ascending ?? SortOptions.Default.Ascending), + exemplarOptions, + Count ?? QueryOptions.Default.Count, + Offset ?? QueryOptions.Default.Offset); + } + + public string? SortField { get; set; } + + public WritingSystemId? SortWritingSystem { get; set; } + + [FromQuery] + public bool? Ascending { get; set; } + + [FromQuery] + public string? ExemplarValue { get; set; } + public WritingSystemId? ExemplarWritingSystem { get; set; } + + [FromQuery] + public int? Count { get; set; } + + [FromQuery] + public int? Offset { get; set; } + } +} diff --git a/frontend/src/routes/(authenticated)/project/[project_code]/viewer/lfClassicLexboxApi.ts b/frontend/src/routes/(authenticated)/project/[project_code]/viewer/lfClassicLexboxApi.ts index f1f911e23..64dc0c4ca 100644 --- a/frontend/src/routes/(authenticated)/project/[project_code]/viewer/lfClassicLexboxApi.ts +++ b/frontend/src/routes/(authenticated)/project/[project_code]/viewer/lfClassicLexboxApi.ts @@ -19,19 +19,42 @@ export class LfClassicLexboxApi implements LexboxApi { } async GetEntries(_options: QueryOptions | undefined): Promise { - const result = await fetch(`/api/lfclassic/${this.projectCode}/entries?order=desc&count=100`); + //todo pass query options into query + const result = await fetch(`/api/lfclassic/${this.projectCode}/entries${this.toQueryParams(_options)}`); return (await result.json()) as IEntry[]; } - CreateWritingSystem(_type: WritingSystemType, _writingSystem: WritingSystem): Promise { - throw new Error('Method not implemented.'); + async SearchEntries(_query: string, _options: QueryOptions | undefined): Promise { + //todo pass query options into query + const result = await fetch(`/api/lfclassic/${this.projectCode}/entries/${encodeURIComponent(_query)}${this.toQueryParams(_options)}`); + return (await result.json()) as IEntry[]; } - UpdateWritingSystem(_wsId: string, _type: WritingSystemType, _update: JsonPatch): Promise { + private toQueryParams(options: QueryOptions | undefined): string { + + if (!options) return ''; + /* eslint-disable @typescript-eslint/no-unsafe-assignment */ + const asc = options.order.ascending ?? true; + const params = new URLSearchParams({ + SortField: options.order.field, + SortWritingSystem: options.order.writingSystem, + Ascending: asc ? 'true' : 'false', + Count: options.count.toString(), + Offset: options.offset.toString() + }); + if (options.exemplar) { + params.set('ExemplarValue', options.exemplar.value); + params.set('ExemplarWritingSystem', options.exemplar.writingSystem); + } + /* eslint-enable @typescript-eslint/no-unsafe-assignment */ + return '?' + params.toString(); + } + + CreateWritingSystem(_type: WritingSystemType, _writingSystem: WritingSystem): Promise { throw new Error('Method not implemented.'); } - SearchEntries(_query: string, _options: QueryOptions | undefined): Promise { + UpdateWritingSystem(_wsId: string, _type: WritingSystemType, _update: JsonPatch): Promise { throw new Error('Method not implemented.'); }