This commit is contained in:
Diamantis Tziotzios 2024-05-29 18:56:47 +03:00
parent a088e7b2dc
commit b72adf92d5
34 changed files with 307 additions and 3038 deletions

View File

@ -117,15 +117,6 @@ export class DescriptionService {
return this.httpClient.get(url, { params: params, responseType: 'blob', observe: 'response', headers: headerXml }); return this.httpClient.get(url, { params: params, responseType: 'blob', observe: 'response', headers: headerXml });
} }
// public downloadPDF(id: string): Observable<HttpResponse<Blob>> {
// return this.httpClient.get(`${this.apiBase}/${id}/export/Pdf`, { responseType: 'blob', observe: 'response', headers: this.headers });
// }
public download(id: string, format: string): Observable<HttpResponse<Blob>> {
//let headerDocx: HttpHeaders = this.headers.set('Content-Type', 'application/msword')
return this.httpClient.get(`${this.apiBase}/${id}/export/${format}`, { responseType: 'blob', observe: 'response', headers: this.headers });
}
public updateDescriptionTemplate(item: UpdateDescriptionTemplatePersist): Observable<boolean> { public updateDescriptionTemplate(item: UpdateDescriptionTemplatePersist): Observable<boolean> {
const url = `${this.apiBase}/update-description-template`; const url = `${this.apiBase}/update-description-template`;

View File

@ -168,16 +168,6 @@ export class DmpService {
return this.http.get<any>(url).pipe(catchError((error: any) => throwError(error))); return this.http.get<any>(url).pipe(catchError((error: any) => throwError(error)));
} }
public download(id: string, format: string): Observable<HttpResponse<Blob>> {
//let headerDoc: HttpHeaders = this.headers.set('Content-Type', 'application/msword')
return this.httpClient.get(`${this.apiBase}/${id}/export/${format}`, { responseType: 'blob', observe: 'response', headers: this.headers });
}
// public downloadJson(id: string): Observable<HttpResponse<Blob>> {
// return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' });
// }
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

@ -37,7 +37,7 @@ export class FileTransformerService extends BaseService {
private _availableFormats: RepositoryFileFormat[] = []; private _availableFormats: RepositoryFileFormat[] = [];
get availableFormats(): RepositoryFileFormat[] { get availableFormats(): RepositoryFileFormat[] {
if (!this.authentication.currentAccountIsAuthenticated()){ if (!this.authentication.currentAccountIsAuthenticated()) {
return; return;
} }
// console.log('availableFormats'); // console.log('availableFormats');
@ -70,7 +70,7 @@ export class FileTransformerService extends BaseService {
exportDmp(id: Guid, repositoryId: string, format: string) { exportDmp(id: Guid, repositoryId: string, format: string) {
this._loading = true; this._loading = true;
if (repositoryId == this.xmlExportRepo.repositoryId) { if (repositoryId == this.xmlExportRepo.repositoryId) {
this.dmpService.downloadXML(id) this.dmpService.downloadXML(id)
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(response => { .subscribe(response => {
const blob = new Blob([response.body], { type: 'application/xml' }); const blob = new Blob([response.body], { type: 'application/xml' });
@ -84,10 +84,10 @@ export class FileTransformerService extends BaseService {
})).subscribe(result => { })).subscribe(result => {
if (result !== null) { if (result !== null) {
const blob = new Blob([result.body], { type: 'application/octet-stream' }); const blob = new Blob([result.body], { type: 'application/octet-stream' });
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(result.headers.get('Content-Disposition')); const filename = this.fileUtils.getFilenameFromContentDispositionHeader(result.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename); FileSaver.saveAs(blob, filename);
this.analyticsService.trackDownload('dmps', format, id.toString()); this.analyticsService.trackDownload('dmps', format, id.toString());
} }
}); });

View File

@ -6,90 +6,90 @@ import { AnalyticsProviderType, AnalyticsProviders } from "@app/core/model/confi
@Injectable() @Injectable()
export class AnalyticsService { export class AnalyticsService {
//#region track page view //#region track page view
public static Dashboard: string = 'Home Dashboard'; public static Dashboard: string = 'Home Dashboard';
public static About: string = 'About'; public static About: string = 'About';
public static DescriptionTemplateEditor: string = 'Admin: DMP Blueprints'; public static DescriptionTemplateEditor: string = 'Admin: DMP Blueprints';
public static DescriptionTemplateListing: string = 'Admin: DMP Templates'; public static DescriptionTemplateListing: string = 'Admin: DMP Templates';
public static DmpBlueprintEditor: string = 'Admin: DMP Blueprints'; public static DmpBlueprintEditor: string = 'Admin: DMP Blueprints';
public static DmpBlueprintListing: string = 'Admin: DMP Templates'; public static DmpBlueprintListing: string = 'Admin: DMP Templates';
public static LanguagesEditor: string = 'Admin: Languages'; public static LanguagesEditor: string = 'Admin: Languages';
public static PrefillingSourcesEditor: string = 'Admin: PrefillingSources'; public static PrefillingSourcesEditor: string = 'Admin: PrefillingSources';
public static ReferencesEditor: string = 'Admin: References'; public static ReferencesEditor: string = 'Admin: References';
public static TenantsEditor: string = 'Admin: Tenants'; public static TenantsEditor: string = 'Admin: Tenants';
public static TenantConfigurationsColorsEditor: string = 'Admin: TenantConfigurations'; public static TenantConfigurationsColorsEditor: string = 'Admin: TenantConfigurations';
public static TenantConfigurationsUserLocaleEditor: string = 'Admin: TenantConfigurations'; public static TenantConfigurationsUserLocaleEditor: string = 'Admin: TenantConfigurations';
public static DepositEditor: string = 'Admin: TenantConfigurations'; public static DepositEditor: string = 'Admin: TenantConfigurations';
public static FileTransformerEditor: string = 'Admin: TenantConfigurations'; public static FileTransformerEditor: string = 'Admin: TenantConfigurations';
public static LogoEditor: string = 'Admin: TenantConfigurations'; public static LogoEditor: string = 'Admin: TenantConfigurations';
public static ContactContent: string = 'Contact Content'; public static ContactContent: string = 'Contact Content';
public static RecentEditedActivity: string = 'Recent DMP Activity'; public static RecentEditedActivity: string = 'Recent DMP Activity';
public static DescriptionEditor: string = 'Description Editor'; public static DescriptionEditor: string = 'Description Editor';
public static DescriptionListing: string = 'Descriptions'; public static DescriptionListing: string = 'Descriptions';
public static DatasetCriteriaDialog: string = 'Dataset Criteria'; public static DatasetCriteriaDialog: string = 'Dataset Criteria';
public static DescriptionListingItem: string = 'Description Listing Item'; public static DescriptionListingItem: string = 'Description Listing Item';
public static DescriptionOverview: string = 'Description Overview'; public static DescriptionOverview: string = 'Description Overview';
public static DmpEditor: string = 'DMP Editor'; public static DmpEditor: string = 'DMP Editor';
public static DmpListing: string = 'DMPs'; public static DmpListing: string = 'DMPs';
public static DmpCriteriaDialog: string = 'DMP Criteria'; public static DmpCriteriaDialog: string = 'DMP Criteria';
public static DmpListingItem: string = 'DMP Listing Item'; public static DmpListingItem: string = 'DMP Listing Item';
public static StartNewDmpDialog: string = 'Start New DMP Dialog'; public static StartNewDmpDialog: string = 'Start New DMP Dialog';
public static DmpUploadDialog: string = 'DMP Upload Dialog'; public static DmpUploadDialog: string = 'DMP Upload Dialog';
public static DmpOverview: string = 'DMP Overview'; public static DmpOverview: string = 'DMP Overview';
public static FAQ: string = 'FAQ'; public static FAQ: string = 'FAQ';
public static Glossary: string = 'Glossary'; public static Glossary: string = 'Glossary';
public static Navbar: string = 'Navbar'; public static Navbar: string = 'Navbar';
public static Sidebar: string = 'Sidebar'; public static Sidebar: string = 'Sidebar';
public static SidebarFooter: string = 'Sidebar Footer'; public static SidebarFooter: string = 'Sidebar Footer';
public static Terms: string = 'Terms of Service'; public static Terms: string = 'Terms of Service';
public static UserGuideContent: string = 'User Guide Content'; public static UserGuideContent: string = 'User Guide Content';
public static UserProfile: string = 'User Profile'; public static UserProfile: string = 'User Profile';
public static NotificationTempplateEditor: string = 'Admin: Notification Tempplates'; public static NotificationTempplateEditor: string = 'Admin: Notification Tempplates';
//#endregion //#endregion
//#region trackDownload //#region trackDownload
public static trackDmp: string = "dmps" public static trackDmp: string = "dmps"
public static trackDatasets: string = "datasets" public static trackDatasets: string = "datasets"
public static trackDescriptions: string = "descriptions" public static trackDescriptions: string = "descriptions"
//#endregion //#endregion
constructor( constructor(
private configurationService: ConfigurationService, private configurationService: ConfigurationService,
private matomoService: MatomoService private matomoService: MatomoService
) { } ) { }
trackPageView(customTitle?: string): void { trackPageView(customTitle?: string): void {
const analytics: AnalyticsProviders = this.configurationService.analyticsProviders; const analytics: AnalyticsProviders = this.configurationService.analyticsProviders;
for (let provider of analytics.providers) { for (let provider of analytics.providers) {
switch(provider.type) { switch (provider.type) {
case(AnalyticsProviderType.Matomo): case (AnalyticsProviderType.Matomo):
this.matomoService.trackPageView(provider, customTitle); this.matomoService.trackPageView(provider, customTitle);
break; break;
} }
} }
} }
trackSiteSearch(keyword: string, category?: string, resultsCount?: number): void { trackSiteSearch(keyword: string, category?: string, resultsCount?: number): void {
const analytics: AnalyticsProviders = this.configurationService.analyticsProviders; const analytics: AnalyticsProviders = this.configurationService.analyticsProviders;
for (let provider of analytics.providers) { for (let provider of analytics.providers) {
switch(provider.type) { switch (provider.type) {
case(AnalyticsProviderType.Matomo): case (AnalyticsProviderType.Matomo):
this.matomoService.trackSiteSearch(keyword, category, resultsCount); this.matomoService.trackSiteSearch(keyword, category, resultsCount);
break; break;
} }
} }
} }
trackDownload(category: "dmps" | "datasets" | "descriptions", type: string, id: string): void { trackDownload(category: "dmps" | "datasets" | "descriptions", type: string, id: string): void {
const analytics: AnalyticsProviders = this.configurationService.analyticsProviders; const analytics: AnalyticsProviders = this.configurationService.analyticsProviders;
for (let provider of analytics.providers) { for (let provider of analytics.providers) {
switch(provider.type) { switch (provider.type) {
case(AnalyticsProviderType.Matomo): case (AnalyticsProviderType.Matomo):
this.matomoService.trackDownload(category, type, id); this.matomoService.trackDownload(category, type, id);
break; break;
} }
} }
} }
} }

View File

@ -2,9 +2,15 @@
import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
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 { SumarizeTextPipe } from '@app/core/pipes/sumarize-text.pipe';
import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
@ -12,6 +18,7 @@ import { QueryParamsService } from '@app/core/services/utilities/query-params.se
import { BaseListingComponent } from '@common/base/base-listing-component'; import { BaseListingComponent } from '@common/base/base-listing-component';
import { PipeService } from '@common/formatting/pipe.service'; import { PipeService } from '@common/formatting/pipe.service';
import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe';
import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe';
import { QueryResult } from '@common/model/query-result'; import { QueryResult } from '@common/model/query-result';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
@ -23,13 +30,6 @@ import { Observable } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { ImportDescriptionTemplateDialogComponent } from './import-description-template/import-description-template.dialog.component'; import { ImportDescriptionTemplateDialogComponent } from './import-description-template/import-description-template.dialog.component';
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
import { DescriptionTemplateLookup } from '@app/core/query/description-template.lookup';
import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe';
import { DescriptionTemplateVersionStatus } from '@app/core/common/enum/description-template-version-status';
import { SumarizeTextPipe } from '@app/core/pipes/sumarize-text.pipe';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({ @Component({
@ -101,7 +101,7 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
if (this.mode && this.mode == 'versions-listing') { if (this.mode && this.mode == 'versions-listing') {
lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))]; lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))];
lookup.versionStatuses = null; lookup.versionStatuses = null;
}else{ } else {
lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current, DescriptionTemplateVersionStatus.NotFinalized]; lookup.versionStatuses = [DescriptionTemplateVersionStatus.Current, DescriptionTemplateVersionStatus.NotFinalized];
} }
this.updateOrderUiFields(lookup.order); this.updateOrderUiFields(lookup.order);
@ -252,179 +252,3 @@ export class DescriptionTemplateListingComponent extends BaseListingComponent<De
}); });
} }
} }
// ngOnInit() {
// refresh() {
// this.dataSource = new DatasetDataSource(this.descriptionTemplateService, this._paginator, this.sort, this.criteria);
// }
// clone(id: string) {
// this.router.navigate(['description-templates/clone/' + id]);
// }
// rowClick(rowId: String) {
// this.router.navigate(['description-templates/' + rowId]);
// }
// downloadXML(descriptionTemplateId: string): void {
// this.descriptionTemplateService.downloadXML(descriptionTemplateId)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/xml' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// });
// }
// deleteTemplate(id: string) {
// if (id) {
// this.dialog.open(ConfirmationDialogComponent, {
// data: {
// isDeleteConfirmation: true,
// confirmButton: this.languageService.instant('DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
// cancelButton: this.languageService.instant("DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
// message: this.languageService.instant("DESCRIPTION-TEMPLATE-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
// }
// })
// .afterClosed()
// .subscribe(
// confirmed => {
// if (confirmed) {
// this.descriptionTemplateService.delete(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DESCRIPTION-TEMPLATE-DELETE'), SnackBarNotificationLevel.Success);
// this.refresh();
// },
// error => {
// this.onCallbackError(error);
// if (error.error.statusCode == 674) {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DESCRIPTION-TEMPLATE-DELETE'), SnackBarNotificationLevel.Error);
// } else {
// this.uiNotificationService.snackBarNotification(this.languageService.instant(error.message), SnackBarNotificationLevel.Error);
// }
// }
// );
// }
// }
// )
// }
// }
// onCallbackError(errorResponse: HttpErrorResponse) {
// this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning);
// }
// getDefaultCriteria(): DescriptionTemplateCriteria {
// const defaultCriteria = new DescriptionTemplateCriteria();
// return defaultCriteria;
// }
// // makeItPublic(id: String) {
// // debugger;
// // this.datasetService.makeDatasetPublic(id).pipe(takeUntil(this._destroyed)).subscribe();
// // }
// parseStatus(value: number): string {
// const stringVal = value.toString()
// try {
// return this.statuses.find(status => status.value === stringVal).viewValue;
// } catch {
// return stringVal;
// }
// }
// openDialog(): void {
// const dialogRef = this.dialog.open(DialodConfirmationUploadDescriptionTemplates, {
// restoreFocus: false,
// data: {
// message: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-TITLE'),
// confirmButton: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML'),
// cancelButton: this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.IMPORT.UPLOAD-XML-FILE-CANCEL'),
// name: '',
// file: FileList,
// sucsess: false
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(data => {
// if (data && data.sucsess && data.name != null && data.file != null) {
// this.descriptionTemplateService.uploadFile(data.file, data.name)
// .pipe(takeUntil(this._destroyed))
// .subscribe(_ => {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('DESCRIPTION-TEMPLATE-LISTING.MESSAGES.TEMPLATE-UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success);
// this.refresh();
// },
// error => {
// this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error);
// });
// }
// });
// }
// getStatusClass(status: number): string {
// if (status === 1) {//finalized
// return 'status-chip-finalized'
// }
// if (status === 0) {
// return 'status-chip-draft';
// }
// return '';
// }
// }
// export class DatasetDataSource extends DataSource<DescriptionTemplateListing> {
// totalCount = 0;
// constructor(
// private _service: descriptionTemplateService,
// private _paginator: MatPaginator,
// private _sort: MatSort,
// private _criteria: DescriptionTemplateCriteriaComponent
// ) {
// super();
// }
// connect(): Observable<DescriptionTemplateListing[]> {
// const displayDataChanges = [
// this._paginator.page
// //this._sort.matSortChange
// ];
// return observableMerge(...displayDataChanges).pipe(
// startWith(null),
// switchMap(() => {
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
// let fields: Array<string> = new Array();
// if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; }
// const request = new DataTableRequest<DescriptionTemplateCriteria>(startIndex, this._paginator.pageSize, { fields: fields });
// request.criteria = this._criteria.criteria;
// return this._service.getPagedBlueprint(request);
// }),
// /*.catch((error: any) => {
// this._snackBar.openFromComponent(SnackBarNotificationComponent, {
// data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
// duration: 3000,
// extraClasses: ['snackbar-warning']
// });
// //this._criteria.criteria.onCallbackError(error);
// return Observable.of(null);
// })*/
// map(result => {
// return result;
// }),
// map(result => {
// if (!result) { return []; }
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
// return result.data;
// }));
// }
// disconnect() {
// // No-op
// }

View File

@ -3,11 +3,13 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
import { DmpBlueprintVersionStatus } from '@app/core/common/enum/dmp-blueprint-version-status';
import { IsActive } from '@app/core/common/enum/is-active.enum'; import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup'; import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
@ -15,6 +17,7 @@ import { QueryParamsService } from '@app/core/services/utilities/query-params.se
import { BaseListingComponent } from '@common/base/base-listing-component'; import { BaseListingComponent } from '@common/base/base-listing-component';
import { PipeService } from '@common/formatting/pipe.service'; import { PipeService } from '@common/formatting/pipe.service';
import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe';
import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe';
import { QueryResult } from '@common/model/query-result'; import { QueryResult } from '@common/model/query-result';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
@ -26,9 +29,6 @@ import { Observable } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { ImportDmpBlueprintDialogComponent } from './import-dmp-blueprint/import-dmp-blueprint.dialog.component'; import { ImportDmpBlueprintDialogComponent } from './import-dmp-blueprint/import-dmp-blueprint.dialog.component';
import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe';
import { DmpBlueprintVersionStatus } from '@app/core/common/enum/dmp-blueprint-version-status';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({ @Component({
@ -98,7 +98,7 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
if (this.mode && this.mode == 'versions-listing') { if (this.mode && this.mode == 'versions-listing') {
lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))]; lookup.groupIds = [Guid.parse(this.route.snapshot.paramMap.get('groupid'))];
lookup.versionStatuses = null; lookup.versionStatuses = null;
}else{ } else {
lookup.versionStatuses = [DmpBlueprintVersionStatus.Current, DmpBlueprintVersionStatus.NotFinalized]; lookup.versionStatuses = [DmpBlueprintVersionStatus.Current, DmpBlueprintVersionStatus.NotFinalized];
} }
this.updateOrderUiFields(lookup.order); this.updateOrderUiFields(lookup.order);
@ -243,179 +243,3 @@ export class DmpBlueprintListingComponent extends BaseListingComponent<DmpBluepr
}); });
} }
} }
// ngOnInit() {
// refresh() {
// this.dataSource = new DatasetDataSource(this.dmpBlueprintService, this._paginator, this.sort, this.criteria);
// }
// clone(id: string) {
// this.router.navigate(['dmp-blueprints/clone/' + id]);
// }
// rowClick(rowId: String) {
// this.router.navigate(['dmp-blueprints/' + rowId]);
// }
// downloadXML(dmpBlueprintId: string): void {
// this.dmpBlueprintService.downloadXML(dmpBlueprintId)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/xml' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// });
// }
// deleteTemplate(id: string) {
// if (id) {
// this.dialog.open(ConfirmationDialogComponent, {
// data: {
// isDeleteConfirmation: true,
// confirmButton: this.languageService.instant('DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'),
// cancelButton: this.languageService.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"),
// message: this.languageService.instant("DMP-BLUEPRINT-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE")
// }
// })
// .afterClosed()
// .subscribe(
// confirmed => {
// if (confirmed) {
// this.dmpBlueprintService.delete(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// complete => {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Success);
// this.refresh();
// },
// error => {
// this.onCallbackError(error);
// if (error.error.statusCode == 674) {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error);
// } else {
// this.uiNotificationService.snackBarNotification(this.languageService.instant(error.message), SnackBarNotificationLevel.Error);
// }
// }
// );
// }
// }
// )
// }
// }
// onCallbackError(errorResponse: HttpErrorResponse) {
// this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning);
// }
// getDefaultCriteria(): DmpBlueprintCriteria {
// const defaultCriteria = new DmpBlueprintCriteria();
// return defaultCriteria;
// }
// // makeItPublic(id: String) {
// // debugger;
// // this.datasetService.makeDatasetPublic(id).pipe(takeUntil(this._destroyed)).subscribe();
// // }
// parseStatus(value: number): string {
// const stringVal = value.toString()
// try {
// return this.statuses.find(status => status.value === stringVal).viewValue;
// } catch {
// return stringVal;
// }
// }
// openDialog(): void {
// const dialogRef = this.dialog.open(DialodConfirmationUploadDmpBlueprints, {
// restoreFocus: false,
// data: {
// message: this.languageService.instant('DMP-BLUEPRINT-LISTING.IMPORT.UPLOAD-XML-FILE-TITLE'),
// confirmButton: this.languageService.instant('DMP-BLUEPRINT-LISTING.IMPORT.UPLOAD-XML'),
// cancelButton: this.languageService.instant('DMP-BLUEPRINT-LISTING.IMPORT.UPLOAD-XML-FILE-CANCEL'),
// name: '',
// file: FileList,
// sucsess: false
// }
// });
// dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(data => {
// if (data && data.sucsess && data.name != null && data.file != null) {
// this.dmpBlueprintService.uploadFile(data.file, data.name)
// .pipe(takeUntil(this._destroyed))
// .subscribe(_ => {
// this.uiNotificationService.snackBarNotification(this.languageService.instant('DMP-BLUEPRINT-LISTING.MESSAGES.TEMPLATE-UPLOAD-SUCCESS'), SnackBarNotificationLevel.Success);
// this.refresh();
// },
// error => {
// this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error);
// });
// }
// });
// }
// getStatusClass(status: number): string {
// if (status === 1) {//finalized
// return 'status-chip-finalized'
// }
// if (status === 0) {
// return 'status-chip-draft';
// }
// return '';
// }
// }
// export class DatasetDataSource extends DataSource<DmpBlueprintListing> {
// totalCount = 0;
// constructor(
// private _service: dmpBlueprintService,
// private _paginator: MatPaginator,
// private _sort: MatSort,
// private _criteria: DmpBlueprintCriteriaComponent
// ) {
// super();
// }
// connect(): Observable<DmpBlueprintListing[]> {
// const displayDataChanges = [
// this._paginator.page
// //this._sort.matSortChange
// ];
// return observableMerge(...displayDataChanges).pipe(
// startWith(null),
// switchMap(() => {
// const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
// let fields: Array<string> = new Array();
// if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; }
// const request = new DataTableRequest<DmpBlueprintCriteria>(startIndex, this._paginator.pageSize, { fields: fields });
// request.criteria = this._criteria.criteria;
// return this._service.getPagedBlueprint(request);
// }),
// /*.catch((error: any) => {
// this._snackBar.openFromComponent(SnackBarNotificationComponent, {
// data: { message: 'GENERAL.SNACK-BAR.FORMS-BAD-REQUEST', language: this._languageService },
// duration: 3000,
// extraClasses: ['snackbar-warning']
// });
// //this._criteria.criteria.onCallbackError(error);
// return Observable.of(null);
// })*/
// map(result => {
// return result;
// }),
// map(result => {
// if (!result) { return []; }
// if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; }
// return result.data;
// }));
// }
// disconnect() {
// // No-op
// }

View File

@ -1,13 +1,3 @@
<!-- <div class="row root">
<div class="d-flex justify-content-center">
<mat-card class="p-4 mt-4">
<div style="color: red;">Warning: Danger zone. Irreversible actions!</div>
<div>
<button mat-raised-button color="primary" (click)="migrateSemantics($event)" class="lightblue-btn button">Migrate semantics</button>
<button mat-raised-button color="primary" (click)="addRdaInSemantics($event)" class="lightblue-btn button">Add rda in semantics</button>
</div>
</mat-card>
</div> -->
<div class="container-fluid"> <div class="container-fluid">
<div class="row root"> <div class="row root">
<div class="col-md-10 offset-md-1"> <div class="col-md-10 offset-md-1">

View File

@ -29,35 +29,6 @@ export class MaintenanceTasksComponent extends BaseComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
} }
//TODO: refactor
// migrateSemantics(ev: Event) {
// (ev.srcElement as HTMLButtonElement).disabled = true;
// this.maintenanceTasksService.migrateSemantics().pipe(takeUntil(this._destroyed)).subscribe(
// response => {
// (ev.srcElement as HTMLButtonElement).disabled = false;
// this.onCallbackSuccess();
// },
// error => {
// (ev.srcElement as HTMLButtonElement).disabled = false;
// this.onCallbackError(error);
// }
// );
// }
// addRdaInSemantics(ev: Event) {
// (ev.srcElement as HTMLButtonElement).disabled = true;
// this.maintenanceTasksService.addRdaInSemantics().pipe(takeUntil(this._destroyed)).subscribe(
// response => {
// (ev.srcElement as HTMLButtonElement).disabled = false;
// this.onCallbackSuccess();
// },
// error => {
// (ev.srcElement as HTMLButtonElement).disabled = false;
// this.onCallbackError(error);
// }
// );
// }
generateIndex(ev: Event) { generateIndex(ev: Event) {
this.dialog.open(ConfirmationDialogComponent, { this.dialog.open(ConfirmationDialogComponent, {
data: { data: {
@ -252,5 +223,4 @@ export class MaintenanceTasksComponent extends BaseComponent implements OnInit {
onCallbackError(error: any) { onCallbackError(error: any) {
this.uiNotificationService.snackBarNotification(error, SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(error, SnackBarNotificationLevel.Error);
} }
} }

View File

@ -5,77 +5,73 @@
<div class="row flex-column-reverse flex-xl-row"> <div class="row flex-column-reverse flex-xl-row">
<div class="col-12 col-xl-10"> <div class="col-12 col-xl-10">
<div class="row"> <div class="row">
<div *ngIf="newReleaseNotificationVisible" class="new-releases-card col-auto mt-0 mr-4"> <div *ngIf="newReleaseNotificationVisible" class="new-releases-card col-auto mt-0 mr-4">
<a class="col-auto d-flex" (click)="dismissNewReleaseNotification()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a> <a class="col-auto d-flex" (click)="dismissNewReleaseNotification()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a>
<div class="row new-releases-hint-container m-0"> <div class="row new-releases-hint-container m-0">
<p class="new-releases-chip mb-0 col-auto">{{'NEW-RELEASE-NOTIFICATION.HINT' | translate}}</p> <p class="new-releases-chip mb-0 col-auto">{{'NEW-RELEASE-NOTIFICATION.HINT' | translate}}</p>
</div>
<p class="new-releases-title mb-0 pt-4">{{'NEW-RELEASE-NOTIFICATION.TITLE' | translate}}</p>
<p class="new-releases-content mb-0">{{'NEW-RELEASE-NOTIFICATION.BODY' | translate}}</p>
<div class="row d-flex align-items-center mt-4" *ngIf="this.configurationService.newReleaseNotificationLink">
<div class="col-auto d-flex">
<a class="notification-link" href="{{this.configurationService.newReleaseNotificationLink}}" target="_blank">
<button mat-raised-button type="button" class="col-auto align-self-center new-releases-btn">{{'NEW-RELEASE-NOTIFICATION.ACTIONS.LEARN-MORE' | translate}}</button>
</a>
</div>
<span class="new-releases-logo">
<img src="../../../assets/images/new-releases-logo.png">
</span>
</div>
</div> </div>
<div class="card col-auto mt-0" [style.display]="isIntroCardVisible ? 'block' : 'none'"> <p class="new-releases-title mb-0 pt-4">{{'NEW-RELEASE-NOTIFICATION.TITLE' | translate}}</p>
<a *ngIf="this.hasDmps()" class="col-auto d-flex" (click)="dismissIntroCard()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a> <p class="new-releases-content mb-0">{{'NEW-RELEASE-NOTIFICATION.BODY' | translate}}</p>
<p *ngIf="!this.hasDmps()" class="card-title mb-0 pt-4">{{'DASHBOARD.DMP-QUESTION' | translate}}</p> <div class="row d-flex align-items-center mt-4" *ngIf="this.configurationService.newReleaseNotificationLink">
<p *ngIf="!this.hasDmps()" class="card-content mb-0">{{'DASHBOARD.INFO-DMP-TEXT' | translate}}</p> <div class="col-auto d-flex">
<a class="notification-link" href="{{this.configurationService.newReleaseNotificationLink}}" target="_blank">
<p *ngIf="!this.hasDmps()" class="card-content pt-3 mb-0"> <button mat-raised-button type="button" class="col-auto align-self-center new-releases-btn">{{'NEW-RELEASE-NOTIFICATION.ACTIONS.LEARN-MORE' | translate}}</button>
{{'DASHBOARD.NEW-QUESTION' | translate}} <a href="https://www.openaire.eu/how-to-create-a-data-management-plan" target="_blank"><u>{{'DASHBOARD.OPEN-AIR-GUIDE' | translate}}</u></a> {{'DASHBOARD.LEARN-MORE' | translate}} </a>
</p>
<p *ngIf="this.hasDmps()" class="card-content mb-0 pt-0">{{'DASHBOARD.DMP-ABOUT-BEG' | translate}}
<b>{{'DASHBOARD.DATASET-DESCRIPTIONS-DASHBOARD-TEXT' | translate}}</b>
{{'DASHBOARD.DMP-ABOUT-END' | translate}}
</p>
<div class="row d-flex align-items-center">
<div *ngIf="!this.hasDmps()" class="col-auto p-0 add-dataset-btn d-flex">
<div class="pr-2">
<button type="button" class="align-self-center normal-btn" (click)="openNewDmpDialog()">{{'DASHBOARD.START-YOUR-FIRST-DMP' | translate}}</button>
</div>
</div>
<div *ngIf="this.hasDmps()" class="col-auto p-0 new-dataset-tour add-dataset-btn col-auto d-flex">
<div class="pr-2">
<button mat-raised-button type="button" class="align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div>
</div>
<span class="col-auto ml-auto">
<img class="laptop-img\6" src="../../../assets/images/dashboard-popup.png">
</span>
</div> </div>
<span class="new-releases-logo">
<img src="../../../assets/images/new-releases-logo.png">
</span>
</div> </div>
</div>
<div class="card col-auto mt-0" [style.display]="isIntroCardVisible ? 'block' : 'none'">
<a *ngIf="this.hasDmps()" class="col-auto d-flex" (click)="dismissIntroCard()"><span class="ml-auto mt-3 material-icons clear-icon">clear</span></a>
<p *ngIf="!this.hasDmps()" class="card-title mb-0 pt-4">{{'DASHBOARD.DMP-QUESTION' | translate}}</p>
<p *ngIf="!this.hasDmps()" class="card-content mb-0">{{'DASHBOARD.INFO-DMP-TEXT' | translate}}</p>
<p *ngIf="!this.hasDmps()" class="card-content pt-3 mb-0">
{{'DASHBOARD.NEW-QUESTION' | translate}} <a href="https://www.openaire.eu/how-to-create-a-data-management-plan" target="_blank"><u>{{'DASHBOARD.OPEN-AIR-GUIDE' | translate}}</u></a> {{'DASHBOARD.LEARN-MORE' | translate}}
</p>
<p *ngIf="this.hasDmps()" class="card-content mb-0 pt-0">{{'DASHBOARD.DMP-ABOUT-BEG' | translate}}
<b>{{'DASHBOARD.DATASET-DESCRIPTIONS-DASHBOARD-TEXT' | translate}}</b>
{{'DASHBOARD.DMP-ABOUT-END' | translate}}
</p>
<div class="row d-flex align-items-center">
<div *ngIf="!this.hasDmps()" class="col-auto p-0 add-dataset-btn d-flex">
<div class="pr-2">
<button type="button" class="align-self-center normal-btn" (click)="openNewDmpDialog()">{{'DASHBOARD.START-YOUR-FIRST-DMP' | translate}}</button>
</div>
</div>
<div *ngIf="this.hasDmps()" class="col-auto p-0 new-dataset-tour add-dataset-btn col-auto d-flex">
<div class="pr-2">
<button mat-raised-button type="button" class="align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div>
</div>
<span class="col-auto ml-auto">
<img class="laptop-img\6" src="../../../assets/images/dashboard-popup.png">
</span>
</div>
</div>
</div> </div>
<div *ngIf="this.hasDmps()" class="col"> <div *ngIf="this.hasDmps()" class="col">
<div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div> <div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div>
<mat-tab-group color="#00000" mat-stretch-tabs="false" mat-align-tabs="start" class="my-mat-tab remove-border-bottom" [selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel"> <mat-tab-group color="#00000" mat-stretch-tabs="false" mat-align-tabs="start" class="my-mat-tab remove-border-bottom" [selectedIndex]="indexFromCurrentType" (selectedTabChange)="currentType = $event.tab.ariaLabel">
<mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}"> <mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'recent'" [includeDmps]="true" [includeDescriptions]="true"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'recent'" [includeDmps]="true" [includeDescriptions]="true"></app-recent-edited-activity>
<!-- <app-recent-edited-activity (totalCountRecentEdited)="onCountAllRecent($event)" [isActive]="currentType == 'recent'" [includeDmps]="true" [includeDescriptions]="true"></app-recent-edited-activity> -->
<div *ngIf="totalRecents === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div> <div *ngIf="totalRecents === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab> </mat-tab>
<mat-tab aria-label="drafts" label="{{'DASHBOARD.DRAFTS' | translate}}"> <mat-tab aria-label="drafts" label="{{'DASHBOARD.DRAFTS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'drafts'" [includeDmps]="true" [includeDescriptions]="true" [onlyDrafts]="true" type="drafts"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'drafts'" [includeDmps]="true" [includeDescriptions]="true" [onlyDrafts]="true" type="drafts"></app-recent-edited-activity>
<!-- <app-drafts (totalCountDraftDatasets)="onCountDraftDatasets($event)" [isActive]="currentType == 'drafts'"></app-drafts> -->
<div *ngIf="totalDraftDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div> <div *ngIf="totalDraftDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>> </mat-tab>>
<mat-tab aria-label="dmps" label="{{'DASHBOARD.DMPS' | translate}}"> <mat-tab aria-label="dmps" label="{{'DASHBOARD.DMPS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'dmps'" [includeDmps]="true" type="dmps"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'dmps'" [includeDmps]="true" type="dmps"></app-recent-edited-activity>
<!-- <app-recent-edited-dmp-activity (totalCountDmps)="onCountDmps($event)" [isActive]="currentType == 'dmps'"></app-recent-edited-dmp-activity> -->
<div *ngIf="totalDmps === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div> <div *ngIf="totalDmps === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab> </mat-tab>
<mat-tab aria-label="descriptions" label="{{'DASHBOARD.DESCRIPTIONS' | translate}}"> <mat-tab aria-label="descriptions" label="{{'DASHBOARD.DESCRIPTIONS' | translate}}">
<app-recent-edited-activity [isActive]="currentType == 'descriptions'" [includeDescriptions]="true" type="descriptions"></app-recent-edited-activity> <app-recent-edited-activity [isActive]="currentType == 'descriptions'" [includeDescriptions]="true" type="descriptions"></app-recent-edited-activity>
<!-- <app-recent-edited-description-activity (totalCountDatasets)="onCountDatasets($event)" [isActive]="currentType == 'descriptions'"></app-recent-edited-description-activity> -->
<div *ngIf="totalDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div> <div *ngIf="totalDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
<div *ngIf="totalDatasets === 0" class="col-auto d-flex justify-content-center"> <div *ngIf="totalDatasets === 0" class="col-auto d-flex justify-content-center">
<button mat-raised-button class="add-dataset" (click)="addNewDescription()"> <button mat-raised-button class="add-dataset" (click)="addNewDescription()">
@ -121,22 +117,26 @@
</div> </div>
<div class="col-auto col-xl-12"> <div class="col-auto col-xl-12">
<div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}" style="width: fit-content;"> <div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}" style="width: fit-content;">
<span>{{dashboardStatistics?.dmpCount}}</span></div> <span>{{dashboardStatistics?.dmpCount}}</span>
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.DMPS' | translate}}</a> </div>
<a [routerLink]="['/plans']" class="link">{{'DASHBOARD.DMPS' | translate}}</a>
</div> </div>
<div class="col-auto col-xl-12"> <div class="col-auto col-xl-12">
<div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}" style="width: fit-content;"> <div [ngClass]="{'counter': dashboardStatistics?.descriptionCount != 0, 'counter-zero': dashboardStatistics?.descriptionCount == 0}" style="width: fit-content;">
<span>{{dashboardStatistics?.descriptionCount}}</span></div> <span>{{dashboardStatistics?.descriptionCount}}</span>
<a [routerLink]="['/descriptions']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a> </div>
<a [routerLink]="['/descriptions']" class="link">{{'DASHBOARD.DESCRIPTIONS' | translate}}</a>
</div> </div>
<div class="col-auto col-xl-12"> <div class="col-auto col-xl-12">
<div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}" style="width: fit-content;"> <div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}" style="width: fit-content;">
<span>{{grantCount}}</span></div> <span>{{grantCount}}</span>
</div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a> <a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
</div> </div>
<div class="col-auto col-xl-12"> <div class="col-auto col-xl-12">
<div [ngClass]="{'counter': organizationCount != 0, 'counter-zero': organizationCount == 0}" style="width: fit-content;"> <div [ngClass]="{'counter': organizationCount != 0, 'counter-zero': organizationCount == 0}" style="width: fit-content;">
<span>{{organizationCount}}</span></div> <span>{{organizationCount}}</span>
</div>
<a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a> <a href="#" class="link-disabled">{{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}</a>
</div> </div>
</div> </div>
@ -169,23 +169,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- <div *ngIf="hasDmps()" class="col activity">
<div class="latest-activity-title">{{'DASHBOARD.LATEST-ACTIVITY' | translate}}</div>
<mat-tab-group mat-align-tabs="start" class="remove-border-bottom" ( [selectedIndex]="indexFromCurrentType" selectedTabChange)="currentType = $event.tab.ariaLabel">
<mat-tab aria-label="recent" label="{{'DASHBOARD.ALL' | translate}}">
<app-recent-edited-activity (totalCountRecentEdited)="onCountAllRecent($event)" [isActive]="currentType == 'recent'"></app-recent-edited-activity>
<div *ngIf="totalRecents === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<mat-tab aria-label="dmps" label="{{'DASHBOARD.PUBLIC-DMPS' | translate}}">
<app-recent-edited-dmp-activity (totalCountDmps)="onCountDmps($event)" [isActive]="currentType == 'dmps'"></app-recent-edited-dmp-activity>
<div *ngIf="totalDmps === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
<mat-tab aria-label="datasets" label="{{'DASHBOARD.PUBLIC-DATASETS' | translate}}">
<app-recent-edited-description-activity (totalCountDatasets)="onCountDatasets($event)" [isActive]="currentType == 'datasets'"></app-recent-edited-description-activity>
<div *ngIf="totalDatasets === 0" class="empty-list">{{'DASHBOARD.EMPTY-LIST' | translate}}</div>
</mat-tab>
</mat-tab-group>
</div> -->
</div> </div>
<div class="col-12 col-xl-auto mb-4 stats"> <div class="col-12 col-xl-auto mb-4 stats">
<div *ngIf="!hasDmps()" class="row flex-xl-column"> <div *ngIf="!hasDmps()" class="row flex-xl-column">
@ -212,10 +195,10 @@
<div *ngIf="hasDmps()" class="row flex-xl-column"> <div *ngIf="hasDmps()" class="row flex-xl-column">
<div class="col-12"> <div class="col-12">
<div class="personal-usage" ><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div> <div class="personal-usage"><span>{{'DASHBOARD.PUBLIC-USAGE' | translate}}</span></div>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}" ><span>{{dashboardStatistics?.dmpCount}}</span></div> <div [ngClass]="{'counter': dashboardStatistics?.dmpCount != 0, 'counter-zero': dashboardStatistics?.dmpCount == 0}"><span>{{dashboardStatistics?.dmpCount}}</span></div>
<a [routerLink]="['/explore-plans']" class="link">{{'DASHBOARD.PUBLIC-DMPS' | translate}}</a> <a [routerLink]="['/explore-plans']" class="link">{{'DASHBOARD.PUBLIC-DMPS' | translate}}</a>
</div> </div>
@ -225,7 +208,7 @@
</div> </div>
<div class="col-auto"> <div class="col-auto">
<div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}" ><span>{{grantCount}}</span></div> <div [ngClass]="{'counter': grantCount != 0, 'counter-zero': grantCount == 0}"><span>{{grantCount}}</span></div>
<a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a> <a href="#" class="link-disabled">{{'DASHBOARD.GRANTS' | translate}}</a>
</div> </div>

View File

@ -8,10 +8,7 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
import { DescriptionListingModule } from '../description/listing/description-listing.module'; import { DescriptionListingModule } from '../description/listing/description-listing.module';
import { DmpListingModule } from '../dmp/listing/dmp-listing.module'; import { DmpListingModule } from '../dmp/listing/dmp-listing.module';
import { StartNewDmpDialogModule } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.module'; import { StartNewDmpDialogModule } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.module';
import { DraftsComponent } from './drafts/drafts.component';
import { RecentEditedActivityComponent } from './recent-edited-activity/recent-edited-activity.component'; import { RecentEditedActivityComponent } from './recent-edited-activity/recent-edited-activity.component';
import { RecentEditedDescriptionActivityComponent } from './recent-edited-description-activity/recent-edited-description-activity.component';
import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/recent-edited-dmp-activity.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -19,7 +16,6 @@ import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/r
FormattingModule, FormattingModule,
DashboardRoutingModule, DashboardRoutingModule,
ConfirmationDialogModule, ConfirmationDialogModule,
// DatasetCopyDialogModule,
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
@ -30,9 +26,6 @@ import { RecentEditedDmpActivityComponent } from './recent-edited-dmp-activity/r
declarations: [ declarations: [
DashboardComponent, DashboardComponent,
RecentEditedActivityComponent, RecentEditedActivityComponent,
RecentEditedDmpActivityComponent,
RecentEditedDescriptionActivityComponent,
DraftsComponent
] ]
}) })
export class DashboardModule { } export class DashboardModule { }

View File

@ -1,222 +0,0 @@
.dmp-card,
.dataset-card {
min-width: 712px;
/* min-height: 308px; */
background: #ffffff 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #0000001a;
border-radius: 4px;
opacity: 1;
margin-top: 2.43rem;
margin-bottom: 1rem;
}
.remove-border-bottom ::ng-deep .mat-tab-header {
border-bottom: none;
}
input[type="text"] {
background: #fafafa 0% 0% no-repeat padding-box;
border: 1px solid #d1d1d1;
border-radius: 4px;
opacity: 1;
width: 347px;
height: 56px;
font-family: Arial, FontAwesome;
padding-left: 15px;
}
.edited-date {
text-align: left;
font-weight: 300;
line-height: 2.4;
letter-spacing: 0px;
color: #212121;
opacity: 0.6;
}
.dmp-label {
background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
opacity: 1;
min-width: 67px;
height: 37px;
color: #ffffff;
line-height: 2.4;
}
.dataset-label {
width: auto;
height: 37px;
background: var(--secondary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
text-align: left;
line-height: 2.8;
font-size: 0.875rem;
letter-spacing: 0px;
color: #212121;
font-weight: 400;
}
.icon-align {
display: inline-flex;
vertical-align: middle;
/* line-height: .9em; */
/* padding-bottom: 0.4rem; */
}
.dataset-card-actions,
.dmp-card-actions {
display: flex;
flex-direction: row;
border-top: 1px solid #dbdbdb;
line-height: 4;
color: #848484;
}
.dataset-card-actions a,
.dmp-card-actions a {
color: #848484 !important;
text-decoration: none !important;
}
.dataset-card-actions a:hover,
.dmp-card-actions a:hover {
color: var(--primary-color) !important;
}
.dmp-dataset-descriptions-title {
color: #000000;
opacity: 0.6;
padding-top: 1.5rem;
padding-bottom: 0.8rem;
}
.dmp-dataset-descriptions-name {
color: #000000;
opacity: 0.6;
font-weight: 700;
}
.show-more {
color: black !important;
}
.show-more:hover {
color: var(--primary-color) !important;
}
.btn-load-more {
border: 2px solid #212121;
border-radius: 30px;
opacity: 1;
min-width: 132px;
width: auto;
height: 40px;
margin-top: 4.125rem;
}
.btn-load-more:hover {
background-color: black;
color: white;
}
.draft {
color: #f16868;
}
.pointer {
cursor: pointer;
}
.search-form {
text-align: left;
width: 20rem;
}
.search-form mat-icon {
color: var(--primary-color);
}
::ng-deep .search-form .mat-form-field-wrapper {
background-color: white !important;
padding-bottom: 0 !important;
}
::ng-deep .sort-form .mat-form-field-wrapper {
background-color: white !important;
padding-bottom: 0 !important;
}
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
padding: 0.3rem 0rem 0.6rem 0rem !important;
}
/* .grey {
color: rgb(162, 162, 162);
}
.card-draft {
height: calc(100% - 60px);
}
.draft-desc {
position: relative;
overflow: hidden;
height: 60px;
font-size: 14px;
padding-top: 15px;
margin-bottom: 30px;
}
.draft-desc:after {
content: "";
text-align: right;
position: absolute;
bottom: 0;
right: 0;
width: 70%;
height: 1.4em;
background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);
}
td:hover .draft-desc:after {
background: rgba(255, 255, 255, 0);
}
.draft-subtitle {
font-weight: 400;
color: rgb(162, 162, 162);
}
.draft-title {
font-weight: 500;
color: black;
}
.drafts-more-btn {
text-align: right;
}
.grant-pill {
width: 80%;
border: 1px solid rgb(231, 230, 230);
color: rgb(145, 145, 145);
background-color: rgb(242, 242, 242);
border-radius: 10em;
text-align: center;
max-width: 160px;
padding-left: 0.5em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.view-all {
margin-left: auto;
margin-bottom: 0px !important;
color: #6aa4d9;
}
.view-all:hover {
color: rgb(46, 117, 182) !important;
} */

View File

@ -1,47 +0,0 @@
<div class="container-fluid">
<div class="row">
<div class="col-md-12 d-flex justify-content-center" *ngIf="listingItems == null">
<span class="empty-list">{{'DMP-LISTING.EMPTY-LIST' | translate}}</span>
</div>
<div *ngIf="listingItems != null" id="results" class="col-12" #results>
<div class="row pt-4">
<!-- Sort by -->
<div class="col-12 col-xl-auto d-flex align-items-center">
<span class="mb-4">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
</div>
<div class="col-12 col-xl-auto">
<mat-form-field appearance="outline" class="sort-form w-100">
<mat-select placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option [value]="order.UpdatedAt">{{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}}</mat-option>
<mat-option [value]="order.Label">{{enumUtils.toRecentActivityOrderString(order.Label)}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<!-- End of Sort by -->
<!-- Search Filter-->
<div class="col-12 col-xl-auto ml-auto">
<mat-form-field appearance="outline" class="search-form w-100" floatLabel="never">
<mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<!-- End of Search Filter -->
</div>
<div *ngIf="listingItems && listingItems.length > 0 && pageSize > pageLessSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadLess()">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component *ngIf="item.dmp" [showDivider]="i != (listingItems.length - 1)" [dmp]="item.dmp" [isPublic]="false"></app-dmp-listing-item-component>
<app-description-listing-item-component *ngIf="item.description" [showDivider]="i != (listingItems.length - 1)" [description]="item.description" [isPublic]="false" ></app-description-listing-item-component>
</div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="listingItems && listingItems.length > 0 && listingItems.length < pageSize">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="listingItems && listingItems.length > 0 && (listingItems.length >= startIndex + pageSize)" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
</div>
</div>

View File

@ -1,250 +0,0 @@
import { Location } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { Dmp, DmpDescriptionTemplate, DmpUser } from "@app/core/model/dmp/dmp";
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { Reference } from '@app/core/model/reference/reference';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { DashboardService } from "@app/core/services/dashboard/dashboard.service";
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { AuthService } from '../../../core/services/auth/auth.service';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({
selector: 'app-drafts',
templateUrl: './drafts.component.html',
styleUrls: ['./drafts.component.css']
})
export class DraftsComponent extends BaseComponent implements OnInit {
lookup: RecentActivityItemLookup = new RecentActivityItemLookup();
pageSize: number = 5;
pageLessSize = this.pageSize;
listingItems: RecentActivityItem[] = [];
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
publicMode = false;
order = RecentActivityOrder;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
page: number = 1;
@Input() isActive: boolean = false;
constructor(
private route: ActivatedRoute,
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private dashboardService: DashboardService,
private location: Location,
private dmpService: DmpService,
private analyticsService: AnalyticsService
) {
super();
}
ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity);
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (this.isAuthenticated()) {
if (order === undefined || (order != this.order.UpdatedAt && order != this.order.Label && order != this.order.Status)) {
order = this.order.UpdatedAt;
}
} else {
//TODO refactor
// if (order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) {
// order = this.order.PUBLISHED;
// }
}
this.formGroup.get('order').setValue(order);
let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword'];
this.formGroup.get("like").setValue(keyword);
this.updateUrl();
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
this.refresh();
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=drafts" +
(this.page != 1 ? "&page=" + this.page : "") +
//TODO refactor
//(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
refresh(): void {
this.lookup.onlyDraft = true;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.orderField = this.formGroup.get('order').value ?? this.order.UpdatedAt;
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
fields: [
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.description)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.version)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.versionStatus)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.hash)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.CreateNewVersionDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.DeleteDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.CloneDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.FinalizeDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.ExportDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.AssignDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.EditDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.EditDescription].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.DeleteDescription].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
]
};
this.getItems();
}
loadMore() {
this.pageSize = this.pageSize + this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
loadLess() {
this.pageSize = this.pageSize - this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
private getItems() {
this.listingItems = [];
this.dashboardService
.getMyRecentActivityItems(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
response.forEach(item => {
if (item.dmp) {
if (item.dmp.descriptions) {
if (item.dmp.status == DmpStatus.Finalized) {
item.dmp.descriptions = item.dmp.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
} else {
item.dmp.descriptions = item.dmp.descriptions.filter(x => x.isActive === IsActive.Active && x.status != DescriptionStatus.Canceled);
}
}
item.dmp.dmpUsers = item.dmp.dmpUsers.filter(x => x.isActive === IsActive.Active);
this.listingItems.push(item);
}
if (item.description) {
if (item.description.status != DescriptionStatus.Canceled) this.listingItems.push(item);
}
})
});
}
}

View File

@ -130,14 +130,6 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn
} }
updateUrl() { updateUrl() {
// let parameters = "" +
// (this.page != 1 ? "&page=" + this.page : "") +
// //TODO refactor
// // (((this.formGroup.get("order").value != this.order.UpdatedAt && !this.publicMode) || (this.formGroup.get("order").value != this.order.Published && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
// (this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
// this.location.go(this.router.url.split('?')[0] + parameters);
let parametersArray: string[] = [ let parametersArray: string[] = [
...(this.type ? ["type=" + this.type] : []), ...(this.type ? ["type=" + this.type] : []),
...(this.currentPage > 1 ? ["page=" + this.currentPage] : []), ...(this.currentPage > 1 ? ["page=" + this.currentPage] : []),

View File

@ -1,45 +0,0 @@
<div class="container-fluid">
<div class="row">
<div *ngIf="listingItems != null" id="descriptions" class="col-12" #descriptions>
<div class="row pt-4">
<!-- Sort by -->
<div class="col-12 col-xl-auto d-flex align-items-center">
<span class="mb-4">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
</div>
<div class="col-12 col-xl-auto">
<mat-form-field appearance="outline" class="sort-form w-100">
<mat-select placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option *ngIf="!publicMode" [value]="order.UpdatedAt">{{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}}</mat-option>
<!-- <mat-option *ngIf="publicMode" [value]="order.DATASETPUBLISHED">{{enumUtils.toRecentActivityOrderString(order.DATASETPUBLISHED)}}</mat-option> -->
<mat-option [value]="order.Label">{{enumUtils.toRecentActivityOrderString(order.Label)}}</mat-option>
<mat-option *ngIf="!publicMode" [value]="order.Status">{{enumUtils.toRecentActivityOrderString(order.Status)}}</mat-option>
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
</div>
<!-- End of Sort by -->
<!-- Search Filter-->
<div class="col-12 col-xl-auto ml-auto">
<mat-form-field appearance="outline" class="search-form w-100" floatLabel="never">
<mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<!-- End of Search Filter -->
</div>
<div *ngIf="listingItems && listingItems.length > 0 && pageSize > pageLessSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadLess()">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let item of listingItems; let i = index">
<app-description-listing-item-component *ngIf="item" [showDivider]="i != (listingItems.length - 1)" [description]="item" [isPublic]="false" ></app-description-listing-item-component>
</div>
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="listingItems && listingItems.length > 0 && listingItems.length < pageSize">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="listingItems && listingItems.length > 0 && listingItems.length >= pageSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
</div>
</div>

View File

@ -1,137 +0,0 @@
.remove-border-bottom ::ng-deep .mat-tab-header {
border-bottom: none;
}
input[type="text"] {
background: #fafafa 0% 0% no-repeat padding-box;
border: 1px solid #d1d1d1;
border-radius: 4px;
opacity: 1;
width: 347px;
height: 56px;
font-family: Arial, FontAwesome;
padding-left: 15px;
}
.dmp-label {
background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
opacity: 1;
min-width: 67px;
height: 37px;
color: #ffffff;
line-height: 2.4;
}
.description-label {
width: auto;
height: 37px;
background: var(--secondary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
text-align: left;
line-height: 2.8;
font-size: 0.875rem;
letter-spacing: 0px;
color: #212121;
font-weight: 400;
}
.icon-align {
display: inline-flex;
vertical-align: middle;
// line-height: .9em;
// padding-bottom: 0.4rem;
}
.dmp-subtitle,
.description-subtitle {
.icon-align {
display: inline-flex;
vertical-align: top;
margin-right: .2rem;
line-height: .95em;
}
}
.description-card-actions,
.dmp-card-actions {
display: flex;
flex-direction: row;
border-top: 1px solid #dbdbdb;
line-height: 4;
color: #848484;
}
.description-card-actions a,
.dmp-card-actions a {
color: #848484 !important;
text-decoration: none !important;
}
.description-card-actions a:hover,
.dmp-card-actions a:hover {
color: var(--primary-color) !important;
}
.dmp-description-descriptions-title {
color: #000000;
opacity: 0.6;
padding-top: 1.5rem;
padding-bottom: 0.8rem;
}
.dmp-description-descriptions-name {
color: #000000;
opacity: 0.6;
font-weight: 700;
}
.show-more {
color: black !important;
}
.show-more:hover {
color: var(--primary-color) !important;
}
.btn-load-more {
border: 2px solid #212121;
border-radius: 30px;
opacity: 1;
min-width: 132px;
width: auto;
height: 40px;
margin-top: 4.125rem;
}
.btn-load-more:hover {
background-color: black;
color: white;
}
.draft {
color: #f16868;
}
.pointer {
cursor: pointer;
}
.search-form {
text-align: left;
width: 20rem;
}
.search-form mat-icon {
color: var(--primary-color);
}
::ng-deep .search-form .mat-form-field-wrapper {
background-color: white !important;
padding-bottom: 0 !important;
}
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
padding: 0.3rem 0rem 0.6rem 0rem !important;
}

View File

@ -1,196 +0,0 @@
import { Location } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { Dmp, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DashboardService } from '@app/core/services/dashboard/dashboard.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({
selector: 'app-recent-edited-description-activity',
templateUrl: './recent-edited-description-activity.component.html',
styleUrls: ['./recent-edited-description-activity.component.scss']
})
export class RecentEditedDescriptionActivityComponent extends BaseComponent implements OnInit {
lookup: RecentActivityItemLookup = new RecentActivityItemLookup();
pageSize: number = 5;
pageLessSize= this.pageSize;
listingItems: Description[] = [];
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
publicMode = false;
order = RecentActivityOrder;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
page: number = 1;
@Input() isActive: boolean = false;
constructor(
private route: ActivatedRoute,
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private dashboardService: DashboardService,
private location: Location,
private analyticsService: AnalyticsService
) {
super();
}
ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity);
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (this.isAuthenticated()) {
if (order === undefined || (order != this.order.UpdatedAt && order != this.order.Label && order != this.order.Status)) {
order = this.order.UpdatedAt;
}
} else {
//TODO refactor
// if (order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) {
// order = this.order.PUBLISHED;
// }
}
this.formGroup.get('order').setValue(order);
let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword'];
this.formGroup.get("like").setValue(keyword);
this.updateUrl();
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => {
console.log('valueChanges');
this.refresh()
});
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
this.refresh();
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=descriptions" +
(this.page != 1 ? "&page=" + this.page : "") +
//TODO refactor
//(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
refresh(): void {
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.onlyDescription = true;
this.lookup.orderField = this.formGroup.get('order').value ??this.order.UpdatedAt;
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
fields: [
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.EditDescription].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.DeleteDescription].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
[nameof<RecentActivityItem>(x => x.description), nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
]
};
this.getItems();
}
loadMore() {
this.pageSize = this.pageSize + this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
loadLess() {
this.pageSize = this.pageSize - this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
getItems(){
this.listingItems = [];
this.dashboardService
.getMyRecentActivityItems(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
response.forEach(item => {
if (item.description){
if (item.description.status != DescriptionStatus.Canceled) this.listingItems.push(item.description);
}
})
});
}
}

View File

@ -1,200 +0,0 @@
.dmp-card, .dataset-card {
min-width: 712px;
/* min-height: 308px; */
background: #ffffff 0% 0% no-repeat padding-box;
box-shadow: 0px 3px 6px #0000001a;
border-radius: 4px;
opacity: 1;
margin-top: 2.43rem;
margin-bottom: 1rem;
}
.remove-border-bottom ::ng-deep .mat-tab-header {
border-bottom: none;
}
input[type="text"] {
background: #fafafa 0% 0% no-repeat padding-box;
border: 1px solid #d1d1d1;
border-radius: 4px;
opacity: 1;
width: 347px;
height: 56px;
font-family: Arial, FontAwesome;
padding-left: 15px;
}
.dmp-label {
background: var(--primary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
opacity: 1;
min-width: 67px;
height: 37px;
color: #ffffff;
line-height: 2.4;
}
.dataset-label {
width: auto;
height: 37px;
background: var(--secondary-color) 0% 0% no-repeat padding-box;
border-radius: 4px 0px;
text-align: left;
line-height: 2.8;
font-size: 0.875rem;
letter-spacing: 0px;
color: #212121;
}
.icon-align {
display: inline-flex;
vertical-align: middle;
/* line-height: .9em; */
/* padding-bottom: 0.4rem; */
}
.dataset-card-actions, .dmp-card-actions {
display: flex;
flex-direction: row;
border-top: 1px solid #dbdbdb;
line-height: 4;
color: #848484;
}
.dataset-card-actions a, .dmp-card-actions a {
color: #848484 !important;
text-decoration: none !important;
}
.dataset-card-actions a:hover, .dmp-card-actions a:hover {
color: var(--primary-color) !important;
}
.dmp-dataset-descriptions-title {
color: #000000;
opacity: 0.6;
padding-top: 1.5rem;
padding-bottom: 0.8rem;
}
.dmp-dataset-descriptions-name {
color: #000000;
opacity: 0.6;
font-weight: 700;
}
.show-more {
color: black !important;
}
.show-more:hover {
color: var(--primary-color) !important;
}
.btn-load-more {
border: 2px solid #212121;
border-radius: 30px;
opacity: 1;
min-width: 132px;
width: auto;
height: 40px;
margin-top: 4.125rem;
}
.btn-load-more:hover {
background-color: black;
color: white;
}
.draft {
color: #f16868;
}
.pointer {
cursor: pointer;
}
.search-form {
text-align: left;
width: 20rem;
}
.search-form mat-icon {
color: var(--primary-color);
}
::ng-deep .search-form .mat-form-field-wrapper {
background-color: white !important;
padding-bottom: 0 !important;
}
::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix {
padding: 0.3rem 0rem 0.6rem 0rem !important;
}
/* th {
text-transform: uppercase;
}
a {
color: #212529;
}
.table-row {
cursor: pointer;
display: table-row;
}
.is-public {
padding-left: 5px;
padding-right: 5px;
border: 1px solid var(--primary-color-3)3b;
color: var(--primary-color-3);
background-color: var(--primary-color-3)0f;
border-radius: 10em;
text-align: center;
}
.template-name {
padding-left: 0.5em;
border: 1px solid rgb(218, 227, 243);
color: rgb(43, 104, 209);
background-color: rgb(236, 241, 249);
border-radius: 10em;
text-align: center;
max-width: 160px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chip {
padding: 0.1em 1em;
margin-bottom: 1em;
margin-left: 2.5em;
margin-right: 2.5em;
border-radius: 10em;
background-color: #0d7489;
color: #fff;
text-transform: uppercase;
text-align: center;
font-weight: 500;
max-width: 160px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mat-icon-button :hover {
color: rgb(120, 173, 220);
}
.view-all {
margin-left: auto;
margin-bottom: 0px !important;
color: #6aa4d9;
}
.view-all:hover {
color: rgb(46, 117, 182) !important;
} */

View File

@ -1,117 +0,0 @@
<div class="container-fluid">
<div class="row">
<div *ngIf="listingItems != null" id="dmps" class="col-12" #dmps>
<div class="row pt-4">
<!-- Sort by -->
<div class="col-12 col-xl-auto d-flex align-items-center">
<span class="mb-4">{{'DMP-LISTING.SORT-BY' | translate}}:</span>
</div>
<div class="col-12 col-xl-auto">
<mat-form-field appearance="outline" class="sort-form w-100">
<mat-select placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" [formControl]="formGroup.get('order')">
<mat-option *ngIf="!publicMode" [value]="order.UpdatedAt">{{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}}</mat-option>
<!-- <mat-option *ngIf="publicMode" [value]="order.PUBLISHED">{{enumUtils.toRecentActivityOrderString(order.PUBLISHED)}}</mat-option> -->
<mat-option [value]="order.Label">{{enumUtils.toRecentActivityOrderString(order.Label)}}</mat-option>
<mat-option *ngIf="!publicMode" [value]="order.Status">{{enumUtils.toRecentActivityOrderString(order.Status)}}</mat-option>
<!-- <mat-option [value]="order.CREATED">{{enumUtils.toRecentActivityOrderString(order.CREATED)}}</mat-option> -->
</mat-select>
</mat-form-field>
</div>
<!-- End of Sort by -->
<!-- Search Filter-->
<div class="col-12 col-xl-auto ml-auto">
<mat-form-field appearance="outline" class="search-form w-100" floatLabel="never">
<mat-icon matSuffix>search</mat-icon>
<input matInput placeholder="{{'GENERAL.CRITERIA.LIKE'| translate}}" name="likeCriteria" [formControl]="formGroup.get('like')">
<mat-error *ngIf="formGroup.get('like').hasError('backendError')">{{formGroup.get('like').getError('backendError').message}}</mat-error>
</mat-form-field>
</div>
<!-- End of Search Filter -->
</div>
<div *ngIf="listingItems && listingItems.length > 0 && pageSize > pageLessSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadLess()">{{'GENERAL.ACTIONS.LOAD-LESS' | translate}}</button>
</div>
<div *ngFor="let item of listingItems; let i = index">
<app-dmp-listing-item-component *ngIf="item" [showDivider]="i != (listingItems.length - 1)" [dmp]="item" [isPublic]="false"></app-dmp-listing-item-component>
</div>
<!-- <div *ngFor="let activity of listingItems">
<div class="dmp-card">
<a [routerLink]="navigateToUrl(activity.id)" class="pointer">
<div class="d-flex flex-direction-row">
<div class="col-auto dmp-label">{{ 'DMP-LISTING.DMP' | translate }}</div>
<div *ngIf="!publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modifiedTime | dateTimeCultureFormatter: "d MMMM y" }}</div>
<div *ngIf="publicMode" class="col-auto ml-auto edited-date">{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}</div>
</div>
<div class="col-auto" [ngClass]="{'dmp-title': activity.status === 1, 'dmp-title-draft': activity.status === 0}">{{activity.label}}</div>
<div class="dmp-subtitle">
<span class="col-auto">{{ roleDisplay(activity.users) }}</span>
<span>.</span>
<span class="col-auto" *ngIf="activity.status === 1 && activity.public === true"><span class="material-icons icon-align">public</span>{{'TYPES.DMP-VISIBILITY.PUBLIC' | translate}}</span>
<span *ngIf="activity.status === 1 && activity.public === false" class="col-auto"><span class="material-icons icon-align">done</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span *ngIf="activity.status === 0" class=" col-auto draft"><span class="material-icons icon-align">create</span>{{ enumUtils.toDmpStatusString(activity.status) }}</span>
<span>.</span>
<span class="col-auto">{{'DMP-LISTING.VERSION' | translate}} {{activity.version}}</span>
<span>.</span>
<span class="col">{{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}}</span>
</div>
<div class="col-auto dmp-dataset-descriptions-title">{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ activity.datasets.length }})
</div>
<div *ngFor="let dataset of activity.datasets; let i = index; let last = last" [ngClass]="{'pb-3': i === activity.datasets.length - 1}">
<div *ngIf="i < 3">
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="!last && i !== 2">{{dataset.label}},</div>
<div class="col-auto dmp-dataset-descriptions-name" *ngIf="last || i == 2">{{dataset.label}}</div>
</div>
</div>
<a class="d-flex justify-content-center pb-3 show-more" *ngIf="activity.datasets.length > 3" [routerLink]="navigateToUrl(activity.id)"><u>{{'GENERAL.ACTIONS.SHOW-MORE' | translate}}</u></a>
</a>
<div class="dmp-card-actions">
<a class="col-auto border-right pointer" [matMenuTriggerFor]="exportMenu"><span class="material-icons icon-align pr-2">open_in_new</span>{{'DMP-LISTING.ACTIONS.EXPORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isDraftDmp(activity)" [routerLink]="['/plans/edit/' + activity.id]" target="_blank"><span class="material-icons icon-align">add</span>{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isUserOwner(activity)" (click)="openShareDialog(activity.id, activity.label)"><span class="material-icons icon-align pr-2">group_add</span>{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="isAuthenticated()" (click)="cloneOrNewVersionClicked(activity, false)"><span class="material-icons icon-align pr-2">filter_none</span>{{'DMP-LISTING.ACTIONS.CLONE' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isAuthenticated()" (click)="viewVersions(activity.groupId, activity.label, activity)"><span class="material-icons icon-align pr-2">library_books</span>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}</a>
<a class="col-auto border-right pointer" *ngIf="!isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteClicked(activity.id)"><span class="material-icons icon-align pr-2">delete</span>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}</a>
<a class="col-auto pointer" *ngIf="isAuthenticated()" [matMenuTriggerFor]="actionsMenu"><span class="material-icons icon-align pl-2">more_horiz</span></a>
</div>
<mat-menu #exportMenu="matMenu" xPosition="before">
<button mat-menu-item (click)="downloadPDF(activity.id)">
<i class="fa fa-file-pdf-o pr-2"></i>
<span>{{'GENERAL.FILE-TRANSFOMER.PDF' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadDocx(activity.id)">
<i class="fa fa-file-word-o pr-2"></i>
<span>{{'GENERAL.FILE-TRANSFOMER.DOC' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadXml(activity.id)">
<i class="fa fa-file-code-o pr-2"></i>
<span>{{'GENERAL.FILE-TRANSFOMER.XML' | translate}}</span>
</button>
<button mat-menu-item (click)="downloadJson(activity.id)">
<i class="fa fa-file-o pr-2"></i>
<span>{{'GENERAL.FILE-TRANSFOMER.JSON' | translate}}</span>
</button>
</mat-menu>
<mat-menu #actionsMenu="matMenu" xPosition="before">
<button *ngIf="isUserOwner(activity)" mat-menu-item (click)="cloneOrNewVersionClicked(activity, true)">
<mat-icon>queue</mat-icon>{{'DMP-LISTING.ACTIONS.NEW-VERSION' | translate}}
</button>
<button mat-menu-item (click)="viewVersions(activity.groupId, activity.label, activity)">
<mat-icon>library_books</mat-icon>{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}}
</button>
<button mat-menu-item *ngIf="isDraftDmp(activity) && isUserOwner(activity)" (click)="deleteClicked(activity.id)" class="menu-item">
<mat-icon>delete</mat-icon>{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }}
</button>
</mat-menu>
</div>
</div> -->
<div class="text-muted d-flex justify-content-center mt-5" *ngIf="listingItems && listingItems.length > 0 && listingItems.length < pageSize">
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
</div>
<div *ngIf="listingItems && listingItems.length > 0 && listingItems.length >= pageSize" class="d-flex justify-content-center">
<button type="button" class="btn-load-more" (click)="loadMore()">{{'GENERAL.ACTIONS.LOAD-MORE' | translate}}</button>
</div>
</div>
</div>
</div>

View File

@ -1,224 +0,0 @@
import { Location } from '@angular/common';
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
import { RecentActivityItem } from '@app/core/model/dashboard/recent-activity-item';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference';
import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup';
import { AuthService } from '@app/core/services/auth/auth.service';
import { DashboardService } from '@app/core/services/dashboard/dashboard.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { BaseComponent } from '@common/base/base.component';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
@Component({
selector: 'app-recent-edited-dmp-activity',
templateUrl: './recent-edited-dmp-activity.component.html',
styleUrls: ['./recent-edited-dmp-activity.component.css']
})
export class RecentEditedDmpActivityComponent extends BaseComponent implements OnInit {
lookup: RecentActivityItemLookup = new RecentActivityItemLookup();
pageSize: number = 5;
pageLessSize = this.pageSize;
@Output() totalCountDmps: EventEmitter<any> = new EventEmitter();
@ViewChild("dmps") resultsContainer;
listingItems: Dmp[] = [];
isDraft: boolean;
totalCount: number;
startIndex: number = 0;
offsetLess: number = 0;
dmpFormGroup: UntypedFormGroup;
public formGroup = new UntypedFormBuilder().group({
like: new UntypedFormControl(),
order: new UntypedFormControl()
});
publicMode = false;
order = RecentActivityOrder;
page: number = 1;
@Input() isActive: boolean = false;
constructor(
private route: ActivatedRoute,
private router: Router,
public enumUtils: EnumUtils,
private authentication: AuthService,
private dashboardService: DashboardService,
private location: Location,
private analyticsService: AnalyticsService
) {
super();
}
ngOnInit() {
this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity);
this.route.queryParams.subscribe(params => {
if (this.isActive) {
let page = (params['page'] === undefined) ? 1 : +params['page'];
this.page = (page <= 0) ? 1 : page;
this.startIndex = (this.page - 1) * this.pageSize;
if (this.page > 1) {
this.offsetLess = (this.page - 2) * this.pageSize;
}
let order = params['order'];
if (this.isAuthenticated()) {
//TODO refactor
// if (order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL && order != this.order.STATUS)) {
// order = this.order.MODIFIED;
// }
} else {
//TODO refactor
// if (order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) {
// order = this.order.PUBLISHED;
// }
}
this.formGroup.get('order').setValue(order);
let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword'];
this.formGroup.get("like").setValue(keyword);
this.updateUrl();
}
});
this.formGroup.get('like').valueChanges
.pipe(takeUntil(this._destroyed), debounceTime(500))
.subscribe(x => this.refresh());
this.formGroup.get('order').valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(x => this.refresh());
this.refresh();
}
ngOnChanges() {
if (this.isActive) {
this.updateUrl();
}
}
updateUrl() {
let parameters = "?type=dmps" +
(this.page != 1 ? "&page=" + this.page : "") +
//TODO refactor
//(((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order=" + this.formGroup.get("order").value : "") +
(this.formGroup.get("like").value ? ("&keyword=" + this.formGroup.get("like").value) : "");
this.location.go(this.router.url.split('?')[0] + parameters);
}
public isAuthenticated(): boolean {
return this.authentication.currentAccountIsAuthenticated();
}
refresh(): void {
this.lookup.page = { size: this.pageSize, offset: 0 };
this.lookup.onlyDmp = true;
this.lookup.orderField = this.formGroup.get('order').value ?? this.order.UpdatedAt;
this.lookup.like = this.formGroup.get('like').value;
this.lookup.project = {
fields: [
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.description)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.versionStatus)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.version)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.groupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.updatedAt)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.hash)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.CreateNewVersionDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.DeleteDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.CloneDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.FinalizeDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.ExportDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.AssignDmpUsers].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.EditDmp].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.label)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
[nameof<RecentActivityItem>(x => x.dmp), nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.groupId)].join('.'),
]
};
this.getItems();
}
loadMore() {
this.pageSize = this.pageSize + this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
loadLess() {
this.pageSize = this.pageSize - this.pageLessSize;
this.lookup.page = { size: this.pageSize, offset: 0 };
this.getItems();
}
private getItems() {
this.listingItems = [];
this.dashboardService
.getMyRecentActivityItems(this.lookup)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
response.forEach(item => {
if (item.dmp) {
item.dmp.dmpUsers = item.dmp.dmpUsers.filter(x => x.isActive === IsActive.Active);
if (item.dmp.descriptions) {
if (item.dmp.status == DmpStatus.Finalized) {
item.dmp.descriptions = item.dmp.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
} else {
item.dmp.descriptions = item.dmp.descriptions.filter(x => x.isActive === IsActive.Active && x.status != DescriptionStatus.Canceled);
}
}
this.listingItems.push(item.dmp);
}
})
});
}
}

View File

@ -63,24 +63,6 @@
padding-right: 6px; padding-right: 6px;
} }
.downloadPDF {
margin-top: 15px;
margin-bottom: 15px;
margin-right: 15px;
}
.downloadXML {
margin-top: 15px;
margin-bottom: 15px;
margin-right: 15px;
}
.downloadDOCX {
margin-top: 15px;
margin-bottom: 15px;
margin-right: 15px;
}
.updateDescriptionProfile { .updateDescriptionProfile {
margin-top: 15px; margin-top: 15px;
margin-bottom: 15px; margin-bottom: 15px;

View File

@ -124,44 +124,6 @@ export class DescriptionListingItemComponent extends BaseComponent implements On
return this.isPublic ? [`/explore-plans/overview/public/${this.description.dmp.id}`] : [`/plans/edit/${this.description.dmp.id}`]; return this.isPublic ? [`/explore-plans/overview/public/${this.description.dmp.id}`] : [`/plans/edit/${this.description.dmp.id}`];
} }
// downloadPDF(description: Description): void {
// this.descriptionService.downloadPDF(description.id.toString())
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/pdf' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('descriptions', "pdf", description.id.toString());
// });
// }
download(description: Description, format: string): void {
this.descriptionService.download(description.id.toString(), format)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body], { type: 'application/octet-stream' });
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.analyticsService.trackDownload('descriptions', format, description.id.toString());
});
}
downloadXML(description: Description): void {
//TODO: add file transformer service
// this.descriptionService.downloadXML(description.id as string)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/xml' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('descriptions', "xml", description.id);
// });
}
openShareDialog() { openShareDialog() {
// TODO: This is a shared component. Put it in a seperate module. // TODO: This is a shared component. Put it in a seperate module.
const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {

View File

@ -2,45 +2,44 @@ import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { UntypedFormBuilder, UntypedFormControl, Validators } from '@angular/forms'; import { UntypedFormBuilder, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params, Router } from '@angular/router';
import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpStatus } from '@app/core/common/enum/dmp-status';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description, DescriptionStatusPersist } from '@app/core/model/description/description'; import { Description, DescriptionStatusPersist } from '@app/core/model/description/description';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp'; import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference'; import { Reference } from '@app/core/model/reference/reference';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { DescriptionService } from '@app/core/services/description/description.service'; import { DescriptionService } from '@app/core/services/description/description.service';
import { DmpService } from '@app/core/services/dmp/dmp.service'; import { DmpService } from '@app/core/services/dmp/dmp.service';
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service'; import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
import { LockService } from '@app/core/services/lock/lock.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service'; import { ReferenceService } from '@app/core/services/reference/reference.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
import { DescriptionValidationOutput } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dialog/dmp-invitation-dialog.component';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver'; import { takeUntil } from 'rxjs/operators';
import { filter, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { DescriptionCopyDialogComponent } from '../description-copy-dialog/description-copy-dialog.component'; import { DescriptionCopyDialogComponent } from '../description-copy-dialog/description-copy-dialog.component';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DescriptionValidationOutput } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component';
import { LockService } from '@app/core/services/lock/lock.service';
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dialog/dmp-invitation-dialog.component';
import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({ @Component({
@ -122,19 +121,19 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
// this.users = this.description.dmp.users; // this.users = this.description.dmp.users;
this.checkLockStatus(this.description.id); this.checkLockStatus(this.description.id);
this.canDelete = (this.authService.hasPermission(AppPermission.DeleteDescription) || this.canDelete = (this.authService.hasPermission(AppPermission.DeleteDescription) ||
this.description.authorizationFlags?.some(x => x === AppPermission.DeleteDescription)) && this.description.belongsToCurrentTenant != false; this.description.authorizationFlags?.some(x => x === AppPermission.DeleteDescription)) && this.description.belongsToCurrentTenant != false;
this.canEdit = (this.authService.hasPermission(AppPermission.EditDescription) || this.canEdit = (this.authService.hasPermission(AppPermission.EditDescription) ||
this.description.authorizationFlags?.some(x => x === AppPermission.EditDescription)) && this.description.belongsToCurrentTenant != false; this.description.authorizationFlags?.some(x => x === AppPermission.EditDescription)) && this.description.belongsToCurrentTenant != false;
this.canReview = (this.authService.hasPermission(AppPermission.ReviewDescription) || this.canReview = (this.authService.hasPermission(AppPermission.ReviewDescription) ||
this.description.authorizationFlags?.some(x => x === AppPermission.ReviewDescription)) && this.description.belongsToCurrentTenant != false; this.description.authorizationFlags?.some(x => x === AppPermission.ReviewDescription)) && this.description.belongsToCurrentTenant != false;
this.canFinalize = (this.authService.hasPermission(AppPermission.FinalizeDescription) || this.canFinalize = (this.authService.hasPermission(AppPermission.FinalizeDescription) ||
this.description.authorizationFlags?.some(x => x === AppPermission.FinalizeDescription)) && this.description.belongsToCurrentTenant != false; this.description.authorizationFlags?.some(x => x === AppPermission.FinalizeDescription)) && this.description.belongsToCurrentTenant != false;
this.canInviteDmpUsers = (this.authService.hasPermission(AppPermission.InviteDmpUsers) || this.canInviteDmpUsers = (this.authService.hasPermission(AppPermission.InviteDmpUsers) ||
this.description.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers)) && this.description.belongsToCurrentTenant != false; this.description.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers)) && this.description.belongsToCurrentTenant != false;
// const breadCrumbs = []; // const breadCrumbs = [];
// breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DESCRIPTION-DESCRIPTIONS'), url: "/descriptions" }); // breadCrumbs.push({ parentComponentName: null, label: this.language.instant('NAV-BAR.MY-DESCRIPTION-DESCRIPTIONS'), url: "/descriptions" });
// breadCrumbs.push({ parentComponentName: 'DescriptionListingComponent', label: this.description.label, url: '/descriptions/overview/' + this.description.id }); // breadCrumbs.push({ parentComponentName: 'DescriptionListingComponent', label: this.description.label, url: '/descriptions/overview/' + this.description.id });
@ -327,48 +326,12 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
} }
getSectionNameById(sectionId: Guid): string { getSectionNameById(sectionId: Guid): string {
if (sectionId == null) return ''; if (sectionId == null) return '';
let sections: DmpBlueprintDefinitionSection[] = this.description?.dmp?.blueprint?.definition?.sections?.filter((section:DmpBlueprintDefinitionSection) => sectionId===section.id); let sections: DmpBlueprintDefinitionSection[] = this.description?.dmp?.blueprint?.definition?.sections?.filter((section: DmpBlueprintDefinitionSection) => sectionId === section.id);
return sections == null ? '' : sections[0].label; return sections == null ? '' : sections[0].label;
} }
// downloadPDF(id: string) {
// this.descriptionService.downloadPDF(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/pdf' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('descriptions', "pdf", id);
// });
// }
download(id: string, format: string) {
this.descriptionService.download(id, format)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body], { type: 'application/octet-stream' });
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.analyticsService.trackDownload('descriptions', format, id);
});
}
downloadXml(id: string) {
// TODO: add download
// this.descriptionService.downloadXML(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/xml' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('descriptions', "xml", id);
// });
}
openCopyToDmpDialog() { openCopyToDmpDialog() {
const formGroup = this.fb.group({ const formGroup = this.fb.group({
@ -427,35 +390,36 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
finalize(description: Description) { finalize(description: Description) {
this.descriptionService.validate([description.id]).pipe(takeUntil(this._destroyed) this.descriptionService.validate([description.id]).pipe(takeUntil(this._destroyed)
).subscribe(result => { ).subscribe(result => {
if (result[0].result == DescriptionValidationOutput.Invalid){ if (result[0].result == DescriptionValidationOutput.Invalid) {
this.router.navigate(['descriptions/edit/' + description.id + '/finalize']); this.router.navigate(['descriptions/edit/' + description.id + '/finalize']);
}else{ } else {
const dialogRef = this.dialog.open(ConfirmationDialogComponent, { const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
restoreFocus: false, restoreFocus: false,
data: { data: {
message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'), message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'),
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'), confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'),
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'), cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'),
isDeleteConfirmation: false isDeleteConfirmation: false
} }
}); });
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
const descriptionStatusPersist: DescriptionStatusPersist = { const descriptionStatusPersist: DescriptionStatusPersist = {
id: description.id, id: description.id,
status: DescriptionStatus.Finalized, status: DescriptionStatus.Finalized,
hash: description.hash hash: description.hash
}; };
this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed)) this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed))
.subscribe(data => { .subscribe(data => {
this.reloadPage(); this.reloadPage();
this.onUpdateCallbackSuccess() this.onUpdateCallbackSuccess()
}, (error: any) => { }, (error: any) => {
this.onUpdateCallbackError(error) this.onUpdateCallbackError(error)
}); });
}}); }
} });
}
}); });
} }
@ -517,7 +481,7 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.status)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags),AppPermission.InviteDmpUsers].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.authorizationFlags), AppPermission.InviteDmpUsers].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.id)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.label)].join('.'),
[nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'), [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.id)].join('.'),

View File

@ -1,7 +1,6 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormattingModule } from '@app/core/formatting.module'; import { FormattingModule } from '@app/core/formatting.module';
import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing'; import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing';
// import {GeneralTabComponent} from '@app/ui/dmp/editor/general-tab/general-tab.component';
import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonFormsModule } from '@common/forms/common-forms.module';
import { CommonUiModule } from '@common/ui/common-ui.module'; import { CommonUiModule } from '@common/ui/common-ui.module';
@ -16,57 +15,5 @@ import { CommonUiModule } from '@common/ui/common-ui.module';
], ],
exports: [ exports: [
] ]
// imports: [
// CommonUiModule,
// CommonFormsModule,
// ConfirmationDialogModule,
// FormattingModule,
// AutoCompleteModule,
// DmpRoutingModule,
// DmpOverviewModule,
// FormValidationErrorsDialogModule,
// MultipleChoiceDialogModule,
// DatasetEditorDetailsModule,
// DatasetDescriptionFormModule,
// NgxDropzoneModule,
// FormProgressIndicationModule,
// RichTextEditorModule
// ],
// declarations: [
// DmpListingComponent,
// DmpCriteriaComponent,
// DmpEditorComponent,
// InvitationAcceptedComponent,
// DmpToDatasetDialogComponent,
// DmpWizardComponent,
// DmpWizardEditorComponent,
// DmpWizardDatasetListingComponent,
// AddResearcherComponent,
// AvailableProfilesComponent,
// DmpFinalizeDialogComponent,
// DynamicFieldsGrantComponent,
// DynamicFieldGrantComponent,
// DmpUploadDialogue,
// DmpListingItemComponent,
// PeopleTabComponent,
// GrantTabComponent,
// DatasetsTabComponent,
// DmpCloneComponent,
// AddOrganizationComponent,
// DmpCriteriaDialogComponent,
// AddCostComponent,
// CostListingComponent,
// StartNewDmpDialogComponent,
// StartNewDatasetDialogComponent,
// MainInfoComponent,
// FundingInfoComponent,
// DatasetInfoComponent,
// LicenseInfoComponent,
// DatasetPreviewDialogComponent,
// DmpEditorBlueprintComponent
// ],
// exports: [
// DmpListingItemComponent
// ]
}) })
export class DmpModule { } export class DmpModule { }

View File

@ -1,112 +0,0 @@
<form class="dataset-editor-details" *ngIf="formGroup" [formGroup]="formGroup">
<div class="col-12 intro">
{{'DATASET-EDITOR.TITLE.INTRO' | translate}}
</div>
<div class="col-12 card">
<!-- Title Field -->
<div class="row">
<div class="col-12">
<div class="heading">1.1 {{'DATASET-EDITOR.FIELDS.TITLE' | translate}}*</div>
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span>
<a class="dmp-link dmp-tour-{{ formGroup.get('id').value + 1 }}" (click)="restartTour(formGroup.get('id').value + 1)">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a>
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
<div class="title-form">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.FIELDS.TITLE' | translate}}" type="text" name="label" formControlName="label" required>
<mat-error *ngIf="formGroup.get('label').hasError('backendError')"> {{formGroup.get('label').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
</div>
<!-- Description field -->
<div class="row">
<div class="col-12">
<div class="heading">1.2 {{'DATASET-EDITOR.FIELDS.DESCRIPTION' | translate}}</div>
<span class="hint">{{'DATASET-EDITOR.HINT.DESCRIPTION' | translate}}</span>
<!-- <span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span>
<a class="dmp-link dmp-tour-{{ formGroup.get('id').value + 2 }}" (click)="restartTour(formGroup.get('id').value + 2)">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a>
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span> -->
<div class="description-form">
<mat-form-field>
<textarea rows="3" matInput class="description-area" placeholder="{{'DMP-EDITOR.PLACEHOLDER.DESCRIPTION' | translate}}" formControlName="description"></textarea>
<mat-error *ngIf="formGroup.get('description').hasError('backendError')">{{formGroup.get('description').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('description').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
</div>
<!-- Uri field -->
<!-- <div class="row">
<div class="col-12">
<div class="heading">1.3 {{'DATASET-EDITOR.FIELDS.EXTERNAL-LINK' | translate}}</div>
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link" target="_blank" [routerLink]="['/overview/' + dmpId]">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
<div class="uri-form">
<mat-form-field>
<input matInput placeholder="{{'DATASET-EDITOR.PLACEHOLDER.EXTERNAL-LINK' | translate}}" type="text" name="uri" formControlName="uri">
<mat-error *ngIf="formGroup.get('uri').hasError('backendError')">{{formGroup.get('uri').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('uri').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
</div>
</div> -->
<!-- External Fields -->
<app-dataset-external-references-editor-component (formChanged)="onFormChanged($event)" [formGroup]="formGroup" [viewOnly]="viewOnly"></app-dataset-external-references-editor-component>
<!-- Template Field -->
<div class="heading">1.5 {{'DATASET-EDITOR.FIELDS.PROFILE' | translate}}*</div>
<div class="profile-form">
<mat-form-field>
<mat-select placeholder="{{'DATASET-WIZARD.FIRST-STEP.PROFILE'| translate}}" [required]="true" [compareWith]="compareWith" [formControl]="formGroup.get('profile')">
<mat-option *ngFor="let profile of availableProfiles" [value]="profile">
{{profile.label}}
</mat-option>
</mat-select>
<mat-error *ngIf="formGroup.get('profile').hasError('backendError')">{{formGroup.get('profile').getError('backendError').message}}</mat-error>
<mat-error *ngIf="formGroup.get('label').hasError('required')">{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
</mat-form-field>
</div>
<!-- Template Form -->
<div *ngIf="hasProfileId() && formGroup.get('datasetProfileDefinition') !== null">
<app-dataset-description [form]="formGroup.get('datasetProfileDefinition')" [visibilityRules]="formGroup.get('datasetProfileDefinition').get('rules').value" [datasetProfileId]="getProfileId()" (formChanged)="onFormChanged($event)"></app-dataset-description>
</div>
<!-- Tags field -->
<!-- <div class="row">
<div class="col-12">
<div class="heading">1.4 {{'DATASET-EDITOR.FIELDS.TAGS' | translate}}</div>
<span class="hint">{{'DATASET-EDITOR.HINT.TITLE' | translate}}</span><a class="dmp-link" target="_blank" [routerLink]="['/overview/' + this.datasetWizardModel.dmp.id]">{{'DATASET-EDITOR.FIELDS.DMP' | translate}}</a><span class="hint">{{'DATASET-EDITOR.HINT.TITLE-REST' | translate}}</span>
<div class="tags-form">
<mat-form-field appearance="outline">
<mat-chip-list #chipList [disabled]="viewOnly">
<mat-chip *ngFor="let tag of formGroup.get('tags').value"
[removable]="true" (removed)="removeTag(tag)">
{{tag.name}}
<mat-icon matChipRemove *ngIf="!viewOnly">cancel</mat-icon>
</mat-chip>
<input matInput [disabled]="viewOnly" placeholder="{{'DATASET-EDITOR.FIELDS.TAGS' | translate}}"
[matChipInputFor]="chipList"
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
[matChipInputAddOnBlur]="true"
(matChipInputTokenEnd)="addTag($event)">
</mat-chip-list>
</mat-form-field>
<ng-template #tagsTemplate let-suggestion let-i="index" let-callback="function">
<div class="col-12 row align-items-center">
<div class="col">
<p>
{{i+1}}) {{suggestion.get('name').value}}
</p>
</div>
<div class="col-auto">
<button mat-icon-button (click)="callback(i)" *ngIf='!viewOnly'>
<mat-icon>close</mat-icon>
</button>
</div>
</div>
</ng-template>
</div>
</div>
</div> -->
</div>
</form>

View File

@ -1,109 +0,0 @@
.dataset-editor-details {
// position: relative;
// left: 362px;
// width: calc(100% - 366px);
.intro {
text-align: left;
font-weight: 400;
letter-spacing: 0px;
color: #212121;
opacity: 1;
margin: 3rem 0rem 3rem 0rem;
}
.heading {
text-align: left;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-top: 1.625rem;
margin-bottom: 0.625rem;
}
.hint {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0px;
color: #212121;
opacity: 0.81;
margin-bottom: 2.125rem;
}
.title-form,
.description-form,
.profile-form {
text-align: left;
font-weight: 400;
font-size: 16px;
letter-spacing: 0.15px;
color: #7d7d7d;
opacity: 1;
margin-bottom: 1rem;
}
// textarea::placeholder {
// font-style: oblique;
// }
.input-btn {
border: none;
color: #aaaaaa;
background-color: #ffffff00;
cursor: pointer;
}
.input-btn :hover {
color: var(--primary-color-3) !important;
}
.dmp-link {
color: #3fafac;
font-weight: 400;
font-size: 16px;
cursor: pointer;
}
.dmp-link:hover {
text-decoration: underline;
}
}
::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .uri-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-outline {
background: #fafafa !important;
}
::ng-deep .title-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
::ng-deep .description-form .mat-form-field-appearance-outline .mat-form-field-infix {
// font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
::ng-deep .uri-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}
::ng-deep .tags-form .mat-form-field-appearance-outline .mat-form-field-infix {
font-size: 1rem;
padding: 0.6em 0 1em 0 !important;
}

View File

@ -1,278 +0,0 @@
import { BaseComponent } from '@common/base/base.component';
import { OnInit, Component, Input, Output, EventEmitter } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { MatChipInputEvent } from '@angular/material/chips';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { ActivatedRoute, Router } from '@angular/router';
import { DmpService } from '@app/core/services/dmp/dmp.service';
import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service';
import { FormService } from '@common/forms/form-service';
import { LockService } from '@app/core/services/lock/lock.service';
import { AuthService } from '@app/core/services/auth/auth.service';
import { UntypedFormGroup, FormControl, UntypedFormArray } from '@angular/forms';
import { takeUntil, map, catchError } from 'rxjs/operators';
import { RequestItem } from '@app/core/query/request-item';
import { isNullOrUndefined } from '@app/utilities/enhancers/utils';
import { interval, Observable, of as observableOf } from 'rxjs';
import { Guid } from '@common/types/guid';
import { Location } from '@angular/common';
import { ENTER, COMMA } from '@angular/cdk/keycodes';
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component';
@Component({
selector: 'dataset-editor-details',
templateUrl: './dataset-editor-details.component.html',
styleUrls: ['./dataset-editor-details.component.scss']
})
export class DatasetEditorDetailsComponent extends BaseComponent implements OnInit {
viewOnly = false;
editMode = false;
// publicMode = false;
// DatasetStatus = DatasetStatus;
// dmpAutoCompleteConfiguration: SingleAutoCompleteConfiguration;
datasetWizardModel: DatasetWizardEditorModel;
// isNew = true;
// isCopy = false;
// formGroup: FormGroup = null;
datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel;
// availableProfiles: DatasetProfileModel[] = [];
// itemId: string;
// publicId: string;
// profileUpdateId: string;
// downloadDocumentId: string;
// isLinear = false;
lock: LockModel;
lockStatus: Boolean;
dmpText: string = null;
@Input() formGroup: UntypedFormGroup;
@Input() dmpId: string;
@Input() datasetId: string;
@Input() availableProfiles: DatasetProfileModel[];
@Output() formChanged: EventEmitter<any> = new EventEmitter();
readonly separatorKeysCodes: number[] = [ENTER, COMMA];
profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration;
constructor(
private datasetWizardService: DatasetWizardService,
private route: ActivatedRoute,
public snackBar: MatSnackBar,
public router: Router,
private language: TranslateService,
private configurationService: ConfigurationService,
private externalSourcesService: ExternalSourcesService,
private dialog: MatDialog,
public dmpService: DmpService,
public externalSourcesConfigurationService: ExternalSourcesConfigurationService,
private uiNotificationService: UiNotificationService,
private formService: FormService,
private lockService: LockService,
private location: Location,
private authService: AuthService,
private guidedTourService: GuidedTourService
) {
super();
}
ngOnInit() {
if (this.formGroup.get('status').value === 1) {
this.formGroup.disable();
}
this.datasetWizardModel = new DatasetWizardEditorModel();
this.profilesAutoCompleteConfiguration = {
filterFn: this.filterProfiles.bind(this),
initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))),
displayFn: (item) => item['label'],
titleFn: (item) => item['label'],
subtitleFn: (item) => item['description'],
popupItemActionIcon: 'visibility'
};
}
public dashboardTourDmp: GuidedTour = {
tourId: 'only-dmp-tour',
useOrb: true,
steps: [
{
title: this.dmpText,
content: 'Step 1',
orientation: Orientation.Bottom,
highlightPadding: 3,
isStepUnique: true,
customTopOffset: 8
}
]
};
getDmpText(): string {
return this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
this.language.instant('DMP-LISTING.GET-IDEA');
}
setDashboardTourDmp(label: string): void {
this.dashboardTourDmp.steps[0].title = this.getDmpText();
this.dashboardTourDmp.steps[0].selector = '.dmp-tour-' + label;
}
public restartTour(label: string): void {
this.setDashboardTourDmp(label);
this.guidedTourService.startTour(this.dashboardTourDmp);
}
registerFormListeners() {
// this.formGroup.get('dmp').valueChanges
// .pipe(takeUntil(this._destroyed))
// .subscribe(x => {
// this.dmpValueChanged(x);
// });
// if (this.isNewDataset) {
// this.formGroup.get('profile').valueChanges
// .pipe(takeUntil(this._destroyed))
// .subscribe(x => {
// if (!isNullOrUndefined(x)) {
// this.datasetProfileValueChanged(x.id);
// }
// });
// }
}
dmpValueChanged(dmp: DmpListingModel) {
if (dmp) {
this.formGroup.get('profile').enable();
this.loadDatasetProfiles();
}
else {
this.availableProfiles = [];
this.formGroup.get('profile').reset();
this.formGroup.get('profile').disable();
this.formGroup.removeControl('datasetProfileDefinition');
}
}
datasetProfileValueChanged(profileId: string) {
if (profileId && profileId.length > 0) {
this.formGroup.removeControl('datasetProfileDefinition');
this.getDefinition(profileId);
}
}
onChanges(): void {
this.formGroup.valueChanges
.pipe(takeUntil(this._destroyed))
.subscribe(val => {
// this.formChanged.emit(val);
});
}
onFormChanged(event) {
// this.formChanged.emit(event);
}
getDefinition(profileId: string) {
// if (this.formGroup.invalid) { setTimeout(() => this.stepper.selectedIndex = 0); return; }
this.datasetWizardService.getDefinition(profileId)
.pipe(takeUntil(this._destroyed))
.subscribe(item => {
this.datasetWizardModel.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item);
this.datasetProfileDefinitionModel = this.datasetWizardModel.datasetProfileDefinition;
this.formGroup.addControl('datasetProfileDefinition', this.datasetProfileDefinitionModel.buildForm());
});
}
loadDatasetProfiles() {
const datasetProfileRequestItem: RequestItem<DatasetProfileCriteria> = new RequestItem();
datasetProfileRequestItem.criteria = new DatasetProfileCriteria();
datasetProfileRequestItem.criteria.id = this.dmpId;
if (datasetProfileRequestItem.criteria.id) {
this.datasetWizardService.getAvailableProfiles(datasetProfileRequestItem)
.pipe(takeUntil(this._destroyed))
.subscribe(items => {
this.availableProfiles = items;
});
}
}
needsUpdate() {
if (this.datasetWizardModel.isProfileLatestVersion || (this.datasetWizardModel.status === DatasetStatus.Finalized)
|| (this.datasetWizardModel.isProfileLatestVersion == undefined && this.datasetWizardModel.status == undefined)) {
return false;
}
else {
return true;
}
}
private pumpLock() {
this.lock.touchedAt = new Date();
this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => {
if (!isNullOrUndefined(result)) {
this.lock.id = Guid.parse(result);
} else {
this.location.back();
}
});
}
removeTag(tag: any) {
(<UntypedFormArray>this.formGroup.get('tags')).removeAt(((<UntypedFormArray>this.formGroup.get('tags')).value as any[]).indexOf(tag));
}
addTag(ev: MatChipInputEvent) {
if (ev.value !== '' && isNullOrUndefined(((<UntypedFormArray>this.formGroup.get('tags')).value as ExternalTagEditorModel[]).find(tag => tag.name === ev.value))) {
(<UntypedFormArray>this.formGroup.get('tags')).push(new ExternalTagEditorModel('', ev.value).buildForm());
}
ev.input.value = '';
}
getProfileId(): string {
if (!isNullOrUndefined(this.formGroup.get('profile').value)) {
return this.formGroup.get('profile').value.id;
} else {
return undefined;
}
}
hasProfileId(): boolean {
return !isNullOrUndefined(this.getProfileId());
}
filterProfiles(value: string): Observable<DatasetProfileModel[]> {
const request = new DataTableRequest<DatasetProfileCriteria>(null, null, { fields: ['+label'] });
const criteria = new DatasetProfileCriteria();
criteria.like = value;
request.criteria = criteria;
return this.dmpService.searchDmpBlueprints(request);
}
allAvailableProfiles(event: MouseEvent) {
event.stopPropagation();
const dialogRef = this.dialog.open(AvailableProfilesComponent, {
data: {
profiles: this.formGroup.get('profiles')
}
});
return false;
}
public compareWith(object1: any, object2: any) {
return object1 && object2 && object1.id === object2.id;
}
}

View File

@ -1,33 +0,0 @@
import { NgModule } from '@angular/core';
import { FormattingModule } from '@app/core/formatting.module';
import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module';
import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module';
import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing';
import { DmpOverviewModule } from '@app/ui/dmp/overview/dmp-overview.module';
import { CommonFormsModule } from '@common/forms/common-forms.module';
import { FormValidationErrorsDialogModule } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module';
import { CommonUiModule } from '@common/ui/common-ui.module';
import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module';
import { DatasetEditorDetailsComponent } from './dataset-editor-details.component';
@NgModule({
imports: [
CommonUiModule,
CommonFormsModule,
ConfirmationDialogModule,
FormattingModule,
AutoCompleteModule,
DmpRoutingModule,
DmpOverviewModule,
FormValidationErrorsDialogModule,
MultipleChoiceDialogModule,
],
declarations: [
DatasetEditorDetailsComponent
],
exports: [
DatasetEditorDetailsComponent
]
})
export class DatasetEditorDetailsModule { }

View File

@ -14,17 +14,26 @@ import { Location } from '@angular/common';
import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { DescriptionStatus } from '@app/core/common/enum/description-status';
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { DepositConfiguration } from '@app/core/model/deposit/deposit-configuration'; import { DepositConfiguration } from '@app/core/model/deposit/deposit-configuration';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
import { Description } from '@app/core/model/description/description'; import { Description } from '@app/core/model/description/description';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp'; import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app/core/model/dmp/dmp';
import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { DmpReference } from '@app/core/model/dmp/dmp-reference';
import { EntityDoi } from '@app/core/model/entity-doi/entity-doi'; import { EntityDoi } from '@app/core/model/entity-doi/entity-doi';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference'; import { Reference } from '@app/core/model/reference/reference';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { DepositService } from '@app/core/services/deposit/deposit.service'; import { DepositService } from '@app/core/services/deposit/deposit.service';
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service';
import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service'; import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
import { LockService } from '@app/core/services/lock/lock.service'; import { LockService } from '@app/core/services/lock/lock.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service'; import { ReferenceService } from '@app/core/services/reference/reference.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service';
@ -32,24 +41,14 @@ import { PopupNotificationDialogComponent } from '@app/library/notification/popu
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { Guid } from '@common/types/guid'; import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import * as FileSaver from 'file-saver';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof'; import { nameof } from 'ts-simple-nameof';
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component'; import { CloneDmpDialogComponent } from '../clone-dialog/dmp-clone-dialog.component';
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
import { AppPermission } from '@app/core/common/enum/permission.enum';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { IsActive } from '@app/core/common/enum/is-active.enum';
import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component'; import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver';
import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component';
@Component({ @Component({
selector: 'app-dmp-overview', selector: 'app-dmp-overview',
@ -232,16 +231,16 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.authorFocus = null; this.authorFocus = null;
} }
canEditDmp(): boolean{ canEditDmp(): boolean {
return (this.isDraftDmp()) && (this.dmp.authorizationFlags?.some(x => x === AppPermission.EditDmp) || this.authentication.hasPermission(AppPermission.EditDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.isDraftDmp()) && (this.dmp.authorizationFlags?.some(x => x === AppPermission.EditDmp) || this.authentication.hasPermission(AppPermission.EditDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canCreateNewVersion(): boolean { canCreateNewVersion(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionDmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp)) && this.dmp.versionStatus === DmpVersionStatus.Current && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.CreateNewVersionDmp) || this.authentication.hasPermission(AppPermission.CreateNewVersionDmp)) && this.dmp.versionStatus === DmpVersionStatus.Current && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canDeleteDmp(): boolean { canDeleteDmp(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DeleteDmp) || this.authentication.hasPermission(AppPermission.DeleteDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DeleteDmp) || this.authentication.hasPermission(AppPermission.DeleteDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canCloneDmp(): boolean { canCloneDmp(): boolean {
@ -249,7 +248,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
} }
canFinalizeDmp(): boolean { canFinalizeDmp(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.FinalizeDmp) || this.authentication.hasPermission(AppPermission.FinalizeDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.FinalizeDmp) || this.authentication.hasPermission(AppPermission.FinalizeDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canExportDmp(): boolean { canExportDmp(): boolean {
@ -257,15 +256,15 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
} }
canInviteDmpUsers(): boolean { canInviteDmpUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers) || this.authentication.hasPermission(AppPermission.InviteDmpUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.InviteDmpUsers) || this.authentication.hasPermission(AppPermission.InviteDmpUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canAssignDmpUsers(): boolean { canAssignDmpUsers(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.AssignDmpUsers) || this.authentication.hasPermission(AppPermission.AssignDmpUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.AssignDmpUsers) || this.authentication.hasPermission(AppPermission.AssignDmpUsers)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
canDepositDmp(): boolean { canDepositDmp(): boolean {
return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DepositDmp) || this.authentication.hasPermission(AppPermission.DepositDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false; return (this.dmp.authorizationFlags?.some(x => x === AppPermission.DepositDmp) || this.authentication.hasPermission(AppPermission.DepositDmp)) && this.isPublicView == false && this.dmp.belongsToCurrentTenant != false;
} }
@ -391,7 +390,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
deleteClicked() { deleteClicked() {
let dialogRef: any; let dialogRef: any;
if (this.dmp.descriptions && this.dmp.descriptions.length > 0){ if (this.dmp.descriptions && this.dmp.descriptions.length > 0) {
dialogRef = this.dialog.open(DmpDeleteDialogComponent, { dialogRef = this.dialog.open(DmpDeleteDialogComponent, {
maxWidth: '300px', maxWidth: '300px',
data: { data: {
@ -440,50 +439,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
this.uiNotificationService.snackBarNotification(error.error.error ? error.error.error : this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error); this.uiNotificationService.snackBarNotification(error.error.error ? error.error.error : this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error);
} }
downloadXml(id: string) {
// this.dmpService.downloadXML(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(response => {
// const blob = new Blob([response.body], { type: 'application/xml' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('dmps', "xml", id);
// });
}
download(id: string, format: string) {
this.dmpService.download(id, format)
.pipe(takeUntil(this._destroyed))
.subscribe(response => {
const blob = new Blob([response.body], { type: 'application/octet-stream' });
const filename = this.fileUtils.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition'));
FileSaver.saveAs(blob, filename);
this.analyticsService.trackDownload('dmps', format, id);
});
}
downloadJson(id: string) {
//TODO: add this
// this.dmpService.downloadJson(id)
// .pipe(takeUntil(this._destroyed))
// .subscribe(complete => {
// const blob = new Blob([complete.body], { type: 'application/json' });
// const filename = this.fileUtils.getFilenameFromContentDispositionHeader(complete.headers.get('Content-Disposition'));
// FileSaver.saveAs(blob, filename);
// this.matomoService.trackDownload('dmps', "json", id);
// }, async error => {
// this.onExportCallbackError(error);
// });
}
// async onExportCallbackError(error: any) {
// const errorJsonText = await error.error.text();
// const errorObj = JSON.parse(errorJsonText);
// this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error);
// }
isUserDmpRelated(): boolean { isUserDmpRelated(): boolean {
const principalId: Guid = this.authentication.userId(); const principalId: Guid = this.authentication.userId();
return this.dmp.dmpUsers?.some(x => (x.user.id === principalId)); return this.dmp.dmpUsers?.some(x => (x.user.id === principalId));
@ -726,9 +681,9 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
} }
getSectionNameById(sectionId: Guid): string { getSectionNameById(sectionId: Guid): string {
if (sectionId == null) return ''; if (sectionId == null) return '';
let sections: DmpBlueprintDefinitionSection[] = this.dmp?.blueprint?.definition?.sections?.filter((section:DmpBlueprintDefinitionSection) => sectionId===section.id); let sections: DmpBlueprintDefinitionSection[] = this.dmp?.blueprint?.definition?.sections?.filter((section: DmpBlueprintDefinitionSection) => sectionId === section.id);
return sections == null ? '' : sections[0].label; return sections == null ? '' : sections[0].label;
} }

View File

@ -2,30 +2,30 @@ import { Location } from '@angular/common';
import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core'; import { Component, ElementRef, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { MatMenuTrigger } from '@angular/material/menu'; import { MatMenuTrigger } from '@angular/material/menu';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AppRole } from '@app/core/common/enum/app-role'; import { AppRole } from '@app/core/common/enum/app-role';
import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type';
import { StorageFile } from '@app/core/model/storage-file/storage-file';
import { LogoTenantConfiguration, TenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration';
import { User } from '@app/core/model/user/user'; import { User } from '@app/core/model/user/user';
import { AuthService, LoginStatus } from '@app/core/services/auth/auth.service'; import { AuthService, LoginStatus } from '@app/core/services/auth/auth.service';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { LanguageService } from '@app/core/services/language/language.service'; import { LanguageService } from '@app/core/services/language/language.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service'; import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service';
import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice'; import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice';
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service';
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service';
import { MineInAppNotificationListingDialogComponent } from '@notification-service/ui/inapp-notification/listing-dialog/mine-inapp-notification-listing-dialog.component';
import { timer } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component'; import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component';
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component'; import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
import { UserDialogComponent } from './user-dialog/user-dialog.component'; import { UserDialogComponent } from './user-dialog/user-dialog.component';
import { MineInAppNotificationListingDialogComponent } from '@notification-service/ui/inapp-notification/listing-dialog/mine-inapp-notification-listing-dialog.component';
import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service';
import { timer } from 'rxjs';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service';
import { LogoTenantConfiguration, TenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration';
import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type';
import { nameof } from 'ts-simple-nameof';
import { StorageFile } from '@app/core/model/storage-file/storage-file';
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({ @Component({
selector: 'app-navbar', selector: 'app-navbar',
@ -109,22 +109,22 @@ export class NavbarComponent extends BaseComponent implements OnInit {
private loadLogo() { private loadLogo() {
if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) { if (this.authentication.currentAccountIsAuthenticated() && this.authentication.selectedTenant()) {
this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.Logo, [ this.tenantConfigurationService.getCurrentTenantType(TenantConfigurationType.Logo, [
nameof<TenantConfiguration>(x => x.type), nameof<TenantConfiguration>(x => x.type),
[nameof<TenantConfiguration>(x => x.logo), nameof<LogoTenantConfiguration>(x => x.storageFile), nameof<StorageFile>(x => x.id)].join('.'), [nameof<TenantConfiguration>(x => x.logo), nameof<LogoTenantConfiguration>(x => x.storageFile), nameof<StorageFile>(x => x.id)].join('.'),
]) ])
.pipe(map(data => data as TenantConfiguration), takeUntil(this._destroyed)) .pipe(map(data => data as TenantConfiguration), takeUntil(this._destroyed))
.subscribe( .subscribe(
data => { data => {
if (data?.logo?.storageFile?.id) { if (data?.logo?.storageFile?.id) {
this.storageFileService.download(data?.logo?.storageFile?.id).pipe(takeUntil(this._destroyed)) this.storageFileService.download(data?.logo?.storageFile?.id).pipe(takeUntil(this._destroyed))
.subscribe(response => { .subscribe(response => {
const blob = new Blob([response.body]); const blob = new Blob([response.body]);
this.extraImageURL = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(response.body)) this.extraImageURL = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(response.body))
}); });
} }
}, },
); );
} }
} }

View File

@ -9,14 +9,10 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
}) })
export class AddAccountDialogComponent implements OnInit { export class AddAccountDialogComponent implements OnInit {
//TODO: refactor
datasetProfileDefinitionModel: any; datasetProfileDefinitionModel: any;
datasetProfileDefinitionFormGroup: UntypedFormGroup; datasetProfileDefinitionFormGroup: UntypedFormGroup;
progressIndication = false; progressIndication = false;
form: FormGroup; form: FormGroup;
// public hasEmail = true;
//TODO: refactor
// private request: any;
constructor( constructor(
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
@ -28,18 +24,6 @@ export class AddAccountDialogComponent implements OnInit {
this.form = this.formBuilder.group({ this.form = this.formBuilder.group({
email: [this.data.email, [Validators.required, Validators.email]] email: [this.data.email, [Validators.required, Validators.email]]
}); });
//TODO refactor
// this.mergeLoginService.getObservable().subscribe(result => {
// if (result !== undefined) {
// if (!(result.email !== undefined && result.email !== null)) {
// this.request = result;
// this.hasEmail = false;
// } else {
// this.dialogRef.close(result);
// }
// }
// });
} }
add(): void { add(): void {

View File

@ -1,44 +1,42 @@
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ActivatedRoute, Params, Router } from '@angular/router'; import { ActivatedRoute, Params } from '@angular/router';
import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type'; import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type';
import { CultureInfo } from '@app/core/model/culture-info'; import { CultureInfo } from '@app/core/model/culture-info';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Reference } from '@app/core/model/reference/reference'; import { Reference } from '@app/core/model/reference/reference';
import { Tenant } from '@app/core/model/tenant/tenant';
import { User, UserAdditionalInfo, UserCredential, UserPersist } from '@app/core/model/user/user'; import { User, UserAdditionalInfo, UserCredential, UserPersist } from '@app/core/model/user/user';
import { AuthService } from '@app/core/services/auth/auth.service'; import { AuthService } from '@app/core/services/auth/auth.service';
import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
import { CultureService } from '@app/core/services/culture/culture-service'; import { CultureService } from '@app/core/services/culture/culture-service';
import { PrincipalService } from '@app/core/services/http/principal.service';
import { LanguageService } from '@app/core/services/language/language.service'; import { LanguageService } from '@app/core/services/language/language.service';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { UserService } from '@app/core/services/user/user.service'; import { UserService } from '@app/core/services/user/user.service';
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
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 { PopupNotificationDialogComponent } from "@app/library/notification/popup/popup-notification.component"; import { PopupNotificationDialogComponent } from "@app/library/notification/popup/popup-notification.component";
import { BaseComponent } from '@common/base/base.component'; import { BaseComponent } from '@common/base/base.component';
import { FormService } from '@common/forms/form-service';
import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
import { Guid } from '@common/types/guid';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { KeycloakService } from 'keycloak-angular';
import * as moment from 'moment-timezone'; import * as moment from 'moment-timezone';
import { Observable, from, of } from 'rxjs'; import { Observable, from, of } from 'rxjs';
import { map, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { nameof } from 'ts-simple-nameof';
import { AddAccountDialogComponent } from './add-account/add-account-dialog.component'; import { AddAccountDialogComponent } from './add-account/add-account-dialog.component';
import { UserProfileEditorModel } from './user-profile-editor.model'; import { UserProfileEditorModel } from './user-profile-editor.model';
import { nameof } from 'ts-simple-nameof';
import { Guid } from '@common/types/guid';
import { BaseHttpParams } from '@common/http/base-http-params';
import { InterceptorType } from '@common/http/interceptors/interceptor-type';
import { PrincipalService } from '@app/core/services/http/principal.service';
import { KeycloakService } from 'keycloak-angular';
import { FormService } from '@common/forms/form-service';
import { ReferenceService } from '@app/core/services/reference/reference.service';
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type';
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
import { Tenant } from '@app/core/model/tenant/tenant';
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
@Component({ @Component({
selector: 'app-user-profile', selector: 'app-user-profile',
@ -73,17 +71,14 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
constructor( constructor(
private userService: UserService, private userService: UserService,
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router,
private authService: AuthService, private authService: AuthService,
private language: TranslateService, private language: TranslateService,
private cultureService: CultureService, private cultureService: CultureService,
private authentication: AuthService,
private languageService: LanguageService, private languageService: LanguageService,
private configurationService: ConfigurationService, private configurationService: ConfigurationService,
private uiNotificationService: UiNotificationService, private uiNotificationService: UiNotificationService,
private dialog: MatDialog, private dialog: MatDialog,
public enumUtils: EnumUtils, public enumUtils: EnumUtils,
private httpClient: HttpClient,
private formBuilder: UntypedFormBuilder, private formBuilder: UntypedFormBuilder,
private keycloakService: KeycloakService, private keycloakService: KeycloakService,
private principalService: PrincipalService, private principalService: PrincipalService,
@ -97,7 +92,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
} }
public getProviderIcons(userCredential: UserCredential, culture:string): string[] { public getProviderIcons(userCredential: UserCredential, culture: string): string[] {
if (userCredential.data.externalProviderNames === undefined || userCredential.data.externalProviderNames?.length === 0) { if (userCredential.data.externalProviderNames === undefined || userCredential.data.externalProviderNames?.length === 0) {
return [this.configurationService.authProviders.defaultAuthProvider.providerClass]; return [this.configurationService.authProviders.defaultAuthProvider.providerClass];
@ -125,62 +120,37 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe((params: Params) => { .subscribe((params: Params) => {
this.getOrRefreshData(); this.getOrRefreshData();
//TODO: refactor
// this.userService.getEmails(userId).pipe(takeUntil(this._destroyed))
// .subscribe(result => {
// this.user.subscribe(x => {
// const mainEmail = result.filter(el => el.email === x.email)
// const otherEmails = result.filter(el => el.email !== x.email)
// this.userCredentials = [...mainEmail, ...otherEmails];
// }
// )
// });
}); });
} }
getOrRefreshData(){ getOrRefreshData() {
this.currentUserId = this.authService.userId()?.toString(); this.currentUserId = this.authService.userId()?.toString();
this.user = this.userService.getSingle( this.user = this.userService.getSingle(
Guid.parse(this.currentUserId), Guid.parse(this.currentUserId),
[ [
nameof<User>(x => x.id), nameof<User>(x => x.id),
nameof<User>(x => x.name), nameof<User>(x => x.name),
nameof<User>(x => x.additionalInfo.language), nameof<User>(x => x.additionalInfo.language),
nameof<User>(x => x.additionalInfo.timezone), nameof<User>(x => x.additionalInfo.timezone),
nameof<User>(x => x.additionalInfo.culture), nameof<User>(x => x.additionalInfo.culture),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.id)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.id)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.label)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.label)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.type), nameof<ReferenceType>(x => x.id)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.reference)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.reference)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.source)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.source)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.sourceType)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.sourceType)].join('.'),
[nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.isActive)].join('.'), [nameof<User>(x => x.additionalInfo), nameof<UserAdditionalInfo>(x => x.organization), nameof<Reference>(x => x.isActive)].join('.'),
nameof<User>(x => x.additionalInfo.roleOrganization), nameof<User>(x => x.additionalInfo.roleOrganization),
nameof<User>(x => x.createdAt), nameof<User>(x => x.createdAt),
nameof<User>(x => x.updatedAt), nameof<User>(x => x.updatedAt),
nameof<User>(x => x.hash), nameof<User>(x => x.hash),
`${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.id)}`, `${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.id)}`,
`${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.email)}`, `${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.email)}`,
`${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.externalProviderNames)}`, `${nameof<User>(x => x.credentials)}.${nameof<UserCredential>(x => x.data.externalProviderNames)}`,
] ]
) )
.pipe(map(result => { .pipe(map(result => {
//tested ui with fake data
// const fakecredentials: UserCredential = {
// "id": Guid.createEmpty(),
// "externalId": "123",
// "user": null,
// "createdAt": new Date(),
// "data": {
// "email": "dmpadmin@dmp.com",
// "externalProviderNames": ["Google", "Facebook"]
// }
// };
// result.credentials.push(fakecredentials);
// result.credentials[0].data.externalProviderNames = ['Google'];
this.userLanguage = result.additionalInfo.language; this.userLanguage = result.additionalInfo.language;
this.firstEmail = result.credentials[0].data.email; this.firstEmail = result.credentials[0].data.email;
this.userCredentials = of(result.credentials); this.userCredentials = of(result.credentials);
@ -188,14 +158,12 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result); this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result);
this.formGroup = this.userProfileEditorModel.buildForm(this.languageService.getAvailableLanguagesCodes()); this.formGroup = this.userProfileEditorModel.buildForm(this.languageService.getAvailableLanguagesCodes());
//this.formGroup.get('language').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { if (x) this.translate.use(x.value) })
this.formGroup.get('additionalInfo').get('timezone').valueChanges this.formGroup.get('additionalInfo').get('timezone').valueChanges
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } }); .subscribe(x => { if (x) { this.timezones = this._filterTimezone(x); } });
this.formGroup.get('additionalInfo').get('culture').valueChanges this.formGroup.get('additionalInfo').get('culture').valueChanges
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } }); .subscribe(x => { if (x) { this.cultures = this._filterCulture(x); } });
// this.initializeDisabledFormGroup();
this.tenants = this.loadUserTenants(); this.tenants = this.loadUserTenants();
this.unlock(); this.unlock();
@ -234,7 +202,7 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
if (culture == null if (culture == null
|| culture.displayName == null || culture.displayName == null
|| culture.nativeName == null) || culture.nativeName == null)
return undefined; return undefined;
return culture.displayName + '-' + culture.nativeName; return culture.displayName + '-' + culture.nativeName;
@ -263,7 +231,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
.pipe(takeUntil(this._destroyed)) .pipe(takeUntil(this._destroyed))
.subscribe(result => { .subscribe(result => {
this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
// this.router.navigate(['/profile']);
window.location.reload(); window.location.reload();
}); });
}, },
@ -275,30 +242,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
this.formGroup.enable(); this.formGroup.enable();
} }
public initializeDisabledFormGroup() {
this.formGroup.disable();
}
public lock() {
if (!this.formGroup.valid) { return; }
//TODO: refactor
// this.userService.updateUserSettings(this.formGroup.value)
// .pipe(takeUntil(this._destroyed))
// .subscribe(
// x => {
// this.editMode = false;
// this.languageService.changeLanguage(this.formGroup.value.language.value);
// this.formGroup.disable();
// this.authService.refresh()
// .pipe(takeUntil(this._destroyed))
// .subscribe(result => this.router.navigate(['/profile']));
// // .subscribe(result => window.location.reload());
// },
// error => {
// console.log(error);
// });
}
private showValidationErrorsDialog(projectOnly?: boolean) { private showValidationErrorsDialog(projectOnly?: boolean) {
const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, {
disableClose: true, disableClose: true,
@ -332,11 +275,11 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
this.dialog.open(PopupNotificationDialogComponent, { this.dialog.open(PopupNotificationDialogComponent, {
data: { data: {
title: this.language.instant('USER-PROFILE.UNLINK-ACCOUNT.TITLE'), title: this.language.instant('USER-PROFILE.UNLINK-ACCOUNT.TITLE'),
message: this.language.instant('USER-PROFILE.UNLINK-ACCOUNT.MESSAGE', {'accountToBeUnlinked': userCredential.data?.email}) message: this.language.instant('USER-PROFILE.UNLINK-ACCOUNT.MESSAGE', { 'accountToBeUnlinked': userCredential.data?.email })
}, maxWidth: '30em' }, maxWidth: '30em'
}); });
}, },
error => this.onCallbackError(error)); error => this.onCallbackError(error));
} }
}); });
} }
@ -349,8 +292,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
const dialogRef = this.dialog.open(AddAccountDialogComponent, { const dialogRef = this.dialog.open(AddAccountDialogComponent, {
restoreFocus: false, restoreFocus: false,
autoFocus: false, autoFocus: false,
// width: '653px',
// maxHeight: '90vh',
width: '30%', width: '30%',
minWidth: 'fit-content', minWidth: 'fit-content',
data: { data: {
@ -360,29 +301,17 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
if (result) { if (result) {
this.userService.mergeAccount({ email: result.email }) this.userService.mergeAccount({ email: result.email })
.subscribe(result => { .subscribe(result => {
if (result) { if (result) {
this.dialog.open(PopupNotificationDialogComponent, { this.dialog.open(PopupNotificationDialogComponent, {
data: { data: {
title: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.TITLE'), title: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.TITLE'),
message: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.MESSAGE') message: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.MESSAGE')
}, maxWidth: '30em' }, maxWidth: '30em'
}); });
} }
}, },
error => this.onCallbackError(error)); //TODO how to handle this error => this.onCallbackError(error)); //TODO how to handle this
//TODO refactor
// this.mergeEmailConfirmation.sendConfirmationEmail(result).pipe(takeUntil(this._destroyed))
// .subscribe(res => {
// this.dialog.open(PopupNotificationDialogComponent, {
// data: {
// title: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.TITLE'),
// message: this.language.instant('USER-PROFILE.MERGING-EMAILS-DIALOG.MESSAGE')
// }, maxWidth: '30em'
// });
// }, err => { });
} }
}); });
} }

View File

@ -204,36 +204,6 @@
$label-placeholder-top: $label-top-margin + $static-font-size + $label-placeholder-top: $label-top-margin + $static-font-size +
$variant-padding-y; $variant-padding-y;
//@debug "font-size: #{$font-size} static-font-size: #{$static-font-size} help-font-size: #{$help-font-size} form-group-context: #{$form-group-context} ";
//Label height: 72dp
//Padding above label text: 16dp
//Padding between label and input text: 8dp
//Padding below input text (including divider): 16dp
//Padding below text divider: 8dp
// @if $form-group-context {
// // Create a space at the top of the bmd-form-group for the label.
// // The label is absolutely positioned, so we use top padding to make space. This padding extends over the label down to the top of the input (padding).
// padding-top: ($label-top-margin + $static-font-size);
// // note: bottom-margin of this is determined by $spacer. @see _spacer.scss
// //margin-bottom: (1.5 * $help-font-size);
// }
// TODO: remove this when known stable. https://github.com/FezVrasta/bootstrap-material-design/issues/849
//@else {
//
// // for radios and checkboxes without a form-group, add some extra vertical spacing to pad down so that
// // any help text above is not encroached upon, or so that it appears more evenly spaced vs form-groups
// .radio,
// label.radio-inline,
// .checkbox,
// label.checkbox-inline,
// .switch {
// padding-top: $spacer-y;
// }
//}
// Set all line-heights preferably to 1 so that we can space out everything manually without additional added space // Set all line-heights preferably to 1 so that we can space out everything manually without additional added space
// from the default line-height of 1.5 // from the default line-height of 1.5
.form-control, .form-control,

View File

@ -68,15 +68,4 @@ export class FormService {
public getValue(control: AbstractControl) { public getValue(control: AbstractControl) {
return JSON.parse(JSON.stringify(control)); //Used to deep copy formGroup. return JSON.parse(JSON.stringify(control)); //Used to deep copy formGroup.
} }
// TODO
// public reapplyValidators(array: FormArray, validationContext: ValidationContext) {
// if (!Array.isArray(array.controls)) { return; }
// array.controls.forEach((element, index) => {
// const formGroup = element as FormGroup;
// Object.keys(formGroup.controls).forEach(key => {
// formGroup.get(key).setValidators(validationContext.getValidation(key).validators);
// });
// });
// }
} }