From 35b80720f634bedc6885df690fd8b36428d3fae8 Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 4 Jun 2025 12:08:25 +0300 Subject: [PATCH 1/6] fix(contributors): fixed add contributors dialog --- .../add-contributor-dialog.component.ts | 12 ++++++++---- .../add-unregistered-contributor-dialog.component.ts | 2 +- .../contributors/store/contributors.actions.ts | 4 ++++ .../project/contributors/store/contributors.state.ts | 6 ++++++ 4 files changed, 19 insertions(+), 5 deletions(-) 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/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]: { From e2bc88df047a6b1bebb070af42705946059e9026 Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 4 Jun 2025 16:49:35 +0300 Subject: [PATCH 2/6] fix(contributors): fixed contributors page --- .../contributors/contributors.component.html | 14 ++-- .../contributors/contributors.component.ts | 1 + .../settings-project-form-card.component.html | 3 +- .../settings-project-form-card.component.ts | 4 ++ ...ttings-view-only-links-card.component.html | 6 +- ...settings-view-only-links-card.component.ts | 3 +- .../project/settings/settings.component.html | 6 +- .../project/settings/settings.component.ts | 26 +++++-- .../settings/store/settings.selectors.ts | 5 ++ .../project/settings/store/settings.state.ts | 6 ++ .../copy-button/copy-button.component.html | 8 +++ .../copy-button/copy-button.component.scss | 13 ++++ .../copy-button/copy-button.component.spec.ts | 22 ++++++ .../copy-button/copy-button.component.ts | 29 ++++++++ src/app/shared/components/index.ts | 1 + .../components/toast/toast.component.html | 2 +- .../view-only-table.component.html | 69 +++++++++---------- .../view-only-table.component.scss | 7 +- .../view-only-table.component.ts | 25 ++++--- src/assets/i18n/en.json | 4 +- src/assets/styles/overrides/tooltip.scss | 1 - 21 files changed, 190 insertions(+), 65 deletions(-) create mode 100644 src/app/shared/components/copy-button/copy-button.component.html create mode 100644 src/app/shared/components/copy-button/copy-button.component.scss create mode 100644 src/app/shared/components/copy-button/copy-button.component.spec.ts create mode 100644 src/app/shared/components/copy-button/copy-button.component.ts 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/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 }}

-
+
@@ -66,6 +59,12 @@ - - -} + } @else { + + + + + + } + + diff --git a/src/app/shared/components/view-only-table/view-only-table.component.scss b/src/app/shared/components/view-only-table/view-only-table.component.scss index cd945c08e..da65d756c 100644 --- a/src/app/shared/components/view-only-table/view-only-table.component.scss +++ b/src/app/shared/components/view-only-table/view-only-table.component.scss @@ -1,9 +1,10 @@ @use "assets/styles/variables" as var; +@use "assets/styles/mixins" as mix; .icon-copy-btn { - right: 1.5rem; top: 50%; + right: mix.rem(16px); transform: translateY(-50%); - width: 1.5rem; - cursor: pointer; + width: mix.rem(24px); + z-index: 1; } diff --git a/src/app/shared/components/view-only-table/view-only-table.component.ts b/src/app/shared/components/view-only-table/view-only-table.component.ts index f62b0ab5b..61baa189a 100644 --- a/src/app/shared/components/view-only-table/view-only-table.component.ts +++ b/src/app/shared/components/view-only-table/view-only-table.component.ts @@ -2,29 +2,38 @@ import { TranslatePipe } from '@ngx-translate/core'; import { Button } from 'primeng/button'; import { InputText } from 'primeng/inputtext'; +import { Skeleton } from 'primeng/skeleton'; import { TableModule } from 'primeng/table'; -import { Clipboard } from '@angular/cdk/clipboard'; import { DatePipe } from '@angular/common'; -import { ChangeDetectionStrategy, Component, inject, input, output } from '@angular/core'; +import { ChangeDetectionStrategy, Component, input, output } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { PaginatedViewOnlyLinksModel, ViewOnlyLinkModel } from '@osf/features/project/settings/models'; +import { CopyButtonComponent } from '../copy-button/copy-button.component'; + @Component({ selector: 'osf-view-only-table', - imports: [TableModule, TranslatePipe, DatePipe, InputText, ReactiveFormsModule, Button], + imports: [ + TableModule, + TranslatePipe, + DatePipe, + InputText, + ReactiveFormsModule, + Button, + CopyButtonComponent, + Skeleton, + ], templateUrl: './view-only-table.component.html', styleUrl: './view-only-table.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) export class ViewOnlyTableComponent { - deleteLink = output(); tableData = input.required(); + isLoading = input(true); - readonly #clipboard = inject(Clipboard); + deleteLink = output(); - copy(link: string): void { - this.#clipboard.copy(link); - } + skeletonData: ViewOnlyLinkModel[] = Array.from({ length: 3 }, () => ({}) as ViewOnlyLinkModel); } diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index faf3cca31..1ff8aec96 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -302,7 +302,9 @@ "daily": "You'll receive a daily summary of file updates.", "none": "You won't receive file update notifications." } - } + }, + "updateProjectDetailsMessage": "Successfully updated project details.", + "updateProjectSettingsMessage": "Successfully updated project settings." } }, "myProfile": { diff --git a/src/assets/styles/overrides/tooltip.scss b/src/assets/styles/overrides/tooltip.scss index 18e532846..e01a506d2 100644 --- a/src/assets/styles/overrides/tooltip.scss +++ b/src/assets/styles/overrides/tooltip.scss @@ -4,7 +4,6 @@ display: flex !important; background: var.$white; color: var.$dark-blue-1; - min-width: 22rem; border: 1px solid var.$grey-3; padding: 1rem; } From 8f8d4b79ca8142907c81437acf084e10b549191f Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 4 Jun 2025 16:59:08 +0300 Subject: [PATCH 3/6] fix(contributors): added sidenav --- src/app/core/components/index.ts | 1 + .../nav-menu/nav-menu.component.html | 110 +++++++++--------- .../components/nav-menu/nav-menu.component.ts | 3 +- .../core/components/root/root.component.html | 2 +- .../components/root/root.component.spec.ts | 13 ++- .../core/components/root/root.component.ts | 4 +- .../components/sidenav/sidenav.component.html | 4 + .../components/sidenav/sidenav.component.scss | 0 .../sidenav/sidenav.component.spec.ts | 26 +++++ .../components/sidenav/sidenav.component.ts | 13 +++ 10 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 src/app/core/components/sidenav/sidenav.component.html create mode 100644 src/app/core/components/sidenav/sidenav.component.scss create mode 100644 src/app/core/components/sidenav/sidenav.component.spec.ts create mode 100644 src/app/core/components/sidenav/sidenav.component.ts diff --git a/src/app/core/components/index.ts b/src/app/core/components/index.ts index d20f23ab0..39b7327d8 100644 --- a/src/app/core/components/index.ts +++ b/src/app/core/components/index.ts @@ -2,4 +2,5 @@ export { BreadcrumbComponent } from './breadcrumb/breadcrumb.component'; export { FooterComponent } from './footer/footer.component'; export { HeaderComponent } from './header/header.component'; export { RootComponent } from './root/root.component'; +export { SidenavComponent } from './sidenav/sidenav.component'; export { TopnavComponent } from './topnav/topnav.component'; diff --git a/src/app/core/components/nav-menu/nav-menu.component.html b/src/app/core/components/nav-menu/nav-menu.component.html index 617b482ba..5958a21cb 100644 --- a/src/app/core/components/nav-menu/nav-menu.component.html +++ b/src/app/core/components/nav-menu/nav-menu.component.html @@ -1,58 +1,54 @@ - + {{ item.label | translate }} + @if (item.items) { + + } + + + @if (item.label === 'navigation.myProjects' && isProjectRoute()) { + + } + + + diff --git a/src/app/core/components/nav-menu/nav-menu.component.ts b/src/app/core/components/nav-menu/nav-menu.component.ts index fe71b525c..fc1502642 100644 --- a/src/app/core/components/nav-menu/nav-menu.component.ts +++ b/src/app/core/components/nav-menu/nav-menu.component.ts @@ -5,7 +5,6 @@ import { PanelMenuModule } from 'primeng/panelmenu'; import { filter, map } from 'rxjs'; -import { NgOptimizedImage } from '@angular/common'; import { Component, computed, inject, output } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { ActivatedRoute, NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/router'; @@ -16,7 +15,7 @@ import { NavItem } from '@osf/shared/models'; @Component({ selector: 'osf-nav-menu', - imports: [NgOptimizedImage, RouterLinkActive, RouterLink, PanelMenuModule, TranslatePipe, IconComponent], + imports: [RouterLinkActive, RouterLink, PanelMenuModule, TranslatePipe, IconComponent], templateUrl: './nav-menu.component.html', styleUrl: './nav-menu.component.scss', }) diff --git a/src/app/core/components/root/root.component.html b/src/app/core/components/root/root.component.html index fdf2f30f1..9f9ace757 100644 --- a/src/app/core/components/root/root.component.html +++ b/src/app/core/components/root/root.component.html @@ -1,6 +1,6 @@ @if (isWeb()) {
- +
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 {} From fbb6e6ef40534e63d4e7048e54599a3cf99876a6 Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 5 Jun 2025 10:47:04 +0300 Subject: [PATCH 4/6] fix(contributors): added full screen loader --- src/app/app.component.html | 1 + src/app/app.component.ts | 12 +++++----- .../full-screen-loader.component.html | 12 ++++++++++ .../full-screen-loader.component.scss | 9 ++++++++ .../full-screen-loader.component.spec.ts | 22 +++++++++++++++++++ .../full-screen-loader.component.ts | 16 ++++++++++++++ src/app/shared/components/index.ts | 1 + src/app/shared/services/index.ts | 1 + src/app/shared/services/loader.service.ts | 17 ++++++++++++++ 9 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 src/app/shared/components/full-screen-loader/full-screen-loader.component.html create mode 100644 src/app/shared/components/full-screen-loader/full-screen-loader.component.scss create mode 100644 src/app/shared/components/full-screen-loader/full-screen-loader.component.spec.ts create mode 100644 src/app/shared/components/full-screen-loader/full-screen-loader.component.ts create mode 100644 src/app/shared/services/loader.service.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 94a21db1e..4997c5280 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,2 +1,3 @@ + diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0bd55f7d1..a87b340a3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,23 +1,23 @@ -import { Store } from '@ngxs/store'; +import { createDispatchMap } from '@ngxs/store'; -import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import { GetCurrentUser } from '@core/store/user'; -import { ToastComponent } from './shared/components'; +import { FullScreenLoaderComponent, ToastComponent } from './shared/components'; @Component({ selector: 'osf-root', - imports: [RouterOutlet, ToastComponent], + imports: [RouterOutlet, ToastComponent, FullScreenLoaderComponent], templateUrl: './app.component.html', styleUrl: './app.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent implements OnInit { - #store = inject(Store); + actions = createDispatchMap({ getCurrentUser: GetCurrentUser }); ngOnInit(): void { - this.#store.dispatch(GetCurrentUser); + this.actions.getCurrentUser(); } } diff --git a/src/app/shared/components/full-screen-loader/full-screen-loader.component.html b/src/app/shared/components/full-screen-loader/full-screen-loader.component.html new file mode 100644 index 000000000..04ca34a68 --- /dev/null +++ b/src/app/shared/components/full-screen-loader/full-screen-loader.component.html @@ -0,0 +1,12 @@ +@if (loaderService.isLoading()) { +
+
+ +
+
+} diff --git a/src/app/shared/components/full-screen-loader/full-screen-loader.component.scss b/src/app/shared/components/full-screen-loader/full-screen-loader.component.scss new file mode 100644 index 000000000..6bb6d941f --- /dev/null +++ b/src/app/shared/components/full-screen-loader/full-screen-loader.component.scss @@ -0,0 +1,9 @@ +.container { + position: absolute; + top: 0; + left: 0; + background-color: var(--white-60); + width: 100%; + height: 100%; + z-index: 2000; +} diff --git a/src/app/shared/components/full-screen-loader/full-screen-loader.component.spec.ts b/src/app/shared/components/full-screen-loader/full-screen-loader.component.spec.ts new file mode 100644 index 000000000..49502c614 --- /dev/null +++ b/src/app/shared/components/full-screen-loader/full-screen-loader.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FullScreenLoaderComponent } from './full-screen-loader.component'; + +describe('FullScreenLoaderComponent', () => { + let component: FullScreenLoaderComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FullScreenLoaderComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(FullScreenLoaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/full-screen-loader/full-screen-loader.component.ts b/src/app/shared/components/full-screen-loader/full-screen-loader.component.ts new file mode 100644 index 000000000..eb7c7a579 --- /dev/null +++ b/src/app/shared/components/full-screen-loader/full-screen-loader.component.ts @@ -0,0 +1,16 @@ +import { ProgressSpinner } from 'primeng/progressspinner'; + +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; + +import { LoaderService } from '@osf/shared/services'; + +@Component({ + selector: 'osf-full-screen-loader', + imports: [ProgressSpinner], + templateUrl: './full-screen-loader.component.html', + styleUrl: './full-screen-loader.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class FullScreenLoaderComponent { + loaderService = inject(LoaderService); +} diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts index 3667e644b..9b3862021 100644 --- a/src/app/shared/components/index.ts +++ b/src/app/shared/components/index.ts @@ -4,6 +4,7 @@ export { CopyButtonComponent } from './copy-button/copy-button.component'; export { CustomPaginatorComponent } from './custom-paginator/custom-paginator.component'; export { EducationHistoryComponent } from './education-history/education-history.component'; export { EmploymentHistoryComponent } from './employment-history/employment-history.component'; +export { FullScreenLoaderComponent } from './full-screen-loader/full-screen-loader.component'; export { IconComponent } from './icon/icon.component'; export { LineChartComponent } from './line-chart/line-chart.component'; export { LoadingSpinnerComponent } from './loading-spinner/loading-spinner.component'; diff --git a/src/app/shared/services/index.ts b/src/app/shared/services/index.ts index ecd67f72f..e3aa084cc 100644 --- a/src/app/shared/services/index.ts +++ b/src/app/shared/services/index.ts @@ -1,3 +1,4 @@ export { FiltersOptionsService } from './filters-options.service'; +export { LoaderService } from './loader.service'; export { SearchService } from './search.service'; export { ToastService } from './toast.service'; diff --git a/src/app/shared/services/loader.service.ts b/src/app/shared/services/loader.service.ts new file mode 100644 index 000000000..e86eccf49 --- /dev/null +++ b/src/app/shared/services/loader.service.ts @@ -0,0 +1,17 @@ +import { Injectable, signal } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class LoaderService { + private _isLoading = signal(false); + readonly isLoading = this._isLoading.asReadonly(); + + show() { + this._isLoading.set(true); + } + + hide() { + this._isLoading.set(false); + } +} From fe341bda62cfe0180847be9bbc180d1ddeb2a6fa Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 5 Jun 2025 10:49:37 +0300 Subject: [PATCH 5/6] fix(contributors): updated social icons --- .../components/footer/footer.component.html | 8 +++-- .../components/footer/footer.component.scss | 14 +++++++++ .../components/footer/footer.component.ts | 29 +++---------------- src/app/core/constants/index.ts | 1 + .../core/constants/social-icons.constant.ts | 28 ++++++++++++++++++ src/app/shared/models/social-icon.model.ts | 1 + 6 files changed, 54 insertions(+), 27 deletions(-) create mode 100644 src/app/core/constants/social-icons.constant.ts diff --git a/src/app/core/components/footer/footer.component.html b/src/app/core/components/footer/footer.component.html index 521118f98..b11f9dd2b 100644 --- a/src/app/core/components/footer/footer.component.html +++ b/src/app/core/components/footer/footer.component.html @@ -8,8 +8,12 @@ diff --git a/src/app/core/components/footer/footer.component.scss b/src/app/core/components/footer/footer.component.scss index 35c12aa6b..c6b90a91a 100644 --- a/src/app/core/components/footer/footer.component.scss +++ b/src/app/core/components/footer/footer.component.scss @@ -18,6 +18,20 @@ color: var.$dark-blue-1; text-align: center; } + + .social-link { + background-color: var.$pr-blue-1; + border-radius: mix.rem(6px); + color: var.$white; + padding: mix.rem(6px); + width: mix.rem(36px); + height: mix.rem(36px); + + &:hover { + background-color: var.$pr-blue-3; + text-decoration: none; + } + } } .footer-links { diff --git a/src/app/core/components/footer/footer.component.ts b/src/app/core/components/footer/footer.component.ts index 86029ce69..1c0b59ab7 100644 --- a/src/app/core/components/footer/footer.component.ts +++ b/src/app/core/components/footer/footer.component.ts @@ -1,16 +1,16 @@ import { TranslateModule } from '@ngx-translate/core'; -import { NgOptimizedImage } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { RouterLink } from '@angular/router'; -import { SocialIcon } from '@osf/shared/models'; +import { SOCIAL_ICONS } from '@osf/core/constants'; +import { IconComponent } from '@osf/shared/components'; import { IS_WEB } from '@shared/utils'; @Component({ selector: 'osf-footer', - imports: [RouterLink, NgOptimizedImage, TranslateModule], + imports: [RouterLink, TranslateModule, IconComponent], templateUrl: './footer.component.html', styleUrl: './footer.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, @@ -18,26 +18,5 @@ import { IS_WEB } from '@shared/utils'; export class FooterComponent { isWeb = toSignal(inject(IS_WEB)); - protected readonly socialIcons: SocialIcon[] = [ - { - name: 'x', - url: 'https://x.com/OSFramework', - ariaLabel: 'X (formerly Twitter)', - }, - { - name: 'facebook', - url: 'https://www.facebook.com/CenterForOpenScience/', - ariaLabel: 'Facebook', - }, - { - name: 'group', - url: 'https://groups.google.com/g/openscienceframework', - ariaLabel: 'Group', - }, - { - name: 'github', - url: 'https://github.com/centerforopenscience', - ariaLabel: 'GitHub', - }, - ]; + protected readonly socialIcons = SOCIAL_ICONS; } diff --git a/src/app/core/constants/index.ts b/src/app/core/constants/index.ts index bfcd12b9b..8547ff127 100644 --- a/src/app/core/constants/index.ts +++ b/src/app/core/constants/index.ts @@ -2,4 +2,5 @@ export * from './error-messages'; export * from './my-projects-table.constants'; export * from './nav-items.constant'; export * from './ngxs-states.constant'; +export * from './social-icons.constant'; export * from './storage-locations.constant'; diff --git a/src/app/core/constants/social-icons.constant.ts b/src/app/core/constants/social-icons.constant.ts new file mode 100644 index 000000000..a9ffe0b0f --- /dev/null +++ b/src/app/core/constants/social-icons.constant.ts @@ -0,0 +1,28 @@ +import { SocialIcon } from '@osf/shared/models'; + +export const SOCIAL_ICONS: SocialIcon[] = [ + { + name: 'github', + iconName: 'fab fa-github', + url: 'https://github.com/centerforopenscience', + ariaLabel: 'GitHub', + }, + { + name: 'linkedIn', + iconName: 'fab fa-linkedin-in', + url: 'https://www.linkedin.com/company/center-for-open-science/', + ariaLabel: 'Linkedin', + }, + { + name: 'bluesky', + iconName: 'fab fa-bluesky', + url: 'https://bsky.app/profile/cos.io', + ariaLabel: 'Bluesky', + }, + { + name: 'mastodon', + iconName: 'fab fa-mastodon', + url: 'https://fosstodon.org/@CenterforOpenScience', + ariaLabel: 'Mastodon', + }, +]; diff --git a/src/app/shared/models/social-icon.model.ts b/src/app/shared/models/social-icon.model.ts index 95355cec0..802f82940 100644 --- a/src/app/shared/models/social-icon.model.ts +++ b/src/app/shared/models/social-icon.model.ts @@ -1,5 +1,6 @@ export interface SocialIcon { name: string; url: string; + iconName: string; ariaLabel: string; } From 92fc2482f1451c3755951b3ffb0d8eef66894b3d Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 5 Jun 2025 11:02:45 +0300 Subject: [PATCH 6/6] fix(styles): fixed hover state --- .../components/header/header.component.html | 1 + .../components/topnav/topnav.component.html | 2 +- src/app/features/home/home.component.html | 10 ++-- src/app/features/home/home.component.scss | 56 ++++++++----------- .../resources/resources.component.html | 5 +- src/app/features/search/search.component.html | 2 +- src/app/features/search/search.component.scss | 4 ++ .../my-projects-table.component.html | 6 ++ src/assets/i18n/en.json | 5 +- src/assets/styles/_common.scss | 11 ++++ src/assets/styles/overrides/input.scss | 4 ++ 11 files changed, 63 insertions(+), 43 deletions(-) diff --git a/src/app/core/components/header/header.component.html b/src/app/core/components/header/header.component.html index c0c26ab32..040f23473 100644 --- a/src/app/core/components/header/header.component.html +++ b/src/app/core/components/header/header.component.html @@ -3,6 +3,7 @@