diff --git a/src/app/features/files/pages/file-detail/file-detail.component.ts b/src/app/features/files/pages/file-detail/file-detail.component.ts index 40ff066d9..d4c60db1a 100644 --- a/src/app/features/files/pages/file-detail/file-detail.component.ts +++ b/src/app/features/files/pages/file-detail/file-detail.component.ts @@ -183,8 +183,8 @@ export class FileDetailComponent { this.actions.getFileResourceMetadata(this.resourceId, this.resourceType); this.actions.getFileResourceContributors(this.resourceId, this.resourceType); if (fileId) { - const storageLink = this.file()?.links.download || ''; - this.actions.getFileRevisions(storageLink, fileId); + const storageLink = this.file()?.links.upload || ''; + this.actions.getFileRevisions(storageLink); this.actions.getCedarTemplates(); this.actions.getCedarRecords(fileId, ResourceType.File); } diff --git a/src/app/features/files/store/files.actions.ts b/src/app/features/files/store/files.actions.ts index 96ef709fa..a6fc56f71 100644 --- a/src/app/features/files/store/files.actions.ts +++ b/src/app/features/files/store/files.actions.ts @@ -114,10 +114,7 @@ export class SetFileMetadata { export class GetFileRevisions { static readonly type = '[Files] Get Revisions'; - constructor( - public link: string, - public fileId: string - ) {} + constructor(public link: string) {} } export class UpdateTags { diff --git a/src/app/features/files/store/files.state.ts b/src/app/features/files/store/files.state.ts index d0e977eb2..d9e572374 100644 --- a/src/app/features/files/store/files.state.ts +++ b/src/app/features/files/store/files.state.ts @@ -257,7 +257,7 @@ export class FilesState { const state = ctx.getState(); ctx.patchState({ fileRevisions: { ...state.fileRevisions, isLoading: true, error: null } }); - return this.filesService.getFileRevisions(action.link, action.fileId).pipe( + return this.filesService.getFileRevisions(action.link).pipe( tap({ next: (revisions) => { ctx.patchState({ fileRevisions: { data: revisions, isLoading: false, error: null } }); diff --git a/src/app/features/metadata/pages/add-metadata/add-metadata.component.ts b/src/app/features/metadata/pages/add-metadata/add-metadata.component.ts index 0c9b31a1f..c27330578 100644 --- a/src/app/features/metadata/pages/add-metadata/add-metadata.component.ts +++ b/src/app/features/metadata/pages/add-metadata/add-metadata.component.ts @@ -123,7 +123,11 @@ export class AddMetadataComponent implements OnInit { if (templates?.links?.first && templates?.links?.last && templates.links.first !== templates.links.last) { this.actions.getCedarTemplates(); } else { - this.router.navigate(['..'], { relativeTo: this.activatedRoute }); + if (this.resourceType() === ResourceType.File) { + this.router.navigate([this.resourceId]); + } else { + this.router.navigate(['..'], { relativeTo: this.activatedRoute }); + } } } diff --git a/src/app/features/project/project.routes.ts b/src/app/features/project/project.routes.ts index 94c3d3947..bf93b0e7d 100644 --- a/src/app/features/project/project.routes.ts +++ b/src/app/features/project/project.routes.ts @@ -4,6 +4,7 @@ import { Routes } from '@angular/router'; import { viewOnlyGuard } from '@osf/core/guards'; import { ResourceType } from '@osf/shared/enums'; +import { LicensesService } from '@osf/shared/services'; import { CitationsState, CollectionsState, @@ -17,6 +18,9 @@ import { ActivityLogsState } from '@osf/shared/stores/activity-logs'; import { AnalyticsState } from '../analytics/store'; import { CollectionsModerationState } from '../moderation/store/collections-moderation'; +import { RegistriesState } from '../registries/store'; +import { LicensesHandlers, ProjectsHandlers, ProvidersHandlers } from '../registries/store/handlers'; +import { FilesHandlers } from '../registries/store/handlers/files.handlers'; import { SettingsState } from './settings/store'; @@ -59,6 +63,14 @@ export const projectRoutes: Routes = [ { path: 'registrations', canActivate: [viewOnlyGuard], + providers: [ + provideStates([RegistriesState]), + ProvidersHandlers, + ProjectsHandlers, + LicensesService, + LicensesHandlers, + FilesHandlers, + ], loadComponent: () => import('../project/registrations/registrations.component').then((mod) => mod.RegistrationsComponent), }, diff --git a/src/app/features/project/registrations/registrations.component.html b/src/app/features/project/registrations/registrations.component.html index 80bf0335a..a9bd9b0ad 100644 --- a/src/app/features/project/registrations/registrations.component.html +++ b/src/app/features/project/registrations/registrations.component.html @@ -15,6 +15,13 @@ @for (registration of registrations(); track registration.id) { } + @if (registrationsTotalCount() > itemsPerPage) { + + } } diff --git a/src/app/features/project/registrations/registrations.component.ts b/src/app/features/project/registrations/registrations.component.ts index 69cf1e5c5..ff5b5c206 100644 --- a/src/app/features/project/registrations/registrations.component.ts +++ b/src/app/features/project/registrations/registrations.component.ts @@ -3,6 +3,7 @@ import { createDispatchMap, select } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; import { DialogService } from 'primeng/dynamicdialog'; +import { PaginatorState } from 'primeng/paginator'; import { map, of } from 'rxjs'; @@ -11,7 +12,12 @@ import { toSignal } from '@angular/core/rxjs-interop'; import { FormsModule } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; -import { LoadingSpinnerComponent, RegistrationCardComponent, SubHeaderComponent } from '@osf/shared/components'; +import { + CustomPaginatorComponent, + LoadingSpinnerComponent, + RegistrationCardComponent, + SubHeaderComponent, +} from '@osf/shared/components'; import { GetRegistrations, RegistrationsSelectors } from './store'; @@ -19,7 +25,14 @@ import { environment } from 'src/environments/environment'; @Component({ selector: 'osf-registrations', - imports: [RegistrationCardComponent, SubHeaderComponent, FormsModule, TranslatePipe, LoadingSpinnerComponent], + imports: [ + RegistrationCardComponent, + SubHeaderComponent, + FormsModule, + TranslatePipe, + LoadingSpinnerComponent, + CustomPaginatorComponent, + ], templateUrl: './registrations.component.html', styleUrl: './registrations.component.scss', providers: [DialogService], @@ -32,11 +45,15 @@ export class RegistrationsComponent implements OnInit { readonly projectId = toSignal(this.route.parent?.params.pipe(map((params) => params['id'])) ?? of(undefined)); registrations = select(RegistrationsSelectors.getRegistrations); + registrationsTotalCount = select(RegistrationsSelectors.getRegistrationsTotalCount); isRegistrationsLoading = select(RegistrationsSelectors.isRegistrationsLoading); actions = createDispatchMap({ getRegistrations: GetRegistrations }); + itemsPerPage = 10; + first = 0; + ngOnInit(): void { - this.actions.getRegistrations(this.projectId()); + this.actions.getRegistrations(this.projectId(), 1, this.itemsPerPage); } addRegistration(): void { @@ -44,4 +61,9 @@ export class RegistrationsComponent implements OnInit { queryParams: { projectId: this.projectId() }, }); } + + onPageChange(event: PaginatorState): void { + this.actions.getRegistrations(this.projectId(), event.page! + 1, this.itemsPerPage); + this.first = event.first!; + } } diff --git a/src/app/features/project/registrations/services/registrations.service.ts b/src/app/features/project/registrations/services/registrations.service.ts index c222b575d..07ecf3b84 100644 --- a/src/app/features/project/registrations/services/registrations.service.ts +++ b/src/app/features/project/registrations/services/registrations.service.ts @@ -15,10 +15,14 @@ export class RegistrationsService { private readonly jsonApiService = inject(JsonApiService); private readonly apiUrl = `${environment.apiDomainUrl}/v2`; - getRegistrations(projectId: string): Observable> { - const params: Record = { embed: 'contributors' }; + getRegistrations(projectId: string, page: number, pageSize: number): Observable> { + const params = { + page, + 'page[size]': pageSize, + embed: ['bibliographic_contributors', 'registration_schema', 'provider'], + }; - const url = `${this.apiUrl}/nodes/${projectId}/linked_by_registrations/`; + const url = `${this.apiUrl}/nodes/${projectId}/registrations/`; return this.jsonApiService.get>(url, params).pipe( map((response) => { diff --git a/src/app/features/project/registrations/store/registrations.actions.ts b/src/app/features/project/registrations/store/registrations.actions.ts index cec5e1dfd..81a2981ef 100644 --- a/src/app/features/project/registrations/store/registrations.actions.ts +++ b/src/app/features/project/registrations/store/registrations.actions.ts @@ -1,5 +1,9 @@ export class GetRegistrations { static readonly type = '[Registrations] Get Registrations'; - constructor(public projectId: string) {} + constructor( + public projectId: string, + public page = 1, + public pageSize = 10 + ) {} } diff --git a/src/app/features/project/registrations/store/registrations.selectors.ts b/src/app/features/project/registrations/store/registrations.selectors.ts index f958bf568..c72a45b9e 100644 --- a/src/app/features/project/registrations/store/registrations.selectors.ts +++ b/src/app/features/project/registrations/store/registrations.selectors.ts @@ -9,6 +9,11 @@ export class RegistrationsSelectors { return state.registrations.data; } + @Selector([RegistrationsState]) + static getRegistrationsTotalCount(state: RegistrationsStateModel): number { + return state.registrations.totalCount; + } + @Selector([RegistrationsState]) static isRegistrationsLoading(state: RegistrationsStateModel) { return state.registrations.isLoading; diff --git a/src/app/features/project/registrations/store/registrations.state.ts b/src/app/features/project/registrations/store/registrations.state.ts index 0fd503eee..a6cc768f9 100644 --- a/src/app/features/project/registrations/store/registrations.state.ts +++ b/src/app/features/project/registrations/store/registrations.state.ts @@ -27,7 +27,7 @@ export class RegistrationsState { registrations: { ...state.registrations, isLoading: true, error: null }, }); - return this.registrationsService.getRegistrations(action.projectId).pipe( + return this.registrationsService.getRegistrations(action.projectId, action.page, action.pageSize).pipe( tap((registrations) => { ctx.setState({ registrations: { diff --git a/src/app/features/registries/components/confirm-registration-dialog/confirm-registration-dialog.component.html b/src/app/features/registries/components/confirm-registration-dialog/confirm-registration-dialog.component.html index 9379b23c6..f4df946e2 100644 --- a/src/app/features/registries/components/confirm-registration-dialog/confirm-registration-dialog.component.html +++ b/src/app/features/registries/components/confirm-registration-dialog/confirm-registration-dialog.component.html @@ -58,6 +58,7 @@ [disabled]="isRegistrationSubmitting()" /> {{ 'common.links.showExample' | translate }} -
- -
+ + {{ 'common.links.hideExample' | translate }} +

{{ q.exampleText }}

@@ -207,6 +199,11 @@

{{ 'files.actions.uploadFile' | translate }}

class="mr-2" (click)="goBack()" >
- + diff --git a/src/app/features/registries/components/custom-step/custom-step.component.ts b/src/app/features/registries/components/custom-step/custom-step.component.ts index fb1467a82..59721646c 100644 --- a/src/app/features/registries/components/custom-step/custom-step.component.ts +++ b/src/app/features/registries/components/custom-step/custom-step.component.ts @@ -152,7 +152,6 @@ export class CustomStepComponent implements OnDestroy { break; default: - console.warn(`Unsupported field type: ${q.fieldType}`); return; } diff --git a/src/app/features/registries/components/metadata/metadata.component.html b/src/app/features/registries/components/metadata/metadata.component.html index c877f627a..a3bb08450 100644 --- a/src/app/features/registries/components/metadata/metadata.component.html +++ b/src/app/features/registries/components/metadata/metadata.component.html @@ -13,6 +13,7 @@

{{ 'registries.metadata.title' | translate }}