diff --git a/src/app/core/constants/nav-items.constant.ts b/src/app/core/constants/nav-items.constant.ts index efcc4338b..cb8e29bf0 100644 --- a/src/app/core/constants/nav-items.constant.ts +++ b/src/app/core/constants/nav-items.constant.ts @@ -31,14 +31,14 @@ export const PROJECT_MENU_ITEMS: MenuItem[] = [ label: 'navigation.overview', routerLink: 'overview', visible: true, - routerLinkActiveOptions: { exact: true }, + routerLinkActiveOptions: { exact: false }, }, { id: 'project-metadata', label: 'navigation.metadata', routerLink: 'metadata', visible: true, - routerLinkActiveOptions: { exact: true }, + routerLinkActiveOptions: { exact: false }, }, { id: 'project-files', @@ -107,14 +107,14 @@ export const REGISTRATION_MENU_ITEMS: MenuItem[] = [ label: 'navigation.overview', routerLink: 'overview', visible: true, - routerLinkActiveOptions: { exact: true }, + routerLinkActiveOptions: { exact: false }, }, { id: 'registration-metadata', label: 'navigation.metadata', routerLink: 'metadata', visible: true, - routerLinkActiveOptions: { exact: true }, + routerLinkActiveOptions: { exact: false }, }, { id: 'registration-files', diff --git a/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.ts b/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.ts index 68c5e097a..e7e155022 100644 --- a/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.ts +++ b/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.ts @@ -7,10 +7,8 @@ import { Button } from 'primeng/button'; import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, computed, OnDestroy, OnInit, signal } from '@angular/core'; -import { FiltersSectionComponent } from '@osf/features/admin-institutions/components/filters-section/filters-section.component'; -import { mapPreprintResourceToTableData } from '@osf/features/admin-institutions/mappers/institution-preprint-to-table-data.mapper'; import { ResourceType, SortOrder } from '@osf/shared/enums'; -import { SearchFilters } from '@osf/shared/models'; +import { PaginationLinksModel, SearchFilters } from '@osf/shared/models'; import { FetchResources, FetchResourcesByLink, @@ -22,9 +20,11 @@ import { } from '@shared/stores/global-search'; import { AdminTableComponent } from '../../components'; +import { FiltersSectionComponent } from '../../components/filters-section/filters-section.component'; import { preprintsTableColumns } from '../../constants'; import { DownloadType } from '../../enums'; import { downloadResults } from '../../helpers'; +import { mapPreprintResourceToTableData } from '../../mappers/institution-preprint-to-table-data.mapper'; import { TableCellData } from '../../models'; import { InstitutionsAdminSelectors } from '../../store'; @@ -75,7 +75,7 @@ export class InstitutionsPreprintsComponent implements OnInit, OnDestroy { next: { href: this.nextLink() }, prev: { href: this.previousLink() }, first: { href: this.firstLink() }, - }; + } as PaginationLinksModel; }); ngOnInit(): void { diff --git a/src/app/features/admin-institutions/pages/institutions-projects/institutions-projects.component.ts b/src/app/features/admin-institutions/pages/institutions-projects/institutions-projects.component.ts index f16029232..36939b6f5 100644 --- a/src/app/features/admin-institutions/pages/institutions-projects/institutions-projects.component.ts +++ b/src/app/features/admin-institutions/pages/institutions-projects/institutions-projects.component.ts @@ -19,11 +19,9 @@ import { } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; -import { UserSelectors } from '@osf/core/store/user'; -import { FiltersSectionComponent } from '@osf/features/admin-institutions/components/filters-section/filters-section.component'; -import { mapProjectResourceToTableCellData } from '@osf/features/admin-institutions/mappers/institution-project-to-table-data.mapper'; +import { UserSelectors } from '@core/store/user'; import { ResourceType, SortOrder } from '@osf/shared/enums'; -import { ResourceModel, SearchFilters } from '@osf/shared/models'; +import { PaginationLinksModel, ResourceModel, SearchFilters } from '@osf/shared/models'; import { ToastService } from '@osf/shared/services'; import { FetchResources, @@ -36,10 +34,12 @@ import { } from '@shared/stores/global-search'; import { AdminTableComponent } from '../../components'; +import { FiltersSectionComponent } from '../../components/filters-section/filters-section.component'; import { projectTableColumns } from '../../constants'; import { ContactDialogComponent } from '../../dialogs'; import { ContactOption, DownloadType } from '../../enums'; import { downloadResults } from '../../helpers'; +import { mapProjectResourceToTableCellData } from '../../mappers/institution-project-to-table-data.mapper'; import { ContactDialogData, TableCellData, TableCellLink, TableIconClickEvent } from '../../models'; import { InstitutionsAdminSelectors, RequestProjectAccess, SendUserMessage } from '../../store'; @@ -101,7 +101,7 @@ export class InstitutionsProjectsComponent implements OnInit, OnDestroy { next: { href: this.nextLink() }, prev: { href: this.previousLink() }, first: { href: this.firstLink() }, - }; + } as PaginationLinksModel; }); ngOnInit(): void { diff --git a/src/app/features/admin-institutions/pages/institutions-registrations/institutions-registrations.component.ts b/src/app/features/admin-institutions/pages/institutions-registrations/institutions-registrations.component.ts index 9bccf44ca..bec708727 100644 --- a/src/app/features/admin-institutions/pages/institutions-registrations/institutions-registrations.component.ts +++ b/src/app/features/admin-institutions/pages/institutions-registrations/institutions-registrations.component.ts @@ -7,10 +7,8 @@ import { Button } from 'primeng/button'; import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, computed, OnDestroy, OnInit, signal } from '@angular/core'; -import { FiltersSectionComponent } from '@osf/features/admin-institutions/components/filters-section/filters-section.component'; -import { mapRegistrationResourceToTableData } from '@osf/features/admin-institutions/mappers/institution-registration-to-table-data.mapper'; import { ResourceType, SortOrder } from '@osf/shared/enums'; -import { SearchFilters } from '@osf/shared/models'; +import { PaginationLinksModel, SearchFilters } from '@osf/shared/models'; import { ClearFilterSearchResults, FetchResources, @@ -23,9 +21,11 @@ import { } from '@shared/stores/global-search'; import { AdminTableComponent } from '../../components'; +import { FiltersSectionComponent } from '../../components/filters-section/filters-section.component'; import { registrationTableColumns } from '../../constants'; import { DownloadType } from '../../enums'; import { downloadResults } from '../../helpers'; +import { mapRegistrationResourceToTableData } from '../../mappers/institution-registration-to-table-data.mapper'; import { TableCellData } from '../../models'; import { InstitutionsAdminSelectors } from '../../store'; @@ -77,7 +77,7 @@ export class InstitutionsRegistrationsComponent implements OnInit, OnDestroy { next: { href: this.nextLink() }, prev: { href: this.previousLink() }, first: { href: this.firstLink() }, - }; + } as PaginationLinksModel; }); ngOnInit(): void { diff --git a/src/app/features/metadata/components/cedar-template-form/cedar-template-form.component.html b/src/app/features/metadata/components/cedar-template-form/cedar-template-form.component.html index a768da6b2..465feaaa0 100644 --- a/src/app/features/metadata/components/cedar-template-form/cedar-template-form.component.html +++ b/src/app/features/metadata/components/cedar-template-form/cedar-template-form.component.html @@ -10,7 +10,7 @@

{{ 'project.metadata.addMetadata.notPublishedTe diff --git a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html index e6cd70eff..2c4a1e26d 100644 --- a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html +++ b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.html @@ -1,7 +1,8 @@
diff --git a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.spec.ts b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.spec.ts index e6de77602..6e23661ce 100644 --- a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.spec.ts +++ b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.spec.ts @@ -1,8 +1,8 @@ import { Store } from '@ngxs/store'; -import { MockProvider } from 'ng-mocks'; +import { MockProvider, MockProviders } from 'ng-mocks'; -import { DynamicDialogRef } from 'primeng/dynamicdialog'; +import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; import { ComponentFixture, TestBed } from '@angular/core/testing'; @@ -23,7 +23,11 @@ describe('AffiliatedInstitutionsDialogComponent', () => { }); await TestBed.configureTestingModule({ imports: [AffiliatedInstitutionsDialogComponent], - providers: [TranslateServiceMock, MockProvider(DynamicDialogRef), MockProvider(Store, MOCK_STORE)], + providers: [ + TranslateServiceMock, + MockProviders(DynamicDialogRef, DynamicDialogConfig), + MockProvider(Store, MOCK_STORE), + ], }).compileComponents(); fixture = TestBed.createComponent(AffiliatedInstitutionsDialogComponent); diff --git a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.ts b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.ts index 5f08d5cd0..1733ece21 100644 --- a/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.ts +++ b/src/app/features/metadata/dialogs/affiliated-institutions-dialog/affiliated-institutions-dialog.component.ts @@ -1,16 +1,16 @@ -import { select } from '@ngxs/store'; +import { createDispatchMap, select } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; import { Button } from 'primeng/button'; -import { DynamicDialogRef } from 'primeng/dynamicdialog'; +import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog'; -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { AffiliatedInstitutionSelectComponent } from '@osf/shared/components'; import { Institution } from '@osf/shared/models'; -import { InstitutionsSelectors } from '@osf/shared/stores'; +import { FetchUserInstitutions, InstitutionsSelectors } from '@osf/shared/stores'; @Component({ selector: 'osf-affiliated-institutions-dialog', @@ -18,20 +18,22 @@ import { InstitutionsSelectors } from '@osf/shared/stores'; templateUrl: './affiliated-institutions-dialog.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class AffiliatedInstitutionsDialogComponent { +export class AffiliatedInstitutionsDialogComponent implements OnInit { dialogRef = inject(DynamicDialogRef); + config = inject(DynamicDialogConfig); + actions = createDispatchMap({ fetchUserInstitutions: FetchUserInstitutions }); userInstitutions = select(InstitutionsSelectors.getUserInstitutions); areUserInstitutionsLoading = select(InstitutionsSelectors.areUserInstitutionsLoading); - selectedInstitutions: Institution[] = []; + selectedInstitutions = signal(this.config.data || []); - onSelectInstitutions(selectedInstitutions: Institution[]): void { - this.selectedInstitutions = selectedInstitutions; + ngOnInit() { + this.actions.fetchUserInstitutions(); } save(): void { - this.dialogRef.close(this.selectedInstitutions); + this.dialogRef.close(this.selectedInstitutions()); } cancel(): void { diff --git a/src/app/features/metadata/metadata.component.ts b/src/app/features/metadata/metadata.component.ts index a2c638d68..5054fd063 100644 --- a/src/app/features/metadata/metadata.component.ts +++ b/src/app/features/metadata/metadata.component.ts @@ -428,24 +428,23 @@ export class MetadataComponent implements OnInit { } openEditAffiliatedInstitutionsDialog(): void { - const dialogRef = this.dialogService.open(AffiliatedInstitutionsDialogComponent, { - header: this.translateService.instant('project.metadata.affiliatedInstitutions.dialog.header'), - width: '500px', - focusOnShow: false, - closeOnEscape: true, - modal: true, - closable: true, - }); - dialogRef.onClose - .pipe( + this.dialogService + .open(AffiliatedInstitutionsDialogComponent, { + header: this.translateService.instant('project.metadata.affiliatedInstitutions.dialog.header'), + width: '500px', + focusOnShow: false, + closeOnEscape: true, + modal: true, + closable: true, + data: this.affiliatedInstitutions(), + }) + .onClose.pipe( filter((result) => !!result), - switchMap((institutions) => { - return this.actions.updateResourceInstitutions(this.resourceId, this.resourceType(), institutions); - }) + switchMap((institutions) => + this.actions.updateResourceInstitutions(this.resourceId, this.resourceType(), institutions) + ) ) - .subscribe({ - next: () => this.toastService.showSuccess('project.metadata.affiliatedInstitutions.updated'), - }); + .subscribe(() => this.toastService.showSuccess('project.metadata.affiliatedInstitutions.updated')); } getSubjectChildren(parentId: string) { diff --git a/src/app/features/my-projects/my-projects.component.html b/src/app/features/my-projects/my-projects.component.html index f584ef2b9..b06ba25fe 100644 --- a/src/app/features/my-projects/my-projects.component.html +++ b/src/app/features/my-projects/my-projects.component.html @@ -70,21 +70,17 @@ - @if (!bookmarks().length && !isLoading()) { -

{{ 'myProjects.bookmarks.emptyState' | translate }}

- } @else { - - } +
diff --git a/src/app/features/preprints/components/preprint-details/general-information/general-information.component.ts b/src/app/features/preprints/components/preprint-details/general-information/general-information.component.ts index a4a2a176c..c6ce10509 100644 --- a/src/app/features/preprints/components/preprint-details/general-information/general-information.component.ts +++ b/src/app/features/preprints/components/preprint-details/general-information/general-information.component.ts @@ -7,7 +7,6 @@ import { Skeleton } from 'primeng/skeleton'; import { ChangeDetectionStrategy, Component, computed, effect, input, OnDestroy, output } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { RouterLink } from '@angular/router'; import { PreprintDoiSectionComponent } from '@osf/features/preprints/components/preprint-details/preprint-doi-section/preprint-doi-section.component'; import { ApplicabilityStatus, PreregLinkInfo } from '@osf/features/preprints/enums'; @@ -29,7 +28,6 @@ import { environment } from 'src/environments/environment'; Skeleton, FormsModule, PreprintDoiSectionComponent, - RouterLink, IconComponent, AffiliatedInstitutionsViewComponent, ], diff --git a/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.html b/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.html index 513d64186..f8d105da8 100644 --- a/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.html +++ b/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.html @@ -1,17 +1,21 @@

{{ 'preprints.preprintStepper.metadata.affiliatedInstitutionsTitle' | translate }}

-

+

{{ 'preprints.preprintStepper.metadata.affiliatedInstitutionsDescription' | translate: { preprintWord: provider()?.preprintWord } }}

-
+
diff --git a/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.ts b/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.ts index bf64dbebb..5941b7ca4 100644 --- a/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.ts +++ b/src/app/features/preprints/components/stepper/metadata-step/preprints-affiliated-institutions/preprints-affiliated-institutions.component.ts @@ -1,16 +1,21 @@ -import { createDispatchMap } from '@ngxs/store'; +import { createDispatchMap, select } from '@ngxs/store'; import { TranslatePipe } from '@ngx-translate/core'; import { Card } from 'primeng/card'; -import { ChangeDetectionStrategy, Component, input, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, input, OnInit, signal } from '@angular/core'; import { PreprintProviderDetails } from '@osf/features/preprints/models'; import { AffiliatedInstitutionSelectComponent } from '@shared/components'; import { ResourceType } from '@shared/enums'; import { Institution } from '@shared/models'; -import { FetchResourceInstitutions, UpdateResourceInstitutions } from '@shared/stores/institutions'; +import { + FetchResourceInstitutions, + FetchUserInstitutions, + InstitutionsSelectors, + UpdateResourceInstitutions, +} from '@shared/stores/institutions'; @Component({ selector: 'osf-preprints-affiliated-institutions', @@ -20,19 +25,39 @@ import { FetchResourceInstitutions, UpdateResourceInstitutions } from '@shared/s changeDetection: ChangeDetectionStrategy.OnPush, }) export class PreprintsAffiliatedInstitutionsComponent implements OnInit { - preprintId = input(); provider = input.required(); + preprintId = input(); + + selectedInstitutions = signal([]); - private actions = createDispatchMap({ + userInstitutions = select(InstitutionsSelectors.getUserInstitutions); + areUserInstitutionsLoading = select(InstitutionsSelectors.areUserInstitutionsLoading); + resourceInstitutions = select(InstitutionsSelectors.getResourceInstitutions); + areResourceInstitutionsLoading = select(InstitutionsSelectors.areResourceInstitutionsLoading); + areResourceInstitutionsSubmitting = select(InstitutionsSelectors.areResourceInstitutionsSubmitting); + + private readonly actions = createDispatchMap({ + fetchUserInstitutions: FetchUserInstitutions, fetchResourceInstitutions: FetchResourceInstitutions, updateResourceInstitutions: UpdateResourceInstitutions, }); + constructor() { + effect(() => { + const resourceInstitutions = this.resourceInstitutions(); + if (resourceInstitutions.length > 0) { + this.selectedInstitutions.set([...resourceInstitutions]); + } + }); + } + ngOnInit() { + this.actions.fetchUserInstitutions(); this.actions.fetchResourceInstitutions(this.preprintId()!, ResourceType.Preprint); } - institutionsSelected(institutions: Institution[]) { + onInstitutionsChange(institutions: Institution[]): void { + this.selectedInstitutions.set(institutions); this.actions.updateResourceInstitutions(this.preprintId()!, ResourceType.Preprint, institutions); } } diff --git a/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.html b/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.html index 529dd73f8..cc505bfa3 100644 --- a/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.html +++ b/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.html @@ -7,8 +7,12 @@

{{ 'project.overview.metadata.affiliatedInstitutions' | translate }}

@if (userInstitutions().length) {
} @else { diff --git a/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.ts b/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.ts index b0162d55a..1a6ffdad8 100644 --- a/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.ts +++ b/src/app/features/registries/components/metadata/registries-affiliated-institution/registries-affiliated-institution.component.ts @@ -4,7 +4,7 @@ import { TranslatePipe } from '@ngx-translate/core'; import { Card } from 'primeng/card'; -import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, effect, inject, OnInit, signal } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { AffiliatedInstitutionSelectComponent } from '@osf/shared/components'; @@ -27,8 +27,14 @@ import { export class RegistriesAffiliatedInstitutionComponent implements OnInit { private readonly route = inject(ActivatedRoute); private readonly draftId = this.route.snapshot.params['id']; - readonly userInstitutions = select(InstitutionsSelectors.getUserInstitutions); - readonly areResourceInstitutionsLoading = select(InstitutionsSelectors.areResourceInstitutionsLoading); + + selectedInstitutions = signal([]); + + userInstitutions = select(InstitutionsSelectors.getUserInstitutions); + areUserInstitutionsLoading = select(InstitutionsSelectors.areUserInstitutionsLoading); + resourceInstitutions = select(InstitutionsSelectors.getResourceInstitutions); + areResourceInstitutionsLoading = select(InstitutionsSelectors.areResourceInstitutionsLoading); + areResourceInstitutionsSubmitting = select(InstitutionsSelectors.areResourceInstitutionsSubmitting); private actions = createDispatchMap({ fetchUserInstitutions: FetchUserInstitutions, @@ -36,6 +42,15 @@ export class RegistriesAffiliatedInstitutionComponent implements OnInit { updateResourceInstitutions: UpdateResourceInstitutions, }); + constructor() { + effect(() => { + const resourceInstitutions = this.resourceInstitutions(); + if (resourceInstitutions.length > 0) { + this.selectedInstitutions.set([...resourceInstitutions]); + } + }); + } + ngOnInit() { this.actions.fetchUserInstitutions(); this.actions.fetchResourceInstitutions(this.draftId, ResourceType.DraftRegistration); diff --git a/src/app/shared/components/add-project-form/add-project-form.component.html b/src/app/shared/components/add-project-form/add-project-form.component.html index ee76fb2c5..3de7dced4 100644 --- a/src/app/shared/components/add-project-form/add-project-form.component.html +++ b/src/app/shared/components/add-project-form/add-project-form.component.html @@ -20,15 +20,18 @@ />
-
-

- {{ 'myProjects.createProject.affiliation.title' | translate }} -

- -
+ @if (affiliations() && affiliations().length) { +
+

+ {{ 'myProjects.createProject.affiliation.title' | translate }} +

+ +
+ }