Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Diamantis Tziotzios 2024-02-08 17:14:29 +02:00
commit f6151b085f
9 changed files with 90 additions and 23 deletions

View File

@ -55,6 +55,8 @@ BEGIN
); );
ALTER TABLE public."DescriptionTemplate" ALTER COLUMN version_status SET NOT NULL; ALTER TABLE public."DescriptionTemplate" ALTER COLUMN version_status SET NOT NULL;
ALTER TABLE public."DescriptionTemplate" ALTER COLUMN version DROP DEFAULT;
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.010', '2023-11-02 12:00:00.000000+02', now(), 'Aling DescriptionTemplate table.'); INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.010', '2023-11-02 12:00:00.000000+02', now(), 'Aling DescriptionTemplate table.');

View File

@ -17,6 +17,16 @@ export interface DescriptionTemplatePersist extends BaseEntityPersist {
users: UserDescriptionTemplatePersist[]; users: UserDescriptionTemplatePersist[];
} }
export interface NewVersionDescriptionTemplatePersist extends BaseEntityPersist {
label: string;
description: string;
language: string;
type: Guid;
status: DescriptionTemplateStatus;
definition: DescriptionTemplateDefinitionPersist;
users: UserDescriptionTemplatePersist[];
}
export interface UserDescriptionTemplatePersist { export interface UserDescriptionTemplatePersist {
userId?: Guid; userId?: Guid;
role?: UserDescriptionTemplateRole; role?: UserDescriptionTemplateRole;

View File

@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { IsActive } from '@app/core/common/enum/is-active.enum'; import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { DescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist'; import { DescriptionTemplatePersist, NewVersionDescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist';
import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup'; import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
@ -68,6 +68,15 @@ export class DescriptionTemplateService {
catchError((error: any) => throwError(error))); catchError((error: any) => throwError(error)));
} }
newVersion(item: NewVersionDescriptionTemplatePersist, reqFields: string[] = []): Observable<DescriptionTemplate> {
const url = `${this.apiBase}/new-version`;
const options = { params: { f: reqFields } };
return this.http
.post<DescriptionTemplate>(url, item).pipe(
catchError((error: any) => throwError(error)));
}
downloadXML(id: Guid): Observable<HttpResponse<Blob>> { downloadXML(id: Guid): Observable<HttpResponse<Blob>> {
const url = `${this.apiBase}/xml/export/${id}`; const url = `${this.apiBase}/xml/export/${id}`;
let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml'); let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml');

View File

@ -14,6 +14,14 @@ const routes: Routes = [
component: DescriptionTemplateListingComponent, component: DescriptionTemplateListingComponent,
canActivate: [AuthGuard] canActivate: [AuthGuard]
}, },
{
path: 'versions/:groupid',
component: DescriptionTemplateListingComponent,
canActivate: [AuthGuard],
data: {
mode: 'versions-listing'
}
},
{ {
path: 'new', path: 'new',
canActivate: [AuthGuard], canActivate: [AuthGuard],
@ -24,7 +32,7 @@ const routes: Routes = [
permissions: [AppPermission.EditDescriptionTemplate] permissions: [AppPermission.EditDescriptionTemplate]
}, },
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.NEW-DMP-BLUEPRINT' title: 'BREADCRUMBS.NEW-DESCRIPTION-TEMPLATES'
}) })
} }
}, },
@ -38,13 +46,31 @@ const routes: Routes = [
}, },
data: { data: {
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DMP-BLUEPRINT' title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATES'
}), }),
authContext: { authContext: {
permissions: [AppPermission.EditDescriptionTemplate] permissions: [AppPermission.EditDescriptionTemplate]
} },
action: 'clone'
}
},
{
path: 'new-version/:newversionid',
canActivate: [AuthGuard],
component: DescriptionTemplateEditorComponent,
canDeactivate: [PendingChangesGuard],
resolve: {
'entity': DescriptionTemplateEditorResolver
},
data: {
...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATES'
}),
authContext: {
permissions: [AppPermission.EditDescriptionTemplate]
},
action: 'new-version'
} }
}, },
{ {
path: ':id', path: ':id',
@ -56,7 +82,7 @@ const routes: Routes = [
}, },
data: { data: {
...BreadcrumbService.generateRouteDataConfiguration({ ...BreadcrumbService.generateRouteDataConfiguration({
title: 'BREADCRUMBS.EDIT-DMP-BLUEPRINT' title: 'BREADCRUMBS.EDIT-DESCRIPTION-TEMPLATES'
}), }),
authContext: { authContext: {
permissions: [AppPermission.EditDescriptionTemplate] permissions: [AppPermission.EditDescriptionTemplate]

View File

@ -14,7 +14,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum';
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role'; import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { DescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist'; import { DescriptionTemplatePersist, NewVersionDescriptionTemplatePersist } from '@app/core/model/description-template/description-template-persist';
import { LanguageInfo } from '@app/core/model/language-info'; import { LanguageInfo } from '@app/core/model/language-info';
import { User } from '@app/core/model/user/user'; import { User } from '@app/core/model/user/user';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
@ -201,13 +201,23 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
} }
persistEntity(onSuccess?: (response) => void): void { persistEntity(onSuccess?: (response) => void): void {
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist; if (this.isNew && !this.isClone && !this.isNewVersion){
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist;
this.descriptionTemplateService.persist(formData) this.descriptionTemplateService.persist(formData)
.pipe(takeUntil(this._destroyed)).subscribe( .pipe(takeUntil(this._destroyed)).subscribe(
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
error => this.onCallbackError(error) error => this.onCallbackError(error)
); );
} else if (this.isNewVersion && !this.isNew && !this.isClone) {
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist;
this.descriptionTemplateService.newVersion(formData)
.pipe(takeUntil(this._destroyed)).subscribe(
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
error => this.onCallbackError(error)
);
}
} }
formSubmit(): void { formSubmit(): void {

View File

@ -103,10 +103,13 @@ export class DescriptionTemplateEditorResolver extends BaseEditorResolver {
]; ];
const id = route.paramMap.get('id'); const id = route.paramMap.get('id');
const cloneid = route.paramMap.get('cloneid'); const cloneid = route.paramMap.get('cloneid');
const newversion = route.paramMap.get('newversionid');
if (id != null) { if (id != null) {
return this.descriptionTemplateService.getSingle(Guid.parse(id), fieldSets).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); return this.descriptionTemplateService.getSingle(Guid.parse(id), fieldSets).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed));
} else if (cloneid != null) { } else if (cloneid != null) {
return this.descriptionTemplateService.clone(Guid.parse(cloneid), fieldSets).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); return this.descriptionTemplateService.clone(Guid.parse(cloneid), fieldSets).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed));
} else if (newversion != null) {
return this.descriptionTemplateService.getSingle(Guid.parse(newversion), fieldSets).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed));
} }
} }
} }

View File

@ -23,7 +23,7 @@
</div> </div>
</div> </div>
<app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns" [count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size" [defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event)" (pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)" (columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate"> <app-hybrid-listing [rows]="gridRows" [columns]="gridColumns" [visibleColumns]="visibleColumns" [count]="totalElements" [offset]="currentPageNumber" [limit]="lookup.page.size" [defaultSort]="lookup.order?.items" [externalSorting]="true" (rowActivated)="onRowActivated($event, '/description-templates')" (pageLoad)="alterPage($event)" (columnSort)="onColumnSort($event)" (columnsChanged)="onColumnsChanged($event)" [listItemTemplate]="listItemTemplate">
<app-description-template-listing-filters hybrid-listing-filters [(filter)]="lookup" (filterChange)="filterChanged($event)" /> <app-description-template-listing-filters hybrid-listing-filters [(filter)]="lookup" (filterChange)="filterChanged($event)" />
@ -95,23 +95,20 @@
<mat-icon>more_horiz</mat-icon> <mat-icon>more_horiz</mat-icon>
</button> </button>
<mat-menu #actionsMenu="matMenu"> <mat-menu #actionsMenu="matMenu">
<button mat-menu-item [routerLink]="['./' + row.id]"> <button mat-menu-item [routerLink]="['/description-templates/', row.id]">
<mat-icon>edit</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.EDIT' | translate}} <mat-icon>edit</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.EDIT' | translate}}
</button> </button>
<button mat-menu-item [routerLink]="['./new-version/' + row.id]"> <button mat-menu-item [routerLink]="['/description-templates/new-version/', row.id]">
<mat-icon>queue</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.NEW-VERSION' | translate}} <mat-icon>queue</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button> </button>
<button mat-menu-item (click)="newVersionFromFile(row.id, row.label)"> <button mat-menu-item [routerLink]="['/description-templates/clone/', row.id]">
<mat-icon>file_copy</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.NEW-VERSION-FROM-FILE' | translate}}
</button>
<button mat-menu-item [routerLink]="['./clone/' + row.id]">
<mat-icon>content_copy</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.CLONE' | translate}} <mat-icon>content_copy</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.CLONE' | translate}}
</button> </button>
<button mat-menu-item [routerLink]="['./versions/' + row.id]"> <button mat-menu-item [routerLink]="['/description-templates/versions/', row.groupId]">
<mat-icon>library_books</mat-icon> <mat-icon>library_books</mat-icon>
{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.VIEW-VERSIONS' | translate}} {{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.VIEW-VERSIONS' | translate}}
</button> </button>
<button mat-menu-item (click)="export(row.id)" [routerLink]="['./' + row.id]"> <button mat-menu-item (click)="export(row.id)" [routerLink]="['/description-templates/', row.id]">
<mat-icon>download</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.DOWNLOAD-XML' | translate}} <mat-icon>download</mat-icon>{{'DESCRIPTION-TEMPLATE-LISTING.ACTIONS.DOWNLOAD-XML' | translate}}
</button> </button>
<button mat-menu-item (click)="delete(row.id)"> <button mat-menu-item (click)="delete(row.id)">

View File

@ -40,6 +40,7 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
userSettingsKey = { key: 'DescriptionTemplateListingUserSettings' }; userSettingsKey = { key: 'DescriptionTemplateListingUserSettings' };
propertiesAvailableForOrder: ColumnDefinition[]; propertiesAvailableForOrder: ColumnDefinition[];
descriptionTemplateStatuses = DescriptionTemplateStatus; descriptionTemplateStatuses = DescriptionTemplateStatus;
mode;
@ViewChild('descriptionTemplateStatus', { static: true }) descriptionTemplateStatus?: TemplateRef<any>; @ViewChild('descriptionTemplateStatus', { static: true }) descriptionTemplateStatus?: TemplateRef<any>;
@ViewChild('actions', { static: true }) actions?: TemplateRef<any>; @ViewChild('actions', { static: true }) actions?: TemplateRef<any>;
@ -50,6 +51,8 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
nameof<DescriptionTemplate>(x => x.label), nameof<DescriptionTemplate>(x => x.label),
nameof<DescriptionTemplate>(x => x.description), nameof<DescriptionTemplate>(x => x.description),
nameof<DescriptionTemplate>(x => x.status), nameof<DescriptionTemplate>(x => x.status),
nameof<DescriptionTemplate>(x => x.version),
nameof<DescriptionTemplate>(x => x.groupId),
nameof<DescriptionTemplate>(x => x.updatedAt), nameof<DescriptionTemplate>(x => x.updatedAt),
nameof<DescriptionTemplate>(x => x.createdAt), nameof<DescriptionTemplate>(x => x.createdAt),
nameof<DescriptionTemplate>(x => x.hash), nameof<DescriptionTemplate>(x => x.hash),
@ -76,6 +79,7 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService); super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService);
// Lookup setup // Lookup setup
// Default lookup values are defined in the user settings class. // Default lookup values are defined in the user settings class.
this.mode = this.route.snapshot?.data['mode'];
this.lookup = this.initializeLookup(); this.lookup = this.initializeLookup();
} }
@ -90,6 +94,7 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE }; lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE };
lookup.isActive = [IsActive.Active]; lookup.isActive = [IsActive.Active];
lookup.order = { items: [this.toDescSortField(nameof<DescriptionTemplate>(x => x.createdAt))] }; lookup.order = { items: [this.toDescSortField(nameof<DescriptionTemplate>(x => x.createdAt))] };
if (this.mode && this.mode == 'versions-listing') lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))]
this.updateOrderUiFields(lookup.order); this.updateOrderUiFields(lookup.order);
lookup.project = { lookup.project = {
@ -116,6 +121,11 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.STATUS', languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.STATUS',
cellTemplate: this.descriptionTemplateStatus cellTemplate: this.descriptionTemplateStatus
}, },
{
prop: nameof<DescriptionTemplate>(x => x.version),
sortable: true,
languageName: 'DESCRIPTION-TEMPLATE-LISTING.FIELDS.VERSION'
},
{ {
prop: nameof<DescriptionTemplate>(x => x.createdAt), prop: nameof<DescriptionTemplate>(x => x.createdAt),
sortable: true, sortable: true,

View File

@ -1074,6 +1074,7 @@
"NAME": "Name", "NAME": "Name",
"DESCRIPTION": "Description", "DESCRIPTION": "Description",
"STATUS": "Status", "STATUS": "Status",
"VERSION": "Version",
"UPDATED-AT": "Updated", "UPDATED-AT": "Updated",
"CREATED-AT": "Created", "CREATED-AT": "Created",
"PUBLISHED-AT": "Published", "PUBLISHED-AT": "Published",
@ -1097,7 +1098,6 @@
"CLONE": "Clone", "CLONE": "Clone",
"DOWNLOAD-XML": "Download XML", "DOWNLOAD-XML": "Download XML",
"NEW-VERSION": "New Version", "NEW-VERSION": "New Version",
"NEW-VERSION-FROM-FILE": "New Version from File",
"VIEW-VERSIONS": "All Description Template Versions" "VIEW-VERSIONS": "All Description Template Versions"
}, },
"IMPORT": { "IMPORT": {