diff --git a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs index d8b00ebc..5402ba05 100644 --- a/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs +++ b/EnvelopeGenerator.Application/Services/EnvelopeTypeService.cs @@ -1,19 +1,31 @@ using AutoMapper; using DigitalData.Core.Application; -using Microsoft.Extensions.Localization; using EnvelopeGenerator.Application.Contracts; using EnvelopeGenerator.Application.DTOs; using EnvelopeGenerator.Domain.Entities; using EnvelopeGenerator.Infrastructure.Contracts; -using EnvelopeGenerator.Application.Resources; +using Microsoft.Extensions.Caching.Memory; +using DigitalData.Core.DTO; +using System.Collections.Generic; +using Microsoft.Extensions.Logging; namespace EnvelopeGenerator.Application.Services { public class EnvelopeTypeService : BasicCRUDService, IEnvelopeTypeService { - public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper) + private static readonly Guid CacheKey = Guid.NewGuid(); + + private readonly IMemoryCache _cache; + + public EnvelopeTypeService(IEnvelopeTypeRepository repository, IMapper mapper, IMemoryCache cache) : base(repository, mapper) { + _cache = cache; } + + public override async Task>> ReadAllAsync() + => await _cache.GetOrCreateAsync(CacheKey, async entry => await base.ReadAllAsync()) + ?? Result.Fail>().Notice(LogLevel.Error, Flag.NotFound, "No cached envelope types are available in the database. If you have added any envelope types after the server started, please restart the server."); + } } \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts index 869ce43e..c23f1870 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/app.config.ts @@ -1,4 +1,4 @@ -import { ApplicationConfig } from '@angular/core'; +import { ApplicationConfig, APP_INITIALIZER } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideClientHydration } from '@angular/platform-browser'; @@ -8,6 +8,7 @@ import { UrlService } from './services/url.service'; import { API_URL } from './tokens/index' import { HTTP_INTERCEPTORS, provideHttpClient, withFetch } from '@angular/common/http'; import { HttpRequestInterceptor } from './http.interceptor'; +import { ConfigurationService } from './services/configuration.service'; export const appConfig: ApplicationConfig = { providers: [ @@ -29,6 +30,12 @@ export const appConfig: ApplicationConfig = { provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true + }, + { + provide: APP_INITIALIZER, + useFactory: (configService: ConfigurationService) => async () => await configService.ngOnInit(), + deps: [ConfigurationService], + multi: true } ] }; \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts index b0e1ef84..43a8d6bf 100644 --- a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/components/envelope-table/envelope-table.component.ts @@ -9,6 +9,7 @@ import { MatInputModule } from '@angular/material/input'; import { MatFormFieldModule } from '@angular/material/form-field'; import {MatPaginator, MatPaginatorModule} from '@angular/material/paginator'; import {MatSort, MatSortModule} from '@angular/material/sort'; +import { ConfigurationService } from '../../services/configuration.service'; @Component({ selector: 'app-envelope-table', @@ -41,7 +42,7 @@ export class EnvelopeTableComponent implements AfterViewInit { }, 'type': { header: 'Type', - field: (element: any) => element.envelope.contractType + field: (element: any) => this.config.envelopeTypeTitles[element.envelope.contractType - 1] }, 'privateMessage': { header: 'Private Message', @@ -65,7 +66,7 @@ export class EnvelopeTableComponent implements AfterViewInit { dataSource = new MatTableDataSource(); - constructor(private erService: EnvelopeReceiverService) { + constructor(private erService: EnvelopeReceiverService, private config: ConfigurationService) { this.dataSource.filterPredicate = (data: any, filter: string): boolean => { const dataStr = Object.values(data as { [key: string]: any }).reduce((currentTerm, key) => { return currentTerm + (key ? key.toString().toLowerCase() : ''); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts new file mode 100644 index 00000000..ec51dfa5 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { ConfigurationService } from './configuration.service'; + +describe('ConfigurationService', () => { + let service: ConfigurationService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(ConfigurationService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts new file mode 100644 index 00000000..1f2b41e5 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/ClientApp/envelope-generator-ui/src/app/services/configuration.service.ts @@ -0,0 +1,37 @@ +import { Injectable, OnInit, inject } from '@angular/core'; +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Observable, firstValueFrom } from 'rxjs'; +import { API_URL } from '../tokens/index'; + +@Injectable({ + providedIn: 'root' +}) +export class ConfigurationService implements OnInit { + + protected url: string; + + private _envelopeTypes! : any[]; + + private _envelopeTypeTitles! : any[]; + + constructor(private http: HttpClient) { + const api_url = inject(API_URL); + this.url = `${api_url}`; + } + + async ngOnInit(): Promise { + const envelopeTypes$: Observable = this.http.get(`${this.url}/EnvelopeType`) + envelopeTypes$.subscribe({next: res => { + this._envelopeTypes = res; + this._envelopeTypeTitles = res.map(e => e.title); + }}); + } + + public get envelopeTypes() { + return this._envelopeTypes; + } + + public get envelopeTypeTitles() { + return this._envelopeTypeTitles; + } +} \ No newline at end of file diff --git a/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs new file mode 100644 index 00000000..daacd703 --- /dev/null +++ b/EnvelopeGenerator.GeneratorAPI/Controllers/EnvelopeTypeController.cs @@ -0,0 +1,43 @@ +using DigitalData.Core.DTO; +using EnvelopeGenerator.Application.Contracts; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System.Net.Mail; +using System.Security.Cryptography.Xml; + +namespace EnvelopeGenerator.GeneratorAPI.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class EnvelopeTypeController : ControllerBase + { + private readonly ILogger _logger; + private readonly IEnvelopeTypeService _service; + + public EnvelopeTypeController(ILogger logger, IEnvelopeTypeService service) + { + _logger = logger; + _service = service; + } + + [HttpGet] + public async Task GetAllAsync() + { + try + { + return await _service.ReadAllAsync().ThenAsync( + Success: Ok, + Fail: IActionResult (msg, ntc) => + { + _logger.LogNotice(ntc); + return ntc.HasFlag(Flag.NotFound) ? NotFound() : StatusCode(StatusCodes.Status500InternalServerError); + }); + } + catch (Exception ex) + { + _logger.LogError(ex, "{Message}", ex.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + } +} \ No newline at end of file