diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java index e1ad1cf80..f1f227312 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java @@ -1,5 +1,6 @@ package eu.eudat.query; +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.query.lookup.DescriptionTemplateTypeLookup; import eu.eudat.query.lookup.LookupAware; @@ -74,6 +75,8 @@ public class DescriptionTemplateTypeQuery extends QueryBase> { - return this.http.get>(this.actionUrl + 'get', { headers: this.headers }); + getAll(lookup: DescriptionTemplateTypeLookup): Observable> { + const url = `${this.apiBase}/all`; + return this.http.post>(url, lookup, { headers: this.headers }); } - getSingle(id: string): Observable { - return this.http.get(this.actionUrl + 'get/' + id, { headers: this.headers }); + getSingle(id: string): Observable> { + const url = `${this.apiBase}/${id}`; + return this.http.get>(url , { headers: this.headers }); } - createType(type: DescriptionTemplateType): Observable { - return this.http.post(this.actionUrl + 'create', type, { headers: this.headers }); + create(payload: DescriptionTemplateType): Observable> { + const url = `${this.apiBase}/create`; + return this.http.post>(url, payload, { headers: this.headers }); } - updateType(type: DescriptionTemplateType): Observable { - return this.http.post(this.actionUrl + 'update', type, { headers: this.headers }); + update(payload: DescriptionTemplateType): Observable> { + const url = `${this.apiBase}/update`; + return this.http.post>(url, payload, { headers: this.headers }); } - deleteType(id: string): Observable { - return this.http.delete(this.actionUrl + 'delete/' + id, { headers: this.headers }); + delete(id: string): Observable { + const url = `${this.apiBase}/delete/${id}`; + return this.http.delete(url, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/core/services/http/base-http-v2.service.ts b/dmp-frontend/src/app/core/services/http/base-http-v2.service.ts new file mode 100644 index 000000000..4d556aea1 --- /dev/null +++ b/dmp-frontend/src/app/core/services/http/base-http-v2.service.ts @@ -0,0 +1,40 @@ + +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +@Injectable() +export class BaseHttpV2Service { + constructor( + protected http: HttpClient + ) { + } + + get(url: string, options?: Object): Observable { + return this.http.get(url, options); + } + + post(url: string, body: any, options?: Object): Observable { + return this.http.post(url, body, options); + } + + put(url: string, body: any, options?: Object): Observable { + return this.http.put(url, body, options); + } + + delete(url: string, options?: Object): Observable { + return this.http.delete(url, options); + } + + patch(url: string, body: any, options?: Object): Observable { + return this.http.patch(url, body, options); + } + + head(url: string, options?: Object): Observable { + return this.http.head(url, options); + } + + options(url: string, options?: Object): Observable { + return this.http.options(url, options); + } +} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts index 904ab51ad..d3ffca7d0 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts @@ -48,6 +48,8 @@ import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; +import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template/description-template-type.lookup'; +import { nameof } from 'ts-simple-nameof'; const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json'); @@ -607,9 +609,17 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent } getDescriptionTemplateTypes(): DescriptionTemplateType[] { - this.descriptionTemplateTypeService.getTypes().pipe(takeUntil(this._destroyed)) + let lookup: DescriptionTemplateTypeLookup = new DescriptionTemplateTypeLookup(); + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.name), + nameof(x => x.status) + ] + }; + this.descriptionTemplateTypeService.getAll(lookup).pipe(takeUntil(this._destroyed)) .subscribe(types => { - this.descriptionTemplateTypes = types.data.filter(type => type.status === DescriptionTemplateTypeStatus.Finalized); + this.descriptionTemplateTypes = types.items.filter(type => type.status === DescriptionTemplateTypeStatus.Finalized); }); return this.descriptionTemplateTypes; } diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts index b430fc263..b7f045d96 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts @@ -14,9 +14,9 @@ import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; @Component({ - selector: 'app-description-type-editor', - templateUrl: './description-type-editor.component.html', - styleUrls: ['./description-type-editor.component.scss'] + selector: 'app-description-type-editor', + templateUrl: './description-type-editor.component.html', + styleUrls: ['./description-type-editor.component.scss'] }) export class DescriptionTypeEditorComponent extends BaseComponent implements OnInit { @@ -34,7 +34,7 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI private language: TranslateService, private route: ActivatedRoute, private router: Router - ) { + ) { super(); } @@ -47,12 +47,12 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI this.descriptionTemplateTypeService.getSingle(this.descriptionTemplateTypeId) .pipe(takeUntil(this._destroyed)).subscribe( type => { - this.descriptionTypeModel = new DescriptionTypeEditorModel().fromModel(type); - if(this.descriptionTypeModel.status === DescriptionTemplateTypeStatus.Finalized){ + this.descriptionTypeModel = new DescriptionTypeEditorModel().fromModel(type.items[0]); + if (this.descriptionTypeModel.status === DescriptionTemplateTypeStatus.Finalized) { this.formGroup = this.descriptionTypeModel.buildForm(null, true); this.viewOnly = true; } - else{ + else { this.formGroup = this.descriptionTypeModel.buildForm(); } }, @@ -67,7 +67,7 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI }); } - formSubmit(): void { + formSubmit(): void { this.formService.touchAllFormFields(this.formGroup); if (!this.isFormValid()) { return; } this.onSubmit(); @@ -82,17 +82,17 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI this.onSubmit(); } - onSubmit(): void { - if(this.isNew){ - this.descriptionTemplateTypeService.createType(this.formGroup.value) + onSubmit(): void { + if (this.isNew) { + this.descriptionTemplateTypeService.create(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(true), error => this.onCallbackError(error) ); } - else{ - this.descriptionTemplateTypeService.updateType(this.formGroup.value) + else { + this.descriptionTemplateTypeService.update(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(false), @@ -102,10 +102,10 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI } onCallbackSuccess(creation: boolean): void { - if(creation){ + if (creation) { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success); } - else{ + else { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); } this.router.navigate(['/description-types']); @@ -123,15 +123,15 @@ export class DescriptionTypeEditorComponent extends BaseComponent implements OnI }); } - public cancel(): void { + public cancel(): void { this.router.navigate(['/description-types']); } } export class DescriptionTypeEditorModel { - public id: string; - public name: string; + public id: string; + public name: string; public status: DescriptionTemplateTypeStatus; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); @@ -151,7 +151,7 @@ export class DescriptionTypeEditorModel { }); return formGroup; } - + createValidationContext(): ValidationContext { const baseContext: ValidationContext = new ValidationContext(); baseContext.validation.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] }); diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html index 27311bafe..2ee578c4e 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html @@ -28,23 +28,26 @@ {{'DESCRIPTION-TYPES-LISTING.COLUMNS.STATUS' | translate}} -
{{parseStatus(row.status) | translate}}
-
- - - - - + +
{{parseStatus(row.status) | translate}}
- + + + + + + + + - + diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts index 99c79b984..bdeb32aa3 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts @@ -1,28 +1,31 @@ import { DataSource } from '@angular/cdk/table'; import { HttpErrorResponse } from '@angular/common/http'; -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, EventEmitter, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; +import { MatTableDataSource } from '@angular/material/table'; import { Router } from '@angular/router'; import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; +import { DescriptionTemplateTypeLookup } from '@app/core/query/description-template/description-template-type.lookup'; import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseComponent } from '@common/base/base.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { TranslateService } from '@ngx-translate/core'; -import { merge as observableMerge, Observable, of } from 'rxjs'; +import { Observable, merge, of } from 'rxjs'; import { map, startWith, switchMap, takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; @Component({ - selector: 'app-description-types', - templateUrl: './description-types.component.html', - styleUrls: ['./description-types.component.scss'] + selector: 'app-description-types', + templateUrl: './description-types.component.html', + styleUrls: ['./description-types.component.scss'] }) export class DescriptionTypesComponent extends BaseComponent implements OnInit { - @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; - @ViewChild(MatSort, { static: true }) sort: MatSort; + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) _sort: MatSort; dataSource: DescriptionTypesDataSource | null; displayedColumns: String[] = ['label', 'status', 'delete']; @@ -38,7 +41,7 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { private language: TranslateService, private uiNotificationService: UiNotificationService, private router: Router - ) { + ) { super(); } @@ -46,25 +49,25 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { this.refresh(); } - refresh() { - this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this.sort/*, this.criteria*/); + refresh() { + this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this._sort); } rowClick(rowId: String) { this.router.navigate(['description-types/' + rowId]); } - parseStatus(value: number): string{ + parseStatus(value: number): string { const stringVal = value.toString() - try{ + try { return this.statuses.find(status => status.value === stringVal).viewValue; - }catch{ + } catch { return stringVal; } } - deleteTemplate(id: string){ - if(id){ + deleteTemplate(id: string) { + if (id) { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { restoreFocus: false, data: { @@ -77,22 +80,22 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { - this.descriptionTemplateTypeService.deleteType(id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); - this.refresh(); - }, - error => { - this.onCallbackError(error); - if (error.error.statusCode == 674) { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); - } else { - this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + this.descriptionTemplateTypeService.delete(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + this.refresh(); + }, + error => { + this.onCallbackError(error); + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } } - } - ); + ); } }); @@ -104,8 +107,8 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { } getStatusClass(status: number): string { - - if(status == 1){ + + if (status == 1) { return 'status-chip-finalized' } @@ -116,7 +119,8 @@ export class DescriptionTypesComponent extends BaseComponent implements OnInit { export class DescriptionTypesDataSource extends DataSource { - totalCount = 0; + data: DescriptionTemplateType[] = []; + loadData: EventEmitter = new EventEmitter(); constructor( private _service: DescriptionTemplateTypeService, @@ -124,27 +128,41 @@ export class DescriptionTypesDataSource extends DataSource { - const displayDataChanges = [ - this._paginator.page - //this._sort.matSortChange + const dataChanges = [ + this._paginator.page, + this._sort.sortChange ]; - return observableMerge(...displayDataChanges).pipe( - startWith(null), + return merge(...dataChanges).pipe( + startWith(null), switchMap(() => { - return this._service.getTypes(); + let lookup: DescriptionTemplateTypeLookup = new DescriptionTemplateTypeLookup(); + lookup.page = { + offset: this._paginator.pageIndex * this._paginator.pageSize, + size: this._paginator.pageSize + }, + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.name), + nameof(x => x.status) + ] + }; + + return this._service.getAll(lookup) }), map(result => { return result; }), map(result => { if (!result) { return []; } - if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } - return result.data; + + this.data = result.items; + this._paginator.length = result.count; + return result.items; })); } diff --git a/dmp-frontend/src/common/model/lookup.ts b/dmp-frontend/src/common/model/lookup.ts new file mode 100644 index 000000000..5758827fd --- /dev/null +++ b/dmp-frontend/src/common/model/lookup.ts @@ -0,0 +1,31 @@ +export class Lookup { + public page: Lookup.Paging; + public order: Lookup.Ordering; + public metadata: Lookup.Header; + public project: Lookup.FieldDirectives; + + constructor() { + this.project = { + fields: [] + }; + } +} + +export namespace Lookup { + export interface Header { + countAll: boolean; + } + + export interface FieldDirectives { + fields: string[]; + } + + export interface Ordering { + items: string[]; + } + + export interface Paging { + offset: number; + size: number; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/common/model/query-result.ts b/dmp-frontend/src/common/model/query-result.ts new file mode 100644 index 000000000..a845cfbfb --- /dev/null +++ b/dmp-frontend/src/common/model/query-result.ts @@ -0,0 +1,5 @@ +export interface QueryResult { + count: number; + countOverride?: number; + items: T[]; +} \ No newline at end of file