Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,10 @@ module.exports = {
'<rootDir>/src/app/app.config.ts',
'<rootDir>/src/app/app.routes.ts',
'<rootDir>/src/app/features/registry/',
'<rootDir>/src/app/features/project/addons/components/configure-configure-addon/',
'<rootDir>/src/app/features/project/addons/components/connect-configured-addon/',
'<rootDir>/src/app/features/project/addons/components/disconnect-addon-modal/',
'<rootDir>/src/app/features/project/addons',
'<rootDir>/src/app/features/project/analytics/',
'<rootDir>/src/app/features/project/contributors/',
'<rootDir>/src/app/features/project/files/',
'<rootDir>/src/app/features/files/',
'<rootDir>/src/app/features/project/metadata/',
'<rootDir>/src/app/features/project/overview/',
'<rootDir>/src/app/features/project/registrations',
Expand Down
26 changes: 24 additions & 2 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { createDispatchMap } from '@ngxs/store';

import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { filter } from 'rxjs/operators';

import { ChangeDetectionStrategy, Component, DestroyRef, inject, OnInit } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { NavigationEnd, Router, RouterOutlet } from '@angular/router';

import { GetCurrentUser } from '@core/store/user';

import { FullScreenLoaderComponent, ToastComponent } from './shared/components';
import { MetaTagsService } from './shared/services/meta-tags.service';

@Component({
selector: 'osf-root',
Expand All @@ -15,11 +19,29 @@ import { FullScreenLoaderComponent, ToastComponent } from './shared/components';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent implements OnInit {
private destroyRef = inject(DestroyRef);

actions = createDispatchMap({
getCurrentUser: GetCurrentUser,
});

constructor(
private router: Router,
private metaTagsService: MetaTagsService
) {
this.setupMetaTagsCleanup();
}

ngOnInit(): void {
this.actions.getCurrentUser();
}

private setupMetaTagsCleanup(): void {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
takeUntilDestroyed(this.destroyRef)
)
.subscribe((event: NavigationEnd) => this.metaTagsService.clearMetaTagsIfNeeded(event.url));
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { TranslatePipe } from '@ngx-translate/core';
import { MockPipe, MockProviders } from 'ng-mocks';

import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ContactDialogComponent } from './contact-dialog.component';
Expand All @@ -8,7 +13,8 @@ describe('ContactDialogComponent', () => {

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ContactDialogComponent],
imports: [ContactDialogComponent, MockPipe(TranslatePipe)],
providers: [MockProviders(DynamicDialogRef, DynamicDialogConfig)],
}).compileComponents();

fixture = TestBed.createComponent(ContactDialogComponent);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { provideStore } from '@ngxs/store';

import { TranslatePipe } from '@ngx-translate/core';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { MockComponents, MockPipe, MockProvider } from 'ng-mocks';

import { of } from 'rxjs';
Expand All @@ -12,6 +12,7 @@ import { ActivatedRoute } from '@angular/router';

import { AdminTableComponent } from '@osf/features/admin-institutions/components';
import { InstitutionsAdminState } from '@osf/features/admin-institutions/store';
import { ToastService } from '@osf/shared/services';
import { LoadingSpinnerComponent } from '@shared/components';
import { InstitutionsSearchState } from '@shared/stores';

Expand All @@ -30,6 +31,8 @@ describe('InstitutionsProjectsComponent', () => {
],
providers: [
MockProvider(ActivatedRoute, { queryParams: of({}) }),
MockProvider(ToastService),
MockProvider(TranslateService),
provideStore([InstitutionsAdminState, InstitutionsSearchState]),
provideHttpClient(),
provideHttpClientTesting(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { UserState } from '@core/store/user';
import { AdminTableComponent } from '@osf/features/admin-institutions/components';
import { InstitutionsAdminState } from '@osf/features/admin-institutions/store';
import { ToastService } from '@osf/shared/services';
import { InstitutionsSearchState } from '@osf/shared/stores';
import { LoadingSpinnerComponent, SelectComponent } from '@shared/components';
import { TranslateServiceMock } from '@shared/mocks';

Expand All @@ -35,7 +36,7 @@ describe('InstitutionsUsersComponent', () => {
MockProvider(Router),
TranslateServiceMock,
MockProvider(ToastService),
provideStore([InstitutionsAdminState, UserState]),
provideStore([InstitutionsAdminState, UserState, InstitutionsSearchState]),
provideHttpClient(),
provideHttpClientTesting(),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Skeleton } from 'primeng/skeleton';

import { filter, map, of } from 'rxjs';

import { DatePipe } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
Expand All @@ -30,21 +31,25 @@ import {
StatusBannerComponent,
WithdrawDialogComponent,
} from '@osf/features/preprints/components';
import { PreprintTombstoneComponent } from '@osf/features/preprints/components/preprint-details/preprint-tombstone/preprint-tombstone.component';
import { PreprintRequestMachineState, ProviderReviewsWorkflow, ReviewsState } from '@osf/features/preprints/enums';
import { UserPermissions } from '@osf/shared/enums';
import { IS_MEDIUM, pathJoin } from '@osf/shared/helpers';
import { ContributorModel } from '@osf/shared/models';
import { MetaTagsService } from '@osf/shared/services';
import { ContributorsSelectors } from '@osf/shared/stores';

import { PreprintTombstoneComponent } from '../../components/preprint-details/preprint-tombstone/preprint-tombstone.component';
import { PreprintRequestMachineState, ProviderReviewsWorkflow, ReviewsState } from '../../enums';
import {
FetchPreprintById,
FetchPreprintRequests,
FetchPreprintReviewActions,
PreprintSelectors,
ResetState,
} from '@osf/features/preprints/store/preprint';
import { GetPreprintProviderById, PreprintProvidersSelectors } from '@osf/features/preprints/store/preprint-providers';
import { CreateNewVersion, PreprintStepperSelectors } from '@osf/features/preprints/store/preprint-stepper';
import { IS_MEDIUM } from '@osf/shared/helpers';
import { UserPermissions } from '@shared/enums';
import { ContributorModel } from '@shared/models';
import { ContributorsSelectors } from '@shared/stores';
} from '../../store/preprint';
import { GetPreprintProviderById, PreprintProvidersSelectors } from '../../store/preprint-providers';
import { CreateNewVersion, PreprintStepperSelectors } from '../../store/preprint-stepper';

import { environment } from 'src/environments/environment';

@Component({
selector: 'osf-preprint-details',
Expand All @@ -61,7 +66,7 @@ import { ContributorsSelectors } from '@shared/stores';
],
templateUrl: './preprint-details.component.html',
styleUrl: './preprint-details.component.scss',
providers: [DialogService],
providers: [DialogService, DatePipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PreprintDetailsComponent implements OnInit, OnDestroy {
Expand All @@ -73,6 +78,8 @@ export class PreprintDetailsComponent implements OnInit, OnDestroy {
private readonly dialogService = inject(DialogService);
private readonly destroyRef = inject(DestroyRef);
private readonly translateService = inject(TranslateService);
private readonly metaTags = inject(MetaTagsService);
private readonly datePipe = inject(DatePipe);
private readonly isMedium = toSignal(inject(IS_MEDIUM));

private providerId = toSignal(this.route.params.pipe(map((params) => params['providerId'])) ?? of(undefined));
Expand Down Expand Up @@ -280,10 +287,34 @@ export class PreprintDetailsComponent implements OnInit, OnDestroy {
this.actions.fetchPreprintRequests();
this.actions.fetchPreprintReviewActions();
}

this.setMetaTags();
},
});
}

private setMetaTags() {
const image = 'engines-dist/registries/assets/img/osf-sharing.png';

this.metaTags.updateMetaTags({
title: this.preprint()?.title,
description: this.preprint()?.description,
publishedDate: this.datePipe.transform(this.preprint()?.dateCreated, 'yyyy-MM-dd'),
modifiedDate: this.datePipe.transform(this.preprint()?.dateModified, 'yyyy-MM-dd'),
url: pathJoin(environment.webUrl, this.preprint()?.id ?? ''),
image,
identifier: this.preprint()?.id,
doi: this.preprint()?.doi,
keywords: this.preprint()?.tags,
siteName: 'OSF',
license: this.preprint()?.embeddedLicense?.name,
contributors: this.contributors().map((contributor) => ({
givenName: contributor.fullName,
familyName: contributor.familyName,
})),
});
}

private hasReadWriteAccess(): boolean {
return this.preprint()?.currentUserPermissions.includes(UserPermissions.Write) || false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ export class OverviewToolbarComponent {
protected destroyRef = inject(DestroyRef);
private readonly router = inject(Router);
private readonly route = inject(ActivatedRoute);
isCollectionsRoute = input<boolean>(false);
protected isPublic = signal(false);
protected isBookmarked = signal(false);

isCollectionsRoute = input<boolean>(false);
isAdmin = input.required<boolean>();
currentResource = input.required<ToolbarResource | null>();
showViewOnlyLinks = input<boolean>(true);

protected isBookmarksLoading = select(MyResourcesSelectors.getBookmarksLoading);
protected isBookmarksSubmitting = select(BookmarksSelectors.getBookmarksCollectionIdSubmitting);
protected bookmarksCollectionId = select(BookmarksSelectors.getBookmarksCollectionId);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@use "/assets/styles/variables" as var;
@use "assets/styles/mixins" as mix;

.left-section {
Expand All @@ -9,20 +8,20 @@
}

.accordion-border {
border: 1px solid var.$grey-2;
border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
height: max-content !important;
}

.blocks-section {
border: 1px solid var.$grey-2;
border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
height: max-content;
}

.right-section {
flex: 1;
border: 1px solid var.$grey-2;
border: 1px solid var(--grey-2);
border-radius: mix.rem(12px);
height: max-content;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ import { GetBookmarksCollectionId } from '@shared/stores';
import { ArchivingMessageComponent, RegistryRevisionsComponent, RegistryStatusesComponent } from '../../components';
import { RegistryMakeDecisionComponent } from '../../components/registry-make-decision/registry-make-decision.component';
import { WithdrawnMessageComponent } from '../../components/withdrawn-message/withdrawn-message.component';
import { GetRegistryInstitutions, GetRegistrySubjects } from '../../store/registry-metadata';
import {
GetRegistryById,
GetRegistryInstitutions,
GetRegistryReviewActions,
GetRegistrySubjects,
RegistryOverviewSelectors,
SetRegistryCustomCitation,
} from '../../store/registry-overview';
Expand All @@ -59,16 +60,17 @@ import {
templateUrl: './registry-overview.component.html',
styleUrl: './registry-overview.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [DialogService],
providers: [DialogService, DatePipe],
})
export class RegistryOverviewComponent {
@HostBinding('class') classes = 'flex-1 flex flex-column w-full h-full';
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);
private readonly destroyRef = inject(DestroyRef);
protected readonly toastService = inject(ToastService);
protected readonly dialogService = inject(DialogService);
protected readonly translateService = inject(TranslateService);
private readonly toastService = inject(ToastService);
private readonly dialogService = inject(DialogService);
private readonly translateService = inject(TranslateService);
private readonly datePipe = inject(DatePipe);

protected readonly registry = select(RegistryOverviewSelectors.getRegistry);
protected readonly isRegistryLoading = select(RegistryOverviewSelectors.isRegistryLoading);
Expand All @@ -78,7 +80,7 @@ export class RegistryOverviewComponent {
protected readonly isInstitutionsLoading = select(RegistryOverviewSelectors.isInstitutionsLoading);
protected readonly schemaBlocks = select(RegistryOverviewSelectors.getSchemaBlocks);
protected readonly isSchemaBlocksLoading = select(RegistryOverviewSelectors.isSchemaBlocksLoading);
protected areReviewActionsLoading = select(RegistryOverviewSelectors.areReviewActionsLoading);
protected readonly areReviewActionsLoading = select(RegistryOverviewSelectors.areReviewActionsLoading);
protected readonly currentRevision = select(RegistriesSelectors.getSchemaResponse);
protected readonly isSchemaResponseLoading = select(RegistriesSelectors.getSchemaResponseLoading);
protected revisionInProgress: SchemaResponse | undefined;
Expand Down Expand Up @@ -173,6 +175,7 @@ export class RegistryOverviewComponent {
.subscribe();
}
});

this.actions.getBookmarksId();
this.route.queryParams
.pipe(
Expand Down
51 changes: 50 additions & 1 deletion src/app/features/registry/registry.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,62 @@
import { ChangeDetectionStrategy, Component, HostBinding } from '@angular/core';
import { select } from '@ngxs/store';

import { DatePipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, effect, HostBinding, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';

import { pathJoin } from '@osf/shared/helpers';
import { MetaTagsService } from '@osf/shared/services';

import { RegistryOverviewSelectors } from './store/registry-overview';

import { environment } from 'src/environments/environment';

@Component({
selector: 'osf-registry',
imports: [RouterOutlet],
templateUrl: './registry.component.html',
styleUrl: './registry.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [DatePipe],
})
export class RegistryComponent {
@HostBinding('class') classes = 'flex-1 flex flex-column';

private readonly metaTags = inject(MetaTagsService);
private readonly datePipe = inject(DatePipe);

protected readonly registry = select(RegistryOverviewSelectors.getRegistry);

constructor() {
effect(() => {
if (this.registry()) {
this.setMetaTags();
}
});
}

private setMetaTags(): void {
const image = 'engines-dist/registries/assets/img/osf-sharing.png';

this.metaTags.updateMetaTagsForRoute(
{
title: this.registry()?.title,
description: this.registry()?.description,
publishedDate: this.datePipe.transform(this.registry()?.dateRegistered, 'yyyy-MM-dd'),
modifiedDate: this.datePipe.transform(this.registry()?.dateModified, 'yyyy-MM-dd'),
url: pathJoin(environment.webUrl, this.registry()?.id ?? ''),
image,
identifier: this.registry()?.id,
doi: this.registry()?.doi,
keywords: this.registry()?.tags,
siteName: 'OSF',
license: this.registry()?.license?.name,
contributors: this.registry()?.contributors.map((contributor) => ({
givenName: contributor.givenName,
familyName: contributor.familyName,
})),
},
'registries'
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}
</div>

@if (totalUsersCount()) {
@if (totalUsersCount() > pageSize()) {
<osf-custom-paginator
[first]="first()"
[totalCount]="totalUsersCount()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class AddContributorDialogComponent implements OnInit, OnDestroy {
protected currentState = signal(AddDialogState.Search);
protected currentPage = signal(1);
protected first = signal(0);
protected pageSize = signal(10);

protected selectedUsers = signal<ContributorAddModel[]>([]);
protected searchControl = new FormControl<string>('');
Expand Down
Loading