diff --git a/src/app/core/components/root/root.component.spec.ts b/src/app/core/components/root/root.component.spec.ts
index a385fe1fe..8e1bb702c 100644
--- a/src/app/core/components/root/root.component.spec.ts
+++ b/src/app/core/components/root/root.component.spec.ts
@@ -11,7 +11,9 @@ import { BreadcrumbComponent } from '@core/components/breadcrumb/breadcrumb.comp
import { FooterComponent } from '@core/components/footer/footer.component';
import { HeaderComponent } from '@core/components/header/header.component';
import { TopnavComponent } from '@core/components/topnav/topnav.component';
-import { IS_WEB, IS_XSMALL } from '@osf/shared/utils/breakpoints.tokens';
+import { IS_WEB, IS_XSMALL } from '@osf/shared/utils';
+
+import { SidenavComponent } from '../sidenav/sidenav.component';
import { RootComponent } from './root.component';
@@ -28,7 +30,14 @@ describe('RootComponent', () => {
await TestBed.configureTestingModule({
imports: [
RootComponent,
- ...MockComponents(HeaderComponent, FooterComponent, TopnavComponent, ConfirmDialog, BreadcrumbComponent),
+ ...MockComponents(
+ HeaderComponent,
+ FooterComponent,
+ TopnavComponent,
+ ConfirmDialog,
+ BreadcrumbComponent,
+ SidenavComponent
+ ),
],
providers: [
MockProvider(IS_WEB, isWebSubject),
diff --git a/src/app/core/components/root/root.component.ts b/src/app/core/components/root/root.component.ts
index bd78eff74..243b76b63 100644
--- a/src/app/core/components/root/root.component.ts
+++ b/src/app/core/components/root/root.component.ts
@@ -11,7 +11,7 @@ import { HeaderComponent } from '@core/components/header/header.component';
import { TopnavComponent } from '@core/components/topnav/topnav.component';
import { IS_MEDIUM, IS_WEB } from '@shared/utils';
-import { NavMenuComponent } from '../nav-menu/nav-menu.component';
+import { SidenavComponent } from '../sidenav/sidenav.component';
@Component({
selector: 'osf-root',
@@ -23,7 +23,7 @@ import { NavMenuComponent } from '../nav-menu/nav-menu.component';
ConfirmDialog,
BreadcrumbComponent,
RouterOutlet,
- NavMenuComponent,
+ SidenavComponent,
],
templateUrl: './root.component.html',
styleUrls: ['./root.component.scss'],
diff --git a/src/app/core/components/sidenav/sidenav.component.html b/src/app/core/components/sidenav/sidenav.component.html
new file mode 100644
index 000000000..dc22dbcb6
--- /dev/null
+++ b/src/app/core/components/sidenav/sidenav.component.html
@@ -0,0 +1,4 @@
+
diff --git a/src/app/core/components/sidenav/sidenav.component.scss b/src/app/core/components/sidenav/sidenav.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/app/core/components/sidenav/sidenav.component.spec.ts b/src/app/core/components/sidenav/sidenav.component.spec.ts
new file mode 100644
index 000000000..0f5064358
--- /dev/null
+++ b/src/app/core/components/sidenav/sidenav.component.spec.ts
@@ -0,0 +1,26 @@
+import { MockComponent } from 'ng-mocks';
+
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NavMenuComponent } from '../nav-menu/nav-menu.component';
+
+import { SidenavComponent } from './sidenav.component';
+
+describe('SidenavDComponent', () => {
+ let component: SidenavComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [SidenavComponent, MockComponent(NavMenuComponent)],
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(SidenavComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/core/components/sidenav/sidenav.component.ts b/src/app/core/components/sidenav/sidenav.component.ts
new file mode 100644
index 000000000..d33c9dc50
--- /dev/null
+++ b/src/app/core/components/sidenav/sidenav.component.ts
@@ -0,0 +1,13 @@
+import { NgOptimizedImage } from '@angular/common';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
+
+import { NavMenuComponent } from '@core/components/nav-menu/nav-menu.component';
+
+@Component({
+ selector: 'osf-sidenav',
+ imports: [NgOptimizedImage, NavMenuComponent],
+ templateUrl: './sidenav.component.html',
+ styleUrl: './sidenav.component.scss',
+ changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class SidenavComponent {}
diff --git a/src/app/core/components/topnav/topnav.component.html b/src/app/core/components/topnav/topnav.component.html
index fa4953dde..ef1dadeca 100644
--- a/src/app/core/components/topnav/topnav.component.html
+++ b/src/app/core/components/topnav/topnav.component.html
@@ -11,7 +11,7 @@
-
-
+
-
+
{{ 'home.loggedIn.publicProjects.title' | translate }}
-
+
{{ 'home.loggedIn.latestResearch.title' | translate }}
{{ 'home.loggedIn.latestResearch.subtitle' | translate }}
@@ -48,7 +48,7 @@
{{ 'home.loggedIn.latestResearch.title' | translate }}
-
+
{{ 'home.loggedIn.hosting.title' | translate }}
{{ 'home.loggedIn.hosting.subtitle' | translate }}
diff --git a/src/app/features/home/home.component.scss b/src/app/features/home/home.component.scss
index c2028f374..7d101630f 100644
--- a/src/app/features/home/home.component.scss
+++ b/src/app/features/home/home.component.scss
@@ -4,46 +4,36 @@
:host {
display: flex;
flex-direction: column;
+}
- .home-container {
- max-width: 100%;
- }
+.home-container {
+ max-width: 100%;
+}
- .quick-search-container {
- background-color: var.$white;
- padding: mix.rem(24px) mix.rem(16px);
+.quick-search-container {
+ background-color: var.$white;
- .text-center {
- color: var.$dark-blue-1;
- }
+ .text-center {
+ color: var.$dark-blue-1;
}
+}
- .public-projects-container {
- background-color: var.$gradient-1;
- padding: mix.rem(48px) mix.rem(16px) mix.rem(24px);
-
- .osf-icon-search {
- color: var.$dark-blue-1;
- font-size: mix.rem(32px);
- margin-right: mix.rem(12px);
- }
- }
+.public-projects-container {
+ background-color: var.$gradient-1;
- .latest-research-container {
- background-color: var.$bg-blue-3;
- row-gap: mix.rem(24px);
- padding: mix.rem(48px) mix.rem(16px);
+ .osf-icon-search {
+ color: var.$dark-blue-1;
+ font-size: mix.rem(32px);
+ margin-right: mix.rem(12px);
}
+}
- .hosting-container {
- background-color: var.$bg-blue-2;
- row-gap: mix.rem(24px);
- padding: mix.rem(48px) mix.rem(16px);
- }
+.latest-research-container {
+ background-color: var.$bg-blue-3;
+ row-gap: mix.rem(24px);
+}
- .medium {
- .quick-search-container {
- padding: mix.rem(12px) mix.rem(36px) mix.rem(24px);
- }
- }
+.hosting-container {
+ background-color: var.$bg-blue-2;
+ row-gap: mix.rem(24px);
}
diff --git a/src/app/features/project/contributors/components/add-contributor-dialog/add-contributor-dialog.component.ts b/src/app/features/project/contributors/components/add-contributor-dialog/add-contributor-dialog.component.ts
index df5c944c7..5fdf93299 100644
--- a/src/app/features/project/contributors/components/add-contributor-dialog/add-contributor-dialog.component.ts
+++ b/src/app/features/project/contributors/components/add-contributor-dialog/add-contributor-dialog.component.ts
@@ -9,7 +9,7 @@ import { PaginatorState } from 'primeng/paginator';
import { debounceTime, distinctUntilChanged, filter, switchMap } from 'rxjs';
-import { ChangeDetectionStrategy, Component, DestroyRef, inject, OnInit, signal } from '@angular/core';
+import { ChangeDetectionStrategy, Component, DestroyRef, inject, OnDestroy, OnInit, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormControl, FormsModule } from '@angular/forms';
@@ -17,7 +17,7 @@ import { CustomPaginatorComponent, LoadingSpinnerComponent, SearchInputComponent
import { AddContributorType, AddDialogState } from '../../enums';
import { ContributorAddModel, ContributorDialogAddModel } from '../../models';
-import { ContributorsSelectors, SearchUsers } from '../../store';
+import { ClearUsers, ContributorsSelectors, SearchUsers } from '../../store';
import { AddContributorItemComponent } from '../add-contributor-item/add-contributor-item.component';
@Component({
@@ -36,7 +36,7 @@ import { AddContributorItemComponent } from '../add-contributor-item/add-contrib
styleUrl: './add-contributor-dialog.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class AddContributorDialogComponent implements OnInit {
+export class AddContributorDialogComponent implements OnInit, OnDestroy {
protected dialogRef = inject(DynamicDialogRef);
private readonly destroyRef = inject(DestroyRef);
readonly config = inject(DynamicDialogConfig);
@@ -53,7 +53,7 @@ export class AddContributorDialogComponent implements OnInit {
protected selectedUsers = signal
([]);
protected searchControl = new FormControl('');
- protected actions = createDispatchMap({ searchUsers: SearchUsers });
+ protected actions = createDispatchMap({ searchUsers: SearchUsers, clearUsers: ClearUsers });
get isSearchState() {
return this.currentState() === AddDialogState.Search;
@@ -64,6 +64,10 @@ export class AddContributorDialogComponent implements OnInit {
this.selectedUsers.set([]);
}
+ ngOnDestroy(): void {
+ this.actions.clearUsers();
+ }
+
addContributor(): void {
if (this.currentState() === AddDialogState.Details) {
const dialogData: ContributorDialogAddModel = { data: this.selectedUsers(), type: AddContributorType.Registered };
diff --git a/src/app/features/project/contributors/components/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.ts b/src/app/features/project/contributors/components/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.ts
index 3e315e92f..bc35f4864 100644
--- a/src/app/features/project/contributors/components/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.ts
+++ b/src/app/features/project/contributors/components/add-unregistered-contributor-dialog/add-unregistered-contributor-dialog.component.ts
@@ -48,7 +48,7 @@ export class AddUnregisteredContributorDialogComponent {
}
addRegistered() {
- const data: ContributorDialogAddModel = { data: [], type: AddContributorType.Unregistered };
+ const data: ContributorDialogAddModel = { data: [], type: AddContributorType.Registered };
this.dialogRef.close(data);
}
diff --git a/src/app/features/project/contributors/contributors.component.html b/src/app/features/project/contributors/contributors.component.html
index 17d550ea7..130383454 100644
--- a/src/app/features/project/contributors/contributors.component.html
+++ b/src/app/features/project/contributors/contributors.component.html
@@ -90,12 +90,14 @@ {{ 'navigation.project.contributors' | tra
{{ 'project.contributors.viewOnly' | translate }}
{{ 'project.contributors.createLink' | translate }}
-
-
+
+
+
+
diff --git a/src/app/features/project/contributors/contributors.component.ts b/src/app/features/project/contributors/contributors.component.ts
index 926b35860..ffa3c72a4 100644
--- a/src/app/features/project/contributors/contributors.component.ts
+++ b/src/app/features/project/contributors/contributors.component.ts
@@ -91,6 +91,7 @@ export class ContributorsComponent implements OnInit {
protected initialContributors = select(ContributorsSelectors.getContributors);
protected contributors = signal([]);
protected readonly isContributorsLoading = select(ContributorsSelectors.isContributorsLoading);
+ protected readonly isViewOnlyLinksLoading = select(SettingsSelectors.isViewOnlyLinksLoading);
protected actions = createDispatchMap({
getViewOnlyLinks: GetViewOnlyLinksTable,
diff --git a/src/app/features/project/contributors/store/contributors.actions.ts b/src/app/features/project/contributors/store/contributors.actions.ts
index ca10c32b1..eaca3b5b5 100644
--- a/src/app/features/project/contributors/store/contributors.actions.ts
+++ b/src/app/features/project/contributors/store/contributors.actions.ts
@@ -59,3 +59,7 @@ export class SearchUsers {
public page: number
) {}
}
+
+export class ClearUsers {
+ static readonly type = '[Contributors] Clear Users';
+}
diff --git a/src/app/features/project/contributors/store/contributors.state.ts b/src/app/features/project/contributors/store/contributors.state.ts
index 4b79e8f2a..7a69ff788 100644
--- a/src/app/features/project/contributors/store/contributors.state.ts
+++ b/src/app/features/project/contributors/store/contributors.state.ts
@@ -8,6 +8,7 @@ import { ContributorsService } from '../services';
import {
AddContributor,
+ ClearUsers,
DeleteContributor,
GetAllContributors,
SearchUsers,
@@ -183,6 +184,11 @@ export class ContributorsState {
);
}
+ @Action(ClearUsers)
+ clearUsers(ctx: StateContext
) {
+ ctx.patchState({ users: { data: [], isLoading: false, error: null, totalCount: 0 } });
+ }
+
private handleError(ctx: StateContext, section: 'contributorsList' | 'users', error: Error) {
ctx.patchState({
[section]: {
diff --git a/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html b/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html
index 697b2daf1..6cfef0955 100644
--- a/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html
+++ b/src/app/features/project/settings/components/settings-project-form-card/settings-project-form-card.component.html
@@ -1,7 +1,7 @@
{{ 'myProjects.settings.project' | translate }}
-