Created At |
@@ -63,7 +69,7 @@
Actions |
-
+
|
|
diff --git a/AdminUi/src/AdminUi/ClientApp/src/app/components/client/client-list/client-list.component.ts b/AdminUi/src/AdminUi/ClientApp/src/app/components/client/client-list/client-list.component.ts
index f476381251..670f8a69ad 100644
--- a/AdminUi/src/AdminUi/ClientApp/src/app/components/client/client-list/client-list.component.ts
+++ b/AdminUi/src/AdminUi/ClientApp/src/app/components/client/client-list/client-list.component.ts
@@ -4,7 +4,7 @@ import { MatSnackBar } from "@angular/material/snack-bar";
import { SelectionModel } from "@angular/cdk/collections";
import { Router } from "@angular/router";
import { MatDialog } from "@angular/material/dialog";
-import { ClientDTO, ClientServiceService } from "src/app/services/client-service/client-service";
+import { ClientOverview, ClientServiceService } from "src/app/services/client-service/client-service";
import { PagedHttpResponseEnvelope } from "src/app/utils/paged-http-response-envelope";
import { forkJoin, Observable } from "rxjs";
import { ConfirmationDialogComponent } from "../../shared/confirmation-dialog/confirmation-dialog.component";
@@ -18,13 +18,13 @@ export class ClientListComponent {
@ViewChild(MatPaginator) public paginator!: MatPaginator;
public header: string;
public headerDescription: string;
- public clients: ClientDTO[];
+ public clients: ClientOverview[];
public totalRecords: number;
public pageSize: number;
public pageIndex: number;
public loading = false;
- public selection = new SelectionModel(true, []);
- public displayedColumns: string[] = ["select", "clientId", "displayName", "defaultTier", "createdAt", "actions"];
+ public selection = new SelectionModel(true, []);
+ public displayedColumns: string[] = ["select", "clientId", "displayName", "defaultTier", "numberOfIdentities", "createdAt", "actions"];
public constructor(
private readonly router: Router,
@@ -47,9 +47,9 @@ export class ClientListComponent {
public getPagedData(): void {
this.loading = true;
- this.selection = new SelectionModel(true, []);
+ this.selection = new SelectionModel(true, []);
this.clientService.getClients(this.pageIndex, this.pageSize).subscribe({
- next: (data: PagedHttpResponseEnvelope) => {
+ next: (data: PagedHttpResponseEnvelope) => {
this.clients = data.result;
if (data.pagination) {
this.totalRecords = data.pagination.totalRecords!;
@@ -143,7 +143,7 @@ export class ClientListComponent {
this.selection.select(...this.clients);
}
- public checkboxLabel(index?: number, row?: ClientDTO): string {
+ public checkboxLabel(index?: number, row?: ClientOverview): string {
if (!row || !index) {
return `${this.isAllSelected() ? "deselect" : "select"} all`;
}
diff --git a/AdminUi/src/AdminUi/ClientApp/src/app/services/client-service/client-service.ts b/AdminUi/src/AdminUi/ClientApp/src/app/services/client-service/client-service.ts
index ef92fd2d59..665b162b65 100644
--- a/AdminUi/src/AdminUi/ClientApp/src/app/services/client-service/client-service.ts
+++ b/AdminUi/src/AdminUi/ClientApp/src/app/services/client-service/client-service.ts
@@ -14,16 +14,16 @@ export class ClientServiceService {
this.apiUrl = `${environment.apiUrl}/Clients`;
}
- public getClientById(id: string): Observable> {
- return this.http.get>(`${this.apiUrl}/${id}`);
+ public getClientById(id: string): Observable> {
+ return this.http.get>(`${this.apiUrl}/${id}`);
}
- public getClients(pageNumber: number, pageSize: number): Observable> {
+ public getClients(pageNumber: number, pageSize: number): Observable> {
const httpOptions = {
params: new HttpParams().set("PageNumber", pageNumber + 1).set("PageSize", pageSize)
};
- return this.http.get>(this.apiUrl, httpOptions);
+ return this.http.get>(this.apiUrl, httpOptions);
}
public createClient(client: Client): Observable> {
@@ -38,16 +38,17 @@ export class ClientServiceService {
return this.http.patch>(`${this.apiUrl}/${clientId}/ChangeSecret`, request);
}
- public updateClient(clientId: string, request: UpdateClientRequest): Observable> {
- return this.http.patch>(`${this.apiUrl}/${clientId}`, request);
+ public updateClient(clientId: string, request: UpdateClientRequest): Observable> {
+ return this.http.patch>(`${this.apiUrl}/${clientId}`, request);
}
}
-export interface ClientDTO {
+export interface ClientOverview {
clientId: string;
displayName?: string;
defaultTier: string;
createdAt: Date;
+ numberOfIdentities: number;
}
export interface Client {
diff --git a/AdminUi/src/AdminUi/Controllers/ClientsController.cs b/AdminUi/src/AdminUi/Controllers/ClientsController.cs
index 36a444b6cd..e378d64b22 100644
--- a/AdminUi/src/AdminUi/Controllers/ClientsController.cs
+++ b/AdminUi/src/AdminUi/Controllers/ClientsController.cs
@@ -1,16 +1,18 @@
-using Backbone.Modules.Devices.Application.Clients.Commands.ChangeClientSecret;
+using AdminUi.Infrastructure.DTOs;
+using AdminUi.Infrastructure.Persistence.Database;
+using Backbone.Modules.Devices.Application.Clients.Commands.ChangeClientSecret;
using Backbone.Modules.Devices.Application.Clients.Commands.CreateClient;
using Backbone.Modules.Devices.Application.Clients.Commands.DeleteClient;
using Backbone.Modules.Devices.Application.Clients.Commands.UpdateClient;
using Backbone.Modules.Devices.Application.Clients.DTOs;
using Backbone.Modules.Devices.Application.Clients.Queries.GetClient;
-using Backbone.Modules.Devices.Application.Clients.Queries.ListClients;
using Enmeshed.BuildingBlocks.API;
using Enmeshed.BuildingBlocks.API.Mvc;
using Enmeshed.BuildingBlocks.API.Mvc.ControllerAttributes;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
namespace AdminUi.Controllers;
@@ -18,15 +20,20 @@ namespace AdminUi.Controllers;
[Authorize("ApiKey")]
public class ClientsController : ApiControllerBase
{
- public ClientsController(IMediator mediator) : base(mediator) { }
+ private readonly AdminUiDbContext _adminUiDbContext;
+
+ public ClientsController(IMediator mediator, AdminUiDbContext adminUiDbContext) : base(mediator)
+ {
+ _adminUiDbContext = adminUiDbContext;
+ }
[HttpGet]
- [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task GetAllClients(CancellationToken cancellationToken)
{
- var clients = await _mediator.Send(new ListClientsQuery(), cancellationToken);
- return Ok(clients);
+ var clientOverviews = await _adminUiDbContext.ClientOverviews.ToListAsync(cancellationToken);
+ return Ok(clientOverviews);
}
[HttpGet("{id}")]
diff --git a/AdminUi/test/AdminUi.Tests.Integration/API/ClientsApi.cs b/AdminUi/test/AdminUi.Tests.Integration/API/ClientsApi.cs
index d93b67fbd6..aa3319626f 100644
--- a/AdminUi/test/AdminUi.Tests.Integration/API/ClientsApi.cs
+++ b/AdminUi/test/AdminUi.Tests.Integration/API/ClientsApi.cs
@@ -7,9 +7,9 @@ public class ClientsApi : BaseApi
{
public ClientsApi(IOptions httpConfiguration, HttpClientFactory factory) : base(httpConfiguration, factory) { }
- public async Task>> GetAllClients(RequestConfiguration requestConfiguration)
+ public async Task>> GetAllClients(RequestConfiguration requestConfiguration)
{
- return await Get>("/Clients", requestConfiguration);
+ return await Get>("/Clients", requestConfiguration);
}
public async Task> GetClient(string clientId, RequestConfiguration requestConfiguration)
diff --git a/AdminUi/test/AdminUi.Tests.Integration/Features/Clients/GET.feature b/AdminUi/test/AdminUi.Tests.Integration/Features/Clients/GET.feature
index 2b7916e7d3..071c48d364 100644
--- a/AdminUi/test/AdminUi.Tests.Integration/Features/Clients/GET.feature
+++ b/AdminUi/test/AdminUi.Tests.Integration/Features/Clients/GET.feature
@@ -1,9 +1,9 @@
-@Integration
+@Integration
Feature: GET Clients
-User requests a Client List
+User requests a Client Overview List
-Scenario: Requesting an Client List
+Scenario: Requesting a list of existing Clients
When a GET request is sent to the /Clients endpoint
Then the response status code is 200 (OK)
And the response contains a paginated list of Clients
diff --git a/AdminUi/test/AdminUi.Tests.Integration/Models/ClientOverviewDTO.cs b/AdminUi/test/AdminUi.Tests.Integration/Models/ClientOverviewDTO.cs
new file mode 100644
index 0000000000..e9207ab67a
--- /dev/null
+++ b/AdminUi/test/AdminUi.Tests.Integration/Models/ClientOverviewDTO.cs
@@ -0,0 +1,8 @@
+namespace AdminUi.Tests.Integration.Models;
+public class ClientOverviewDTO
+{
+ public string ClientId { get; set; }
+ public string DisplayName { get; set; }
+ public string DefaultTier { get; set; }
+ public int NumberOfIdentities { get; set; }
+}
diff --git a/AdminUi/test/AdminUi.Tests.Integration/StepDefinitions/ClientsStepDefinitions.cs b/AdminUi/test/AdminUi.Tests.Integration/StepDefinitions/ClientsStepDefinitions.cs
index f084eef76c..7f7bc87502 100644
--- a/AdminUi/test/AdminUi.Tests.Integration/StepDefinitions/ClientsStepDefinitions.cs
+++ b/AdminUi/test/AdminUi.Tests.Integration/StepDefinitions/ClientsStepDefinitions.cs
@@ -18,7 +18,7 @@ public class ClientsStepDefinitions : BaseStepDefinitions
private string _tierId;
private string _tier1Id;
private string _tier2Id;
- private HttpResponse>? _getClientsResponse;
+ private HttpResponse>? _getClientsResponse;
private readonly HttpResponse? _getClientResponse;
private readonly HttpResponse? _createClientResponse;
private HttpResponse? _changeClientSecretResponse;