-
-
-

{{'USERS.LISTING.TITLE' | translate}}

-
- +
+
+ +
+
+

{{'USER-LISTING.TITLE' | translate}}

+ + +
+
+
- - -
- - - - - - - - - + - - {{'USERS.LISTING.NAME' | translate}} - - - {{row.name}} - - + - - {{'USERS.LISTING.EMAIL' | translate}} - {{row.email}} - + + - - {{'USERS.LISTING.LAST-LOGGED-IN' | translate}} - {{row.lastloggedin | date:'shortDate'}} - - - - - {{'USERS.LISTING.ROLES' | translate}} - - - - - - - - - - - -
+ + + +
+
+ + {{item?.name | nullifyValue}} +
+
+ + + + {{'USER-LISTING.FIELDS.CREATED-AT' | translate}}: + + {{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}} + + +
+
+ + + {{'USER-LISTING.FIELDS.UPDATED-AT' | translate}}: + + {{item?.updatedAt | dateTimeFormatter : 'short' | nullifyValue}} + + + +
+
+
+ + +
+ + +
+
+ + +
+
+ + +
+
{{row.name}}
+ +
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss index 6e01f8143..243385ef3 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss @@ -1,91 +1,68 @@ -.mat-table { - margin-top: 47px; - margin-bottom: 20px; - background: #fafafa 0% 0% no-repeat padding-box; - // box-shadow: 0px 5px 12px #00000038; - border-radius: 4px; - - .mat-header-row { - background: #f3f5f8; - } - - mat-header-cell:first-of-type { - padding-left: 46px; - max-width: 120px; - } - - mat-cell:first-of-type { - padding-left: 46px; - max-width: 120px; - } - - .my-mat-card-avatar { - height: 40px; - width: 40px; - border-radius: 50%; - flex-shrink: 0; - margin-right: 2.5rem; - } -} - .user-listing { - margin-top: 2rem; - margin-left: 1rem; - margin-right: 2rem; + margin-top: 1.3rem; + margin-left: 1rem; + margin-right: 2rem; - .mat-card { - margin: 1em 0; - } - - mat-row:hover { - background-color: #eef5f6; - } - - mat-row:nth-child(odd) { - // background-color: #0c748914; - // background-color: #eef0fb; - } - - .export-btn { - background: #ffffff 0% 0% no-repeat padding-box; - border-radius: 30px; - width: 145px; - color: var(--primary-color); - border: 1px solid var(--primary-color); - } - - .export-icon { - font-size: 20px; - } + .mat-header-row{ + background: #f3f5f8; + } + .mat-card { + margin: 16px 0; + padding: 0px; + } + + .mat-row { + cursor: pointer; + min-height: 4.5em; + } + + mat-row:hover { + background-color: #eef5f6; + } + .mat-fab-bottom-right { + float: right; + z-index: 5; + } +} +.create-btn { + border-radius: 30px; + background-color: var(--secondary-color); + padding-left: 2em; + padding-right: 2em; + // color: #000; + + .button-text{ + display: inline-block; + } } -:host ::ng-deep .mat-paginator-container { - // flex-direction: row-reverse !important; - // justify-content: space-between !important; - // height: 30px; - // min-height: 30px !important; - background-color: #f6f6f6; +.dlt-btn { + color: rgba(0, 0, 0, 0.54); } -// ::ng-deep .mat-paginator-page-size { -// height: 43px; -// } +.status-chip{ + + border-radius: 20px; + padding-left: 1em; + padding-right: 1em; + padding-top: 0.2em; + font-size: .8em; +} -// ::ng-deep .mat-paginator-range-label { -// margin: 15px 32px 0 24px !important; -// } +.status-chip-finalized{ + color: #568b5a; + background: #9dd1a1 0% 0% no-repeat padding-box; +} -// ::ng-deep .mat-paginator-range-actions { -// width: 55% !important; -// min-height: 43px !important; -// justify-content: space-between; -// } +.status-chip-draft{ + color: #00c4ff; + background: #d3f5ff 0% 0% no-repeat padding-box; +} -// ::ng-deep .mat-paginator-navigation-previous { -// margin-left: auto !important; -// } - -// ::ng-deep .mat-icon-button { -// height: 30px !important; -// font-size: 12px !important; -// } +.user-avatar { + height: 40px; + width: 40px; + border-radius: 50%; + flex-shrink: 0; + object-fit: cover; +} diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts index db85ab957..3bee61484 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.ts @@ -1,155 +1,195 @@ - -import { Observable, merge as observableMerge, of as observableOf } from 'rxjs'; - -import { DataSource } from '@angular/cdk/table'; -import { HttpClient } from '@angular/common/http'; -import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { MatSort } from '@angular/material/sort'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; -import { BaseComponent } from '@common/base/base.component'; +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { User, UserAdditionalInfo, UserContactInfo, UserRole } from '@app/core/model/user/user'; +import { UserLookup } from '@app/core/query/user.lookup'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { UserService } from '@app/core/services/user/user.service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { FileUtils } from '@app/core/services/utilities/file-utils.service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { BaseListingComponent } from '@common/base/base-listing-component'; +import { PipeService } from '@common/formatting/pipe.service'; +import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; +import { QueryResult } from '@common/model/query-result'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent, RowActivateEvent } from '@common/modules/hybrid-listing/hybrid-listing.component'; +import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; -import { catchError, map, startWith, switchMap, takeUntil } from 'rxjs/operators'; -import { DataTableRequest } from '../../../../core/model/data-table/data-table-request'; -import { UserListingModel } from '../../../../core/model/user/user-listing'; -import { UserCriteria } from '../../../../core/query/user/user-criteria'; -import { UserServiceOld } from '../../../../core/services/user/user.service-old'; -import { SnackBarNotificationComponent } from '../../../../library/notification/snack-bar/snack-bar-notification.component'; -// import { BreadcrumbItem } from '../../../misc/breadcrumb/definition/breadcrumb-item'; -import { FileUtils } from '@app/core/services/utilities/file-utils.service'; -import { UserCriteriaComponent } from './criteria/user-criteria.component'; - -export class UsersDataSource extends DataSource { - - totalCount = 0; - - constructor( - private _service: UserServiceOld, - private _paginator: MatPaginator, - private _sort: MatSort, - private _languageService: TranslateService, - private _snackBar: MatSnackBar, - private _criteria: UserCriteriaComponent - ) { - super(); - //this._paginator.page.pipe(takeUntil(this._destroyed)).subscribe((pageEvent: PageEvent) => { - // this.store.dispatch(new LoadPhotosRequestAction(pageEvent.pageIndex, pageEvent.pageSize)) - //}) - } - - connect(): Observable { - const displayDataChanges = [ - this._paginator.page - //this._sort.matSortChange - ]; - - // If the user changes the sort order, reset back to the first page. - //this._sort.matSortChange.pipe(takeUntil(this._destroyed)).subscribe(() => { - // this._paginator.pageIndex = 0; - //}) - - return observableMerge(...displayDataChanges).pipe( - startWith(null), - switchMap(() => { - const startIndex = this._paginator.pageIndex * this._paginator.pageSize; - let fields: Array = new Array(); - if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } - const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); - request.criteria = this._criteria.getFormData(); - return this._service.getPaged(request); - }), - catchError((error: any) => { - this._snackBar.openFromComponent(SnackBarNotificationComponent, { - data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService }, - duration: 3000, - }); - this._criteria.onCallbackError(error); - return observableOf(null); - }), - map(result => { - return result; - }), - map(result => { - if (!result) { return []; } - if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } - //result.data.forEach((element: any) => { - // const roles: String[] = []; - // element.roles.forEach((role: any) => { - // this._languageService.get(this._utilities.convertFromPrincipalAppRole(role)).pipe(takeUntil(this._destroyed)).subscribe( - // value => roles.push(value) - // ); - // }); - // element.roles = roles; - //}); - return result.data; - }),); - } - - disconnect() { - // No-op - } -} +import { Observable } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; @Component({ - selector: 'app-user-listing-component', templateUrl: './user-listing.component.html', styleUrls: ['./user-listing.component.scss'] }) -export class UserListingComponent extends BaseComponent implements OnInit, AfterViewInit { +export class UserListingComponent extends BaseListingComponent implements OnInit { + publish = false; + userSettingsKey = { key: 'UserListingUserSettings' }; + propertiesAvailableForOrder: ColumnDefinition[]; - @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; - @ViewChild(MatSort, { static: true }) sort: MatSort; - @ViewChild(UserCriteriaComponent, { static: true }) criteria: UserCriteriaComponent; + @ViewChild('roleCellTemplate', { static: true }) roleCellTemplate?: TemplateRef; + @ViewChild('nameCellTemplate', { static: true }) nameCellTemplate?: TemplateRef; + @ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent; - // breadCrumbs: Observable; - dataSource: UsersDataSource | null; - displayedColumns: String[] = ['avatar', 'name', 'email', 'lastloggedin', 'roles']; + private readonly lookupFields: string[] = [ + nameof(x => x.id), + nameof(x => x.name), + [nameof(x => x.contacts), nameof(x => x.id)].join('.'), + [nameof(x => x.contacts), nameof(x => x.type)].join('.'), + [nameof(x => x.contacts), nameof(x => x.value)].join('.'), + [nameof(x => x.roles), nameof(x => x.id)].join('.'), + [nameof(x => x.roles), nameof(x => x.role)].join('.'), + [nameof(x => x.additionalInfo), nameof(x => x.avatarUrl)].join('.'), + nameof(x => x.updatedAt), + nameof(x => x.createdAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ]; + + rowIdentity = x => x.id; constructor( - private userService: UserServiceOld, - private languageService: TranslateService, - public snackBar: MatSnackBar, - private httpClient: HttpClient, - private matomoService: MatomoService, + protected router: Router, + protected route: ActivatedRoute, + protected uiNotificationService: UiNotificationService, + protected httpErrorHandlingService: HttpErrorHandlingService, + protected queryParamsService: QueryParamsService, + private userService: UserService, + public authService: AuthService, + private pipeService: PipeService, + public enumUtils: EnumUtils, + private language: TranslateService, + private dialog: MatDialog, private fileUtils: FileUtils ) { - super(); + super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService); + // Lookup setup + // Default lookup values are defined in the user settings class. + this.lookup = this.initializeLookup(); } ngOnInit() { - this.matomoService.trackPageView('Admin: Users'); - // this.breadCrumbs = observableOf([{ - // parentComponentName: null, - // label: this.languageService.instant('NAV-BAR.USERS-BREADCRUMB'), - // url: "/users" - // }]); - //this.refresh(); //called on ngAfterViewInit with default criteria + super.ngOnInit(); } - ngAfterViewInit() { - setTimeout(() => { - this.criteria.setRefreshCallback(() => this.refresh()); - this.criteria.setCriteria(this.getDefaultCriteria()); - this.criteria.controlModified(); - }); + protected initializeLookup(): UserLookup { + const lookup = new UserLookup(); + lookup.metadata = { countAll: true }; + lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE }; + lookup.isActive = [IsActive.Active]; + lookup.order = { items: [this.toDescSortField(nameof(x => x.createdAt))] }; + this.updateOrderUiFields(lookup.order); + + lookup.project = { + fields: this.lookupFields + }; + + return lookup; } - refresh() { - this._paginator.pageSize = 10; - this._paginator.pageIndex = 0; - this.dataSource = new UsersDataSource(this.userService, this._paginator, this.sort, this.languageService, this.snackBar, this.criteria); + protected setupColumns() { + this.gridColumns.push(...[{ + prop: nameof(x => x.name), + sortable: true, + languageName: 'USER-LISTING.FIELDS.NAME', + cellTemplate: this.nameCellTemplate + }, + { + prop: nameof(x => x.contacts), + sortable: true, + languageName: 'USER-LISTING.FIELDS.CONTACT-INFO', + valueFunction: (item: User) => (item?.contacts ?? []).map(x => x.value).join(', ') + }, + { + prop: nameof(x => x.createdAt), + sortable: true, + languageName: 'USER-LISTING.FIELDS.CREATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.updatedAt), + sortable: true, + languageName: 'USER-LISTING.FIELDS.UPDATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.roles), + languageName: 'USER-LISTING.FIELDS.ROLES', + alwaysShown: true, + maxWidth: 300, + cellTemplate: this.roleCellTemplate + } + ]); + this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable); } - getDefaultCriteria(): UserCriteria { - const defaultCriteria = new UserCriteria(); - return defaultCriteria; + // + // Listing Component functions + // + onColumnsChanged(event: ColumnsChangedEvent) { + super.onColumnsChanged(event); + this.onColumnsChangedInternal(event.properties.map(x => x.toString())); } - // Export user mails - exportUsers() { - this.userService.downloadCSV() + private onColumnsChangedInternal(columns: string[]) { + // Here are defined the projection fields that always requested from the api. + const fields = new Set(this.lookupFields); + this.gridColumns.map(x => x.prop) + .filter(x => !columns?.includes(x as string)) + .forEach(item => { + fields.delete(item as string) + }); + this.lookup.project = { fields: [...fields] }; + this.onPageLoad({ offset: 0 } as PageLoadEvent); + } + + protected loadListing(): Observable> { + return this.userService.query(this.lookup); + } + + public deleteType(id: Guid) { + if (id) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + isDeleteConfirmation: true, + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.userService.delete(id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.ngOnInit(); + } + + onUserRowActivated(event: RowActivateEvent, baseRoute: string = null) { + // Override default event to prevent click action + } + + // + // Export + // + + export() { //TODO: send lookup to backend to export only filtered + this.userService.exportCSV() .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'application/csv' }); @@ -158,6 +198,9 @@ export class UserListingComponent extends BaseComponent implements OnInit, After }); } + // + // Avatar + // public setDefaultAvatar(ev: Event) { (ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png'; } diff --git a/dmp-frontend/src/app/ui/admin/user/user.module.ts b/dmp-frontend/src/app/ui/admin/user/user.module.ts index 38dae797a..aaa36defe 100644 --- a/dmp-frontend/src/app/ui/admin/user/user.module.ts +++ b/dmp-frontend/src/app/ui/admin/user/user.module.ts @@ -1,24 +1,32 @@ -import { NgModule } from '@angular/core'; -import { FormattingModule } from '@app/core/formatting.module'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { CommonFormattingModule } from '@common/formatting/common-formatting.module'; import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { HybridListingModule } from '@common/modules/hybrid-listing/hybrid-listing.module'; +import { TextFilterModule } from '@common/modules/text-filter/text-filter.module'; +import { UserSettingsModule } from '@common/modules/user-settings/user-settings.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; -import { UserCriteriaComponent } from './listing/criteria/user-criteria.component'; -import { UserRoleEditorComponent } from './listing/role-editor/user-role-editor.component'; +import { UserListingFiltersComponent } from './listing/filters/user-listing-filters.component'; import { UserListingComponent } from './listing/user-listing.component'; -import { UserRoutingModule } from './user.routing'; +import { UsersRoutingModule } from './user.routing'; +import { UserRoleEditorComponent } from './listing/role-editor/user-role-editor.component'; @NgModule({ - imports: [ - CommonUiModule, - CommonFormsModule, - FormattingModule, - UserRoutingModule - ], declarations: [ UserListingComponent, - UserCriteriaComponent, - UserRoleEditorComponent + // UserEditorComponent, + UserRoleEditorComponent, + UserListingFiltersComponent ], + imports: [ + CommonModule, + CommonUiModule, + CommonFormsModule, + CommonFormattingModule, + UsersRoutingModule, + HybridListingModule, + TextFilterModule, + UserSettingsModule + ] }) - -export class UserModule { } \ No newline at end of file +export class UsersModule { } diff --git a/dmp-frontend/src/app/ui/admin/user/user.routing.ts b/dmp-frontend/src/app/ui/admin/user/user.routing.ts index 90e8fa5f9..2515d0e9f 100644 --- a/dmp-frontend/src/app/ui/admin/user/user.routing.ts +++ b/dmp-frontend/src/app/ui/admin/user/user.routing.ts @@ -1,15 +1,19 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { UserListingComponent } from './listing/user-listing.component'; -import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { AuthGuard } from "@app/core/auth-guard.service"; +import { UserListingComponent } from "./listing/user-listing.component"; const routes: Routes = [ - { path: '', component: UserListingComponent, canActivate: [AdminAuthGuard] }, - // { path: ':id', component: UserProfileComponent } -]; + { + path: '', + component: UserListingComponent, + canActivate: [AuthGuard] + }, + { path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) }, +] @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], }) -export class UserRoutingModule { } +export class UsersRoutingModule { } diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 60414cdc1..2cd2e7bfb 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1664,20 +1664,25 @@ "CANCEL": "Cancel" } }, - "USERS": { - "LISTING": { - "TITLE": "Users", - "EMAIL": "Email", - "LAST-LOGGED-IN": "Last Logged In", - "LABEL": "Label", + "USER-LISTING": { + "TITLE": "Users", + "FIELDS": { + "CONTACT-INFO": "Email", "ROLES": "Roles", "NAME": "Name", - "PERMISSIONS": "Permissions", - "EXPORT": "Export users" + "UPDATED-AT": "Updated", + "CREATED-AT": "Created" + }, + "FILTER": { + "TITLE": "Filters", + "IS-ACTIVE": "Is Active", + "CANCEL": "Cancel", + "APPLY-FILTERS": "Apply filters" }, "ACTIONS": { "EDIT": "Edit", - "SAVE": "Save" + "SAVE": "Save", + "EXPORT": "Export users" } }, "TYPES": { From 693f1dba7fc119809159d0c1e92e1189815d3ec1 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 28 Nov 2023 15:52:17 +0200 Subject: [PATCH 2/4] Fetching and building grants for dmps for public API --- .../publicapi/DmpToPublicApiDmpMapper.java | 2 ++ .../grant/GrantPublicOverviewModel.java | 28 +++++++++++++++++++ .../publicapi/PublicDmpsDocumentation.java | 3 ++ 3 files changed, 33 insertions(+) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java index 0d802f1c3..d71b89f74 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java @@ -1,6 +1,7 @@ package eu.eudat.model.mapper.publicapi; import eu.eudat.model.Dmp; +import eu.eudat.model.publicapi.grant.GrantPublicOverviewModel; import eu.eudat.model.publicapi.overviewmodels.DataManagementPlanPublicModel; import eu.eudat.model.publicapi.researcher.ResearcherPublicModel; import eu.eudat.model.publicapi.user.UserInfoPublicModel; @@ -22,6 +23,7 @@ public class DmpToPublicApiDmpMapper { model.setUsers(dmp.getDmpUsers().stream().map(UserInfoPublicModel::fromDmpUser).toList()); model.setResearchers(dmp.getDmpReferences().stream().map(ResearcherPublicModel::fromDmpReference).filter(Objects::isNull).toList()); + model.setGrant(GrantPublicOverviewModel.fromDmpReferences(dmp.getDmpReferences())); model.setCreatedAt(Date.from(dmp.getCreatedAt())); model.setModifiedAt(Date.from(dmp.getUpdatedAt())); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java index 5f6ca2f2a..bb663c7b1 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java @@ -1,9 +1,15 @@ package eu.eudat.model.publicapi.grant; +import eu.eudat.commons.enums.ReferenceType; import eu.eudat.data.old.Grant; +import eu.eudat.model.DmpReference; +import eu.eudat.model.Reference; import eu.eudat.model.publicapi.funder.FunderPublicOverviewModel; +import eu.eudat.model.referencedefinition.Field; +import java.time.Instant; import java.util.Date; +import java.util.List; import java.util.UUID; public class GrantPublicOverviewModel { @@ -72,6 +78,28 @@ public class GrantPublicOverviewModel { this.funder = funder; } + public static GrantPublicOverviewModel fromDmpReferences(List dmpReferences) { + for (DmpReference dmpReference : dmpReferences) { + if (dmpReference.getReference().getType() != ReferenceType.Grants) + continue; + GrantPublicOverviewModel model = new GrantPublicOverviewModel(); + Reference reference = dmpReference.getReference(); + model.setId(reference.getId()); + model.setDescription(reference.getDescription()); + model.setAbbreviation(reference.getAbbreviation()); + model.setLabel(reference.getLabel()); + Field startDate = reference.getDefinition().getFields().stream().filter(x -> x.getCode().equals("startDate")).toList().get(0); + if (startDate != null) model.setStartDate(Date.from(Instant.parse(startDate.getValue()))); + Field endDate = reference.getDefinition().getFields().stream().filter(x -> x.getCode().equals("endDate")).toList().get(0); + if (startDate != null) model.setEndDate(Date.from(Instant.parse(endDate.getValue()))); + Field uri = reference.getDefinition().getFields().stream().filter(x -> x.getCode().equals("uri")).toList().get(0); + if (uri != null) model.setUri(uri.getValue()); + + return model; + } + return null; + } + public GrantPublicOverviewModel fromDataModel(Grant entity) { this.id = entity.getId(); this.label = entity.getLabel(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDmpsDocumentation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDmpsDocumentation.java index 8a8b6d6f1..9c9633aa2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDmpsDocumentation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDmpsDocumentation.java @@ -161,6 +161,9 @@ public class PublicDmpsDocumentation extends BaseController { String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._id)), String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._reference)), String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._label)), + String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._abbreviation)), + String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._description)), + String.join(".", Dmp._dmpReferences, String.join(".", DmpReference._reference, Reference._definition)), Dmp._createdAt, Dmp._updatedAt, Dmp._finalizedAt From b00b04863238f2f468c25216253f9ec755cf4338 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 28 Nov 2023 16:20:31 +0200 Subject: [PATCH 3/4] Fetching and building organizations for dmps for public API --- .../publicapi/DmpToPublicApiDmpMapper.java | 2 + .../organisation/OrganizationPublicModel.java | 62 +++++-------------- .../researcher/ResearcherPublicModel.java | 14 ++--- 3 files changed, 22 insertions(+), 56 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java index d71b89f74..81dbd0a68 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DmpToPublicApiDmpMapper.java @@ -2,6 +2,7 @@ package eu.eudat.model.mapper.publicapi; import eu.eudat.model.Dmp; import eu.eudat.model.publicapi.grant.GrantPublicOverviewModel; +import eu.eudat.model.publicapi.organisation.OrganizationPublicModel; import eu.eudat.model.publicapi.overviewmodels.DataManagementPlanPublicModel; import eu.eudat.model.publicapi.researcher.ResearcherPublicModel; import eu.eudat.model.publicapi.user.UserInfoPublicModel; @@ -24,6 +25,7 @@ public class DmpToPublicApiDmpMapper { model.setUsers(dmp.getDmpUsers().stream().map(UserInfoPublicModel::fromDmpUser).toList()); model.setResearchers(dmp.getDmpReferences().stream().map(ResearcherPublicModel::fromDmpReference).filter(Objects::isNull).toList()); model.setGrant(GrantPublicOverviewModel.fromDmpReferences(dmp.getDmpReferences())); + model.setOrganisations(dmp.getDmpReferences().stream().map(OrganizationPublicModel::fromDmpReference).filter(Objects::isNull).toList()); model.setCreatedAt(Date.from(dmp.getCreatedAt())); model.setModifiedAt(Date.from(dmp.getUpdatedAt())); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/organisation/OrganizationPublicModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/organisation/OrganizationPublicModel.java index 4c802a24c..e9a17493f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/organisation/OrganizationPublicModel.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/organisation/OrganizationPublicModel.java @@ -1,6 +1,9 @@ package eu.eudat.model.publicapi.organisation; +import eu.eudat.commons.enums.ReferenceType; import eu.eudat.data.old.Organisation; +import eu.eudat.model.DmpReference; +import eu.eudat.model.Reference; import java.util.Date; import java.util.HashMap; @@ -64,55 +67,18 @@ public class OrganizationPublicModel { this.key = key; } - public OrganizationPublicModel fromDataModel(Organisation entity) { - this.id = entity.getId().toString(); - this.name = entity.getLabel(); - this.label = entity.getUri(); - if (entity.getReference() != null) { - this.reference = entity.getReference(); - this.key = entity.getReference().substring(0, entity.getReference().indexOf(":")); - } - return this; - } - - public Organisation toDataModel() { - Organisation organisationEntity = new Organisation(); - if (this.key != null && this.reference != null) { - if (this.reference.startsWith(this.key + ":")) { - organisationEntity.setReference(this.reference); - } else { - organisationEntity.setReference(this.key + ":" + this.reference); - } - } - if (this.id != null) { - organisationEntity.setId(UUID.fromString(this.id)); - } - organisationEntity.setLabel(this.name); - organisationEntity.setUri(this.label); - organisationEntity.setCreated(new Date()); - organisationEntity.setStatus((short) this.status); - return organisationEntity; - } - - public static OrganizationPublicModel fromMap(HashMap map) { + public static OrganizationPublicModel fromDmpReference(DmpReference dmpReference) { + if (dmpReference.getReference().getType() != ReferenceType.Organizations) + return null; OrganizationPublicModel model = new OrganizationPublicModel(); - if (map != null) { - model.id = (String) map.get("id"); - model.key = (String) map.get("key"); - model.label = (String) map.get("label"); - model.name = (String) map.get("name"); - model.reference = (String) map.get("reference"); - model.status = (int) map.get("status"); - model.tag = (String) map.get("tag"); - } + Reference reference = dmpReference.getReference(); + model.setId(reference.getId().toString()); + model.setReference(reference.getReference()); + model.setLabel(reference.getLabel()); + model.setName(reference.getLabel()); + if (reference.getReference() != null) + model.setKey(reference.getReference().substring(0, reference.getReference().indexOf(":"))); + return model; } - - public String generateLabel() { - return this.getName(); - } - - public String getHint() { - return null; - } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/researcher/ResearcherPublicModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/researcher/ResearcherPublicModel.java index add469532..ca36c9b99 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/researcher/ResearcherPublicModel.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/researcher/ResearcherPublicModel.java @@ -2,14 +2,11 @@ package eu.eudat.model.publicapi.researcher; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import eu.eudat.commons.enums.ReferenceType; -import eu.eudat.data.old.Researcher; import eu.eudat.model.DmpReference; +import eu.eudat.model.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Date; -import java.util.UUID; - @JsonIgnoreProperties(ignoreUnknown = true) public class ResearcherPublicModel { private static final Logger logger = LoggerFactory.getLogger(ResearcherPublicModel.class); @@ -74,10 +71,11 @@ public class ResearcherPublicModel { if (dmpReference.getReference().getType() != ReferenceType.Researcher) return null; ResearcherPublicModel model = new ResearcherPublicModel(); - model.setId(dmpReference.getReference().getId().toString()); - model.setReference(dmpReference.getReference().getReference()); - model.setLabel(dmpReference.getReference().getLabel()); - model.setName(dmpReference.getReference().getLabel()); + Reference reference = dmpReference.getReference(); + model.setId(reference.getId().toString()); + model.setReference(reference.getReference()); + model.setLabel(reference.getLabel()); + model.setName(reference.getLabel()); String[] refParts = dmpReference.getReference().getReference().split(":"); String source = refParts[0]; if (source.equals("dmp")) From e6cba30e4cbfa94e0fd97f37073178f60e22cea4 Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 28 Nov 2023 16:50:00 +0200 Subject: [PATCH 4/4] Fetching funders on grants for dmps for public API --- .../model/publicapi/grant/GrantPublicOverviewModel.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java index bb663c7b1..d3593ab92 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/grant/GrantPublicOverviewModel.java @@ -79,7 +79,15 @@ public class GrantPublicOverviewModel { } public static GrantPublicOverviewModel fromDmpReferences(List dmpReferences) { + FunderPublicOverviewModel funder = null; for (DmpReference dmpReference : dmpReferences) { + if (dmpReference.getReference().getType() == ReferenceType.Funder) { + funder = new FunderPublicOverviewModel(); + Reference reference = dmpReference.getReference(); + funder.setId(reference.getId()); + funder.setLabel(reference.getLabel()); + continue; + } if (dmpReference.getReference().getType() != ReferenceType.Grants) continue; GrantPublicOverviewModel model = new GrantPublicOverviewModel(); @@ -88,6 +96,7 @@ public class GrantPublicOverviewModel { model.setDescription(reference.getDescription()); model.setAbbreviation(reference.getAbbreviation()); model.setLabel(reference.getLabel()); + model.setFunder(funder); Field startDate = reference.getDefinition().getFields().stream().filter(x -> x.getCode().equals("startDate")).toList().get(0); if (startDate != null) model.setStartDate(Date.from(Instant.parse(startDate.getValue()))); Field endDate = reference.getDefinition().getFields().stream().filter(x -> x.getCode().equals("endDate")).toList().get(0);