From 13c1a2a0b0e0f71d8a9577813a14be1dc5ec7371 Mon Sep 17 00:00:00 2001 From: Valentin Mihai Date: Thu, 6 Jun 2024 18:33:18 +0300 Subject: [PATCH] RED-9201 - added all mapping actions --- ...it-component-mapping-dialog.component.html | 7 +- ...edit-component-mapping-dialog.component.ts | 58 +++++---- .../component-mappings-screen.component.html | 22 +--- .../component-mappings-screen.component.ts | 39 ++++-- .../component-mappings.service.ts | 116 ++++++++---------- libs/common-ui | 2 +- .../component-mapping-list.model.ts | 16 +++ .../component-mapping.model.ts | 24 ---- .../component-mappings/component-mapping.ts | 36 +++++- .../src/lib/component-mappings/index.ts | 2 +- 10 files changed, 166 insertions(+), 156 deletions(-) create mode 100644 libs/red-domain/src/lib/component-mappings/component-mapping-list.model.ts delete mode 100644 libs/red-domain/src/lib/component-mappings/component-mapping.model.ts diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html index bb918f40a..a43c42fcf 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.html @@ -16,16 +16,15 @@ /> -
+
{{ data.mapping.version }} -
- +
@@ -42,7 +41,7 @@
- + {{ translations[type] | translate }} diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts index 2a9a4a488..680565a72 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { CircleButtonComponent, IconButtonComponent, IconButtonTypes, IqserDialogComponent, IqserUploadFileModule } from '@iqser/common-ui'; import { FileAttributeEncodingTypes, IComponentMapping } from '@red/domain'; import { FormBuilder, ReactiveFormsModule, UntypedFormGroup, Validators } from '@angular/forms'; @@ -9,11 +9,20 @@ import { MatDialogClose } from '@angular/material/dialog'; import { MatOption } from '@angular/material/autocomplete'; import { MatSelect } from '@angular/material/select'; import { fileAttributeEncodingTypesTranslations } from '@translations/file-attribute-encoding-types-translations'; +import { firstValueFrom } from 'rxjs'; +import { ComponentMappingsService } from '@services/entity-services/component-mappings.service'; interface DialogData { + dossierTemplateId: string; mapping: IComponentMapping; } -interface DialogResult {} +interface DialogResult { + id: string; + name: string; + file: Blob; + encoding: string; + delimiter: string; +} @Component({ templateUrl: './add-edit-component-mapping-dialog.component.html', @@ -33,37 +42,38 @@ interface DialogResult {} IconButtonComponent, ], }) -export class AddEditComponentMappingDialogComponent extends IqserDialogComponent< - AddEditComponentMappingDialogComponent, - DialogData, - DialogResult -> { +export class AddEditComponentMappingDialogComponent + extends IqserDialogComponent + implements OnInit +{ protected readonly encodingTypeOptions = Object.keys(FileAttributeEncodingTypes); protected readonly translations = fileAttributeEncodingTypesTranslations; protected readonly iconButtonTypes = IconButtonTypes; + activeFile: File; form!: UntypedFormGroup; - constructor(private readonly _formBuilder: FormBuilder) { + constructor( + private readonly _formBuilder: FormBuilder, + private readonly _componentMappingService: ComponentMappingsService, + ) { super(); - this.form = this.#getForm(); } - get file() { - return this.form.get('file').value; + async ngOnInit() { + if (this.data.mapping?.fileName) { + this.activeFile = { name: this.data.mapping.fileName } as File; + const fileContent = await firstValueFrom( + this._componentMappingService.getComponentMappingFile(this.data.dossierTemplateId, this.data.mapping.id), + ); + const file = new Blob([fileContent], { type: 'text/csv' }); + this.form.get('file').setValue(file); + this.initialFormValue = this.form.getRawValue(); + } } - fileChanged(file: Blob | null) { - if (file) { - const fileReader = new FileReader(); - fileReader.onload = () => { - const binaryContent = fileReader.result; - this.form.get('file').setValue(binaryContent); - }; - fileReader.readAsBinaryString(file as Blob); - } else { - this.form.controls['file'].setValue(''); - } + fileChanged(file: Blob) { + this.form.get('file').setValue(file); } save() { @@ -73,9 +83,9 @@ export class AddEditComponentMappingDialogComponent extends IqserDialogComponent #getForm(): UntypedFormGroup { return this._formBuilder.group({ name: [this.data?.mapping?.name, Validators.required], - file: [this.data?.mapping?.file, Validators.required], + file: [null, Validators.required], + encoding: this.encodingTypeOptions.find(e => e === this.data?.mapping?.encoding) ?? this.encodingTypeOptions[0], delimiter: [this.data?.mapping?.delimiter ?? ',', Validators.required], - encodingType: this.encodingTypeOptions.find(e => e === this.data?.mapping?.encodingType) ?? this.encodingTypeOptions[0], }); } } diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.html b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.html index 863ea0597..ad4765486 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.html +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.html @@ -20,14 +20,7 @@
- +
@@ -51,17 +44,6 @@
- - - - - -
@@ -69,7 +51,7 @@
- {{ entity.value }} + {{ entity.version }}
diff --git a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts index 085dcefd9..3044059f0 100644 --- a/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts +++ b/apps/red-ui/src/app/modules/admin/screens/component-mappings/component-mappings-screen.component.ts @@ -11,13 +11,14 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; import { defaultColorsTranslations } from '@translations/default-colors-translations'; import { Roles } from '@users/roles'; import { getCurrentUser } from '@common-ui/users'; -import { User } from '@red/domain'; +import { DOSSIER_TEMPLATE_ID, User } from '@red/domain'; import { ComponentMapping } from '@red/domain'; import { combineLatest, firstValueFrom } from 'rxjs'; import { ComponentMappingsService } from '@services/entity-services/component-mappings.service'; -import { tap } from 'rxjs/operators'; +import { map, tap } from 'rxjs/operators'; import { AddEditComponentMappingDialogComponent } from './add-edit-component-mapping-dialog/add-edit-component-mapping-dialog.component'; import { AdminDialogService } from '../../services/admin-dialog.service'; +import { getParam } from '@common-ui/utils'; @Component({ templateUrl: './component-mappings-screen.component.html', @@ -27,14 +28,15 @@ import { AdminDialogService } from '../../services/admin-dialog.service'; export class ComponentMappingsScreenComponent extends ListingComponent implements OnInit { tableColumnConfigs: readonly TableColumnConfig[] = [ { label: _('component-mappings-screen.table-col-names.name'), sortByKey: 'searchKey' }, - { label: _('component-mappings-screen.table-col-names.version'), width: '2fr' }, + { label: _('component-mappings-screen.table-col-names.version') }, ]; readonly tableHeaderLabel = _('component-mappings-screen.table-header.title'); - readonly context$; + protected readonly context$; protected readonly currentUser = getCurrentUser(); protected readonly translations = defaultColorsTranslations; protected readonly roles = Roles; protected readonly iconButtonTypes = IconButtonTypes; + readonly #dossierTemplateId = getParam(DOSSIER_TEMPLATE_ID); constructor( private readonly _loadingService: LoadingService, @@ -43,8 +45,13 @@ export class ComponentMappingsScreenComponent extends ListingComponent this.entitiesService.setEntities(mappings)), + this.context$ = this.loadData$(); + } + + loadData$() { + return combineLatest([this._componentMappingService.getComponentMappings(this.#dossierTemplateId)]).pipe( + map(([mappingList]) => mappingList.componentMappingList), + tap(mappings => this.entitiesService.setEntities(mappings)), ); } @@ -55,19 +62,29 @@ export class ComponentMappingsScreenComponent extends ListingComponent { - // this._loadingService.start(); - // this._loadingService.stop(); + openDeleteComponentMappingDialog(entity: ComponentMapping) { + this._dialogService.openDialog('confirm', null, async confirmation => { + if (confirmation) { + this._loadingService.start(); + await firstValueFrom(this._componentMappingService.deleteComponentMapping(this.#dossierTemplateId, entity.id)); + await firstValueFrom(this.loadData$()); + this._loadingService.stop(); + } }); } } diff --git a/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts b/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts index e3c9ac956..86d8c0d21 100644 --- a/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts +++ b/apps/red-ui/src/app/services/entity-services/component-mappings.service.ts @@ -1,80 +1,60 @@ import { Injectable } from '@angular/core'; -import { EntitiesService } from '@iqser/common-ui'; -import { ComponentMapping, IComponentMapping } from '@red/domain'; -import { Observable, of } from 'rxjs'; +import { EntitiesService, QueryParam } from '@iqser/common-ui'; +import { ComponentMapping, IComponentMapping, IComponentMappingList } from '@red/domain'; +import { Observable } from 'rxjs'; +import { HeadersConfiguration, List } from '@common-ui/utils'; -const DATA = [ - { - id: '1', - name: 'OECD Number', - file: 'some file name', - delimiter: ',', - encodingType: 'UTF-8', - version: 2, - searchKey: 'OECD Number', - }, - { - id: '2', - name: 'Study Title', - file: 'some file name', - delimiter: ';', - encodingType: 'ASCII', - version: 1, - searchKey: 'Study Title', - }, - { - id: '3', - name: 'Report Number', - file: 'some file name', - delimiter: '.', - encodingType: 'ISO', - version: 2, - searchKey: 'Report Number', - }, - { - id: '4', - name: 'GLP Study', - file: 'some file name', - delimiter: '"', - encodingType: 'UTF-8', - version: 5, - searchKey: 'GLP Study', - }, - { - id: '5', - name: 'Performing Laboratory', - file: 'some file name', - delimiter: ']', - encodingType: 'UTF-8', - version: 2, - searchKey: 'Performing Laboratory', - }, - { - id: '6', - name: 'Test', - file: 'some file name', - delimiter: ';', - encodingType: 'UTF-8', - version: 3, - searchKey: 'Test', - }, -]; +interface CreateMappingParams { + dossierTemplateId: string; + name: string; + encoding: string; + delimiter: string; +} @Injectable({ providedIn: 'root', }) export class ComponentMappingsService extends EntitiesService { - loadData(): Observable { - return of(DATA); + getComponentMappings(dossierTemplateId: string): Observable { + return this._http.get(`/api/dossier-templates/${dossierTemplateId}/component-mappings`); } - saveData(mapping: any): Observable { - if (!mapping.id) { - mapping.id = (Number(DATA[DATA.length - 1].id) + 1).toString(); - mapping.version = 1; - mapping.searchKey = mapping.name; + createComponentMapping( + dossierTemplateId: string, + componentMapping: Partial, + file: Blob, + ): Observable { + const formParams = new FormData(); + formParams.append('file', file); + + const queryParams: List = [ + { key: 'name', value: componentMapping.name }, + { key: 'encoding', value: componentMapping.encoding }, + { key: 'delimiter', value: componentMapping.delimiter }, + ]; + + if (componentMapping.id) { + return this._http.put( + `/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMapping.id}`, + formParams, + { + params: this._queryParams(queryParams), + }, + ); } - DATA.push(mapping); - return of(mapping); + + return this._http.post(`/api/dossier-templates/${dossierTemplateId}/component-mappings`, formParams, { + params: this._queryParams(queryParams), + }); + } + + deleteComponentMapping(dossierTemplateId: string, componentMappingId: string) { + return this._http.delete(`/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMappingId}`); + } + + getComponentMappingFile(dossierTemplateId: string, componentMappingId: string) { + return this._http.get(`/api/dossier-templates/${dossierTemplateId}/component-mappings/${componentMappingId}`, { + responseType: 'text', + }); } } diff --git a/libs/common-ui b/libs/common-ui index 3a9f36e71..5eef6d403 160000 --- a/libs/common-ui +++ b/libs/common-ui @@ -1 +1 @@ -Subproject commit 3a9f36e71b184e66eb791af19deeb258f8ec333d +Subproject commit 5eef6d403a57c224eec836d9d98787c6a128c50a diff --git a/libs/red-domain/src/lib/component-mappings/component-mapping-list.model.ts b/libs/red-domain/src/lib/component-mappings/component-mapping-list.model.ts new file mode 100644 index 000000000..24425c4a7 --- /dev/null +++ b/libs/red-domain/src/lib/component-mappings/component-mapping-list.model.ts @@ -0,0 +1,16 @@ +import { ComponentMapping, IComponentMapping } from './component-mapping'; + +export interface IComponentMappingList { + dossierTemplateId: string; + componentMappingList: IComponentMapping[]; +} + +export class ComponentMappingList implements IComponentMappingList { + readonly dossierTemplateId: string; + readonly componentMappingList: ComponentMapping[]; + + constructor(componentMappingList: IComponentMappingList) { + this.dossierTemplateId = componentMappingList.dossierTemplateId; + this.componentMappingList = componentMappingList.componentMappingList; + } +} diff --git a/libs/red-domain/src/lib/component-mappings/component-mapping.model.ts b/libs/red-domain/src/lib/component-mappings/component-mapping.model.ts deleted file mode 100644 index 35fa1ef58..000000000 --- a/libs/red-domain/src/lib/component-mappings/component-mapping.model.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { IComponentMapping } from './component-mapping'; -import { IListable } from '@iqser/common-ui'; - -export class ComponentMapping implements IComponentMapping, IListable { - readonly id: string; - readonly name: string; - readonly file: string; - readonly delimiter: string; - readonly encodingType: string; - readonly version: number; - - constructor(componentMapping: IComponentMapping) { - this.id = componentMapping.id; - this.name = componentMapping.name; - this.file = componentMapping.file; - this.delimiter = componentMapping.delimiter; - this.encodingType = componentMapping.encodingType; - this.version = componentMapping.version; - } - - get searchKey(): string { - return this.name; - } -} diff --git a/libs/red-domain/src/lib/component-mappings/component-mapping.ts b/libs/red-domain/src/lib/component-mappings/component-mapping.ts index 501c4c3d1..b8e1e7745 100644 --- a/libs/red-domain/src/lib/component-mappings/component-mapping.ts +++ b/libs/red-domain/src/lib/component-mappings/component-mapping.ts @@ -1,8 +1,38 @@ -export interface IComponentMapping { +import { IListable } from '@iqser/common-ui'; + +export interface IComponentMapping extends IListable { id: string; name: string; - file: string; + fileName: string; version: number; + columnLabels: string[]; + numberOfLines: number; + encoding: string; delimiter: string; - encodingType: string; +} + +export class ComponentMapping implements IComponentMapping, IListable { + readonly id: string; + readonly name: string; + readonly fileName: string; + readonly version: number; + readonly columnLabels: string[]; + readonly numberOfLines: number; + readonly encoding: string; + readonly delimiter: string; + + constructor(componentMapping: IComponentMapping) { + this.id = componentMapping.id; + this.name = componentMapping.name; + this.fileName = componentMapping.fileName; + this.version = componentMapping.version; + this.columnLabels = componentMapping.columnLabels; + this.numberOfLines = componentMapping.numberOfLines; + this.encoding = componentMapping.encoding; + this.delimiter = componentMapping.delimiter; + } + + get searchKey(): string { + return this.name; + } } diff --git a/libs/red-domain/src/lib/component-mappings/index.ts b/libs/red-domain/src/lib/component-mappings/index.ts index c0a040a07..88026faa7 100644 --- a/libs/red-domain/src/lib/component-mappings/index.ts +++ b/libs/red-domain/src/lib/component-mappings/index.ts @@ -1,2 +1,2 @@ -export * from './component-mapping.model'; +export * from './component-mapping-list.model'; export * from './component-mapping';