diff --git a/backend/Tnsu.ApprovalRoute.Api/Controllers/RequestTypeListsController.cs b/backend/Tnsu.ApprovalRoute.Api/Controllers/RequestTypeListsController.cs index 2e54a01..6a6314f 100644 --- a/backend/Tnsu.ApprovalRoute.Api/Controllers/RequestTypeListsController.cs +++ b/backend/Tnsu.ApprovalRoute.Api/Controllers/RequestTypeListsController.cs @@ -20,10 +20,14 @@ public sealed class RequestTypeListsController(ListPartitionService service) : C /// заявкам сразу во всех партициях (архив + текущая) любого типа, не нужно /// запрашивать серию по каждому типу отдельно. /// + /// + /// Необязательный фильтр по заголовку партиции (Title списка SharePoint), + /// без учёта регистра, по вхождению подстроки. + /// [HttpGet("lists")] [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)] - public async Task ListAll(CancellationToken ct) => - (await service.ListAllAsync(ct)).ToActionResult(); + public async Task ListAll([FromQuery] string? title, CancellationToken ct) => + (await service.ListAllAsync(title, ct)).ToActionResult(); /// Вся серия партиций одного типа заявок (архив + текущая), от первой к последней. [HttpGet("{requestTypeId:int}/lists")] diff --git a/backend/Tnsu.ApprovalRoute.Application/ListPartitioning/ListPartitionService.cs b/backend/Tnsu.ApprovalRoute.Application/ListPartitioning/ListPartitionService.cs index f7862c9..9a5c12a 100644 --- a/backend/Tnsu.ApprovalRoute.Application/ListPartitioning/ListPartitionService.cs +++ b/backend/Tnsu.ApprovalRoute.Application/ListPartitioning/ListPartitionService.cs @@ -78,7 +78,12 @@ public sealed class ListPartitionService( /// адресов один раз, а не по одному запросу на тип. Типы без настроенного /// списка SharePoint в ответ не попадают — искать там всё равно нечего. /// - public async Task>> ListAllAsync(CancellationToken cancellationToken) + /// + /// Необязательный фильтр по заголовку партиции (Title списка SharePoint), + /// без учёта регистра, по вхождению подстроки. null — фильтр не применяется. + /// + public async Task>> ListAllAsync( + string? title, CancellationToken cancellationToken) { var requestTypes = await db.RequestTypes .Where(x => x.ListId != null && x.SiteUrl != null) @@ -88,6 +93,14 @@ public sealed class ListPartitionService( foreach (var requestType in requestTypes) { var partitions = await BuildSeriesAsync(requestType, cancellationToken); + + if (!string.IsNullOrWhiteSpace(title)) + partitions = partitions + .Where(x => x.Title is not null && x.Title.Contains(title, StringComparison.OrdinalIgnoreCase)) + .ToList(); + + if (partitions.Count == 0) continue; + result.Add(new RequestTypeListSeriesDto(requestType.Id, partitions)); } diff --git a/frontend/src/webparts/approvalAdmin/services/api.ts b/frontend/src/webparts/approvalAdmin/services/api.ts index 05b04de..1c041f1 100644 --- a/frontend/src/webparts/approvalAdmin/services/api.ts +++ b/frontend/src/webparts/approvalAdmin/services/api.ts @@ -72,8 +72,8 @@ export class ApprovalRouteApi { // ListPartitionService.ListAllAsync) — для дашборда (счётчик партиций) и // портала, которому нужен весь список адресов разом, а не по одному запросу // на тип. - listsAll: (): Promise => - this.http.get('/api/request-types/lists'), + listsAll: (title?: string): Promise => + this.http.get('/api/request-types/lists', { title }), // Вся серия партиций ОДНОГО типа заявки (архив + текущая) — нужна экрану // редактирования заявок: заявка может лежать в любой из них, не только в