From 858e98c9f888f2f35998182b49fb782204aebf1c Mon Sep 17 00:00:00 2001 From: Oleh Paduchak Date: Wed, 24 Sep 2025 22:29:59 +0300 Subject: [PATCH 1/4] fix(datacite-tracker): fixed merge artifacts, replaced file target with resource selector --- src/app/features/files/pages/files/files.component.ts | 3 ++- .../project/overview/project-overview.component.ts | 6 +++++- .../components/files-tree/files-tree.component.ts | 11 +++++++---- src/app/shared/services/datacite/datacite.service.ts | 10 +++++----- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/app/features/files/pages/files/files.component.ts b/src/app/features/files/pages/files/files.component.ts index fbbd93fe9..ca8e776e2 100644 --- a/src/app/features/files/pages/files/files.component.ts +++ b/src/app/features/files/pages/files/files.component.ts @@ -144,6 +144,7 @@ export class FilesComponent { readonly currentFolder = select(FilesSelectors.getCurrentFolder); readonly provider = select(FilesSelectors.getProvider); readonly resourceDetails = select(CurrentResourceSelectors.getResourceDetails); + readonly resourceMetadata = select(CurrentResourceSelectors.getCurrentResource); readonly rootFolders = select(FilesSelectors.getRootFolders); readonly isRootFoldersLoading = select(FilesSelectors.isRootFoldersLoading); readonly configuredStorageAddons = select(FilesSelectors.getConfiguredStorageAddons); @@ -436,7 +437,7 @@ export class FilesComponent { const folderId = this.currentFolder()?.id ?? ''; const isRootFolder = !this.currentFolder()?.relationships?.parentFolderLink; const storageLink = this.currentRootFolder()?.folder?.links?.download ?? ''; - const resourcePath = this.urlMap.get(this.resourceType()) ?? 'nodes'; + const resourcePath = this.resourceMetadata()?.type ?? 'nodes'; if (resourceId && folderId) { this.dataciteService.logFileDownload(resourceId, resourcePath).subscribe(); diff --git a/src/app/features/project/overview/project-overview.component.ts b/src/app/features/project/overview/project-overview.component.ts index b769f0168..3627ec624 100644 --- a/src/app/features/project/overview/project-overview.component.ts +++ b/src/app/features/project/overview/project-overview.component.ts @@ -20,7 +20,7 @@ import { inject, OnInit, } from '@angular/core'; -import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop'; +import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, NavigationEnd, Router, RouterLink } from '@angular/router'; @@ -200,6 +200,8 @@ export class ProjectOverviewComponent implements OnInit { this.areSubjectsLoading() ); + currentProject$ = toObservable(this.currentProject); + currentResource = computed(() => { const project = this.currentProject(); if (project) { @@ -288,6 +290,8 @@ export class ProjectOverviewComponent implements OnInit { this.actions.getLinkedProjects(projectId); this.actions.getActivityLogs(projectId, this.activityDefaultPage, this.activityPageSize); } + + this.dataciteService.logIdentifiableView(this.currentProject$).subscribe(); } handleOpenMakeDecisionDialog() { diff --git a/src/app/shared/components/files-tree/files-tree.component.ts b/src/app/shared/components/files-tree/files-tree.component.ts index 248bf93a5..6b08d7271 100644 --- a/src/app/shared/components/files-tree/files-tree.component.ts +++ b/src/app/shared/components/files-tree/files-tree.component.ts @@ -1,3 +1,5 @@ +import { select } from '@ngxs/store'; + import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { PrimeTemplate } from 'primeng/api'; @@ -37,6 +39,7 @@ import { FileLabelModel, FileMenuAction, FilesTreeActions, OsfFile } from '@osf/ import { FileSizePipe } from '@osf/shared/pipes'; import { CustomConfirmationService, FilesService, ToastService } from '@osf/shared/services'; import { DataciteService } from '@osf/shared/services/datacite/datacite.service'; +import { CurrentResourceSelectors } from '@shared/stores'; import { CustomPaginatorComponent } from '../custom-paginator/custom-paginator.component'; import { FileMenuComponent } from '../file-menu/file-menu.component'; @@ -86,6 +89,8 @@ export class FilesTreeComponent implements OnDestroy, AfterViewInit { isDragOver = signal(false); hasViewOnly = computed(() => hasViewOnlyParam(this.router) || this.viewOnly()); + readonly resourceMetadata = select(CurrentResourceSelectors.getCurrentResource); + entryFileClicked = output(); folderIsOpening = output(); uploadFilesConfirmed = output(); @@ -249,10 +254,8 @@ export class FilesTreeComponent implements OnDestroy, AfterViewInit { } downloadFileOrFolder(file: OsfFile) { - if (file.target.id && file.target.type) { - this.dataciteService.logFileDownload(file.target.id, file.target.type).subscribe(); - } - + const resourceType = this.resourceMetadata()?.type ?? 'nodes'; + this.dataciteService.logFileDownload(this.resourceId(), resourceType).subscribe(); if (file.kind === 'file') { this.downloadFile(file.links.download); } else { diff --git a/src/app/shared/services/datacite/datacite.service.ts b/src/app/shared/services/datacite/datacite.service.ts index 0de9087f3..ce30c9703 100644 --- a/src/app/shared/services/datacite/datacite.service.ts +++ b/src/app/shared/services/datacite/datacite.service.ts @@ -15,7 +15,7 @@ export class DataciteService { private readonly environment = inject(ENVIRONMENT); get webUrl() { - return this.environment.webUrl; + return this.environment.apiDomainUrl; } get dataciteTrackerAddress() { @@ -34,11 +34,11 @@ export class DataciteService { return this.watchIdentifiable(trackable, DataciteEvent.DOWNLOAD); } - logFileDownload(targetId: string, targetType: string) { + logFileDownload(targetId: string, targetType: string | undefined) { return this.logFile(targetId, targetType, DataciteEvent.DOWNLOAD); } - logFileView(targetId: string, targetType: string) { + logFileView(targetId: string, targetType: string | undefined) { return this.logFile(targetId, targetType, DataciteEvent.VIEW); } @@ -55,8 +55,8 @@ export class DataciteService { ); } - private logFile(targetId: string, targetType: string, event: DataciteEvent): Observable { - const url = `${this.webUrl}/${targetType}/${targetId}/identifiers`; + private logFile(targetId: string, targetType: string | undefined, event: DataciteEvent): Observable { + const url = `${this.webUrl}/v2/${targetType}/${targetId}/identifiers`; return this.http.get(url).pipe( map((item) => ({ identifiers: item.data.map((identifierData) => ({ From c4a7babc463fd5836af1717f1332eb4c68026c8d Mon Sep 17 00:00:00 2001 From: Oleh Paduchak Date: Wed, 24 Sep 2025 22:47:01 +0300 Subject: [PATCH 2/4] chore(datacite-tracker): revived project overview test for datacite tracker --- .../overview/project-overview.component.spec.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app/features/project/overview/project-overview.component.spec.ts b/src/app/features/project/overview/project-overview.component.spec.ts index 89d00c771..fc7b4fd53 100644 --- a/src/app/features/project/overview/project-overview.component.spec.ts +++ b/src/app/features/project/overview/project-overview.component.spec.ts @@ -12,18 +12,22 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute } from '@angular/router'; import { MetaTagsService, ToastService } from '@osf/shared/services'; +import { DataciteService } from '@shared/services/datacite/datacite.service'; import { GetActivityLogs } from '@shared/stores/activity-logs'; import { ProjectOverviewComponent } from './project-overview.component'; +import { DataciteMockFactory } from '@testing/mocks/datacite.service.mock'; + describe('ProjectOverviewComponent', () => { let fixture: ComponentFixture; let component: ProjectOverviewComponent; let store: Store; + let dataciteService: jest.Mocked; beforeEach(async () => { TestBed.overrideComponent(ProjectOverviewComponent, { set: { template: '' } }); - + dataciteService = DataciteMockFactory(); await TestBed.configureTestingModule({ imports: [ProjectOverviewComponent], providers: [ @@ -33,6 +37,7 @@ describe('ProjectOverviewComponent', () => { provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), + { provide: DataciteService, useValue: dataciteService }, { provide: DialogService, useValue: { open: () => ({ onClose: of(null) }) } }, { provide: TranslateService, useValue: { instant: (k: string) => k } }, @@ -46,8 +51,8 @@ describe('ProjectOverviewComponent', () => { component = fixture.componentInstance; }); - it('should create', () => { - expect(component).toBeTruthy(); + it('should log to datacite', () => { + expect(dataciteService.logIdentifiableView).toHaveBeenCalledWith(component.currentProject$); }); it('dispatches GetActivityLogs with numeric page and pageSize on init', () => { From 51beccc643777c25aa850e8e9cab835e45e904ea Mon Sep 17 00:00:00 2001 From: Oleh Paduchak Date: Thu, 25 Sep 2025 11:55:25 +0300 Subject: [PATCH 3/4] chore(datcite tracker): fixed naming for api domain url --- src/app/shared/services/datacite/datacite.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/services/datacite/datacite.service.ts b/src/app/shared/services/datacite/datacite.service.ts index ce30c9703..c685f1b18 100644 --- a/src/app/shared/services/datacite/datacite.service.ts +++ b/src/app/shared/services/datacite/datacite.service.ts @@ -14,7 +14,7 @@ export class DataciteService { private readonly http: HttpClient = inject(HttpClient); private readonly environment = inject(ENVIRONMENT); - get webUrl() { + get apiDomainUrl() { return this.environment.apiDomainUrl; } @@ -56,7 +56,7 @@ export class DataciteService { } private logFile(targetId: string, targetType: string | undefined, event: DataciteEvent): Observable { - const url = `${this.webUrl}/v2/${targetType}/${targetId}/identifiers`; + const url = `${this.apiDomainUrl}/v2/${targetType}/${targetId}/identifiers`; return this.http.get(url).pipe( map((item) => ({ identifiers: item.data.map((identifierData) => ({ From ddf7fa976d04a5a8822dc652d44f833eb12b2e43 Mon Sep 17 00:00:00 2001 From: Oleh Paduchak Date: Thu, 25 Sep 2025 14:13:43 +0300 Subject: [PATCH 4/4] fix(datacite-tracker): fixed wrong type annotation --- src/app/shared/services/datacite/datacite.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/shared/services/datacite/datacite.service.ts b/src/app/shared/services/datacite/datacite.service.ts index c685f1b18..fa45142d5 100644 --- a/src/app/shared/services/datacite/datacite.service.ts +++ b/src/app/shared/services/datacite/datacite.service.ts @@ -34,11 +34,11 @@ export class DataciteService { return this.watchIdentifiable(trackable, DataciteEvent.DOWNLOAD); } - logFileDownload(targetId: string, targetType: string | undefined) { + logFileDownload(targetId: string, targetType: string) { return this.logFile(targetId, targetType, DataciteEvent.DOWNLOAD); } - logFileView(targetId: string, targetType: string | undefined) { + logFileView(targetId: string, targetType: string) { return this.logFile(targetId, targetType, DataciteEvent.VIEW); } @@ -55,7 +55,7 @@ export class DataciteService { ); } - private logFile(targetId: string, targetType: string | undefined, event: DataciteEvent): Observable { + private logFile(targetId: string, targetType: string, event: DataciteEvent): Observable { const url = `${this.apiDomainUrl}/v2/${targetType}/${targetId}/identifiers`; return this.http.get(url).pipe( map((item) => ({