From 6b15cbc495c5dc753e5ddaa4da6638eb8627ef87 Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 10 Sep 2025 19:24:28 +0300 Subject: [PATCH 01/10] fix(accessibility): update accessibility for some pages --- .../components/header/header.component.html | 6 ++++- .../core/components/root/root.component.html | 2 +- .../core/components/root/root.component.ts | 3 +++ .../pages/dashboard/dashboard.component.html | 4 ++-- .../search-input/search-input.component.html | 8 ++++++- .../search-input/search-input.component.ts | 4 +++- .../search-results-container.component.html | 12 +++++++++- src/assets/i18n/en.json | 22 +++++++++++++++---- src/styles/overrides/tag.scss | 2 +- 9 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/app/core/components/header/header.component.html b/src/app/core/components/header/header.component.html index c76adec66..ccb4cb26a 100644 --- a/src/app/core/components/header/header.component.html +++ b/src/app/core/components/header/header.component.html @@ -18,7 +18,11 @@ } @else { - + } diff --git a/src/app/core/components/root/root.component.html b/src/app/core/components/root/root.component.html index 735043347..143bead91 100644 --- a/src/app/core/components/root/root.component.html +++ b/src/app/core/components/root/root.component.html @@ -26,4 +26,4 @@ } - + diff --git a/src/app/core/components/root/root.component.ts b/src/app/core/components/root/root.component.ts index 12083b732..c230d6860 100644 --- a/src/app/core/components/root/root.component.ts +++ b/src/app/core/components/root/root.component.ts @@ -1,3 +1,5 @@ +import { TranslatePipe } from '@ngx-translate/core'; + import { ConfirmDialog } from 'primeng/confirmdialog'; import { CommonModule } from '@angular/common'; @@ -23,6 +25,7 @@ import { IS_MEDIUM, IS_WEB } from '@osf/shared/helpers'; BreadcrumbComponent, RouterOutlet, SidenavComponent, + TranslatePipe, ], templateUrl: './root.component.html', styleUrls: ['./root.component.scss'], diff --git a/src/app/features/home/pages/dashboard/dashboard.component.html b/src/app/features/home/pages/dashboard/dashboard.component.html index cd1024b79..2be0c1284 100644 --- a/src/app/features/home/pages/dashboard/dashboard.component.html +++ b/src/app/features/home/pages/dashboard/dashboard.component.html @@ -10,11 +10,11 @@

{{ 'home.loggedIn.dashboard.quickSearch.goTo' | translate }} - + {{ 'home.loggedIn.dashboard.quickSearch.myProjects' | translate }} {{ 'home.loggedIn.dashboard.quickSearch.toOrganize' | translate }} - + {{ 'home.loggedIn.dashboard.quickSearch.search' | translate }} {{ 'home.loggedIn.dashboard.quickSearch.osf' | translate }} diff --git a/src/app/shared/components/search-input/search-input.component.html b/src/app/shared/components/search-input/search-input.component.html index 4594076aa..39d0d1957 100644 --- a/src/app/shared/components/search-input/search-input.component.html +++ b/src/app/shared/components/search-input/search-input.component.html @@ -11,6 +11,12 @@ /> @if (showHelpIcon()) { - + }

diff --git a/src/app/shared/components/search-input/search-input.component.ts b/src/app/shared/components/search-input/search-input.component.ts index a04614836..809ecb62b 100644 --- a/src/app/shared/components/search-input/search-input.component.ts +++ b/src/app/shared/components/search-input/search-input.component.ts @@ -1,3 +1,5 @@ +import { TranslatePipe } from '@ngx-translate/core'; + import { Button } from 'primeng/button'; import { InputText } from 'primeng/inputtext'; @@ -8,7 +10,7 @@ import { IconComponent } from '../icon/icon.component'; @Component({ selector: 'osf-search-input', - imports: [InputText, Button, ReactiveFormsModule, IconComponent], + imports: [InputText, Button, ReactiveFormsModule, IconComponent, TranslatePipe], templateUrl: './search-input.component.html', styleUrl: './search-input.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/shared/components/search-results-container/search-results-container.component.html b/src/app/shared/components/search-results-container/search-results-container.component.html index 343612663..b97395488 100644 --- a/src/app/shared/components/search-results-container/search-results-container.component.html +++ b/src/app/shared/components/search-results-container/search-results-container.component.html @@ -51,6 +51,7 @@

severity="secondary" icon="fas fa-sliders" size="large" + [ariaLabel]="'common.accessibility.openFilters' | translate" (click)="openFilters()" > } @@ -59,6 +60,7 @@

severity="secondary" icon="fas fa-filter" size="large" + [ariaLabel]="'common.accessibility.openSortingOptions' | translate" (click)="openSorting()" > @@ -107,13 +109,20 @@

@if (first() && prev()) { - + } @@ -123,6 +132,7 @@

icon="fas fa-angle-right" severity="contrast" text + [ariaLabel]="'common.accessibility.goToNextPage' | translate" [disabled]="!next()" (click)="switchPage(!next() ? first() : next())" > diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index fba1bd785..5f1de6869 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -49,6 +49,20 @@ "createNewVersion": "Create New Version", "leaveThisView": "Leave this view" }, + "accessibility": { + "help": "Help", + "openFilters": "Open filters", + "openSortingOptions": "Open sorting options", + "goToFirstPage": "Go to first page", + "goToPreviousPage": "Go to previous page", + "goToNextPage": "Go to next page", + "mainNavigation": "Main navigation", + "searchHelp": "Search help", + "confirmationDialog": "Confirmation dialog" + }, + "dialogs": { + "confirmation": "Confirmation" + }, "search": { "title": "Search", "noResultsFound": "No results found.", @@ -963,10 +977,10 @@ "link": "Link", "noLink": "No link available" }, - "noLinkedServices": "This project has no configured linked services at the moment.", - "redirectMessage": "Visit", - "addonsLink": "Add-ons", - "redirectMessageSuffix": "to add a linked service." + "noLinkedServices": "This project has no configured linked services at the moment.", + "redirectMessage": "Visit", + "addonsLink": "Add-ons", + "redirectMessageSuffix": "to add a linked service." } }, "files": { diff --git a/src/styles/overrides/tag.scss b/src/styles/overrides/tag.scss index c0fb70971..9a6e145aa 100644 --- a/src/styles/overrides/tag.scss +++ b/src/styles/overrides/tag.scss @@ -5,7 +5,7 @@ --p-tag-warn-background: var(--yellow-2); --p-tag-warn-color: var(--yellow-1); - --p-tag-secondary-background: var(--grey-1); + --p-tag-secondary-background: var(--dark-blue-1); --p-tag-secondary-color: var(--white); --p-tag-info-background: var(--bg-blue-3); From 78ac64c4117ab053c1a7c3611825bb83fb25d690 Mon Sep 17 00:00:00 2001 From: Nazar Semets Date: Wed, 10 Sep 2025 22:54:41 +0300 Subject: [PATCH 02/10] fix(accessibility): added aria labels --- .../view-duplicates/view-duplicates.component.html | 1 + .../institutions-list.component.html | 8 +------- .../moderators-table/moderators-table.component.html | 3 ++- .../array-input/array-input.component.html | 11 +++++++++-- .../array-input/array-input.component.ts | 4 +++- .../stepper/file-step/file-step.component.html | 9 ++++++++- .../supplements-step/supplements-step.component.html | 9 ++++++++- .../linked-resources/linked-resources.component.html | 1 + .../overview-components.component.html | 1 + .../overview-toolbar/overview-toolbar.component.html | 11 ++++++++++- .../settings-project-affiliation.component.html | 1 + .../contributors-list.component.html | 6 +++--- .../components/subjects/subjects.component.html | 1 + .../components/tags-input/tags-input.component.html | 1 + .../view-only-table/view-only-table.component.html | 6 +++--- src/assets/i18n/en.json | 5 +++-- 16 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/app/features/analytics/components/view-duplicates/view-duplicates.component.html b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.html index 16c48218b..46fed730d 100644 --- a/src/app/features/analytics/components/view-duplicates/view-duplicates.component.html +++ b/src/app/features/analytics/components/view-duplicates/view-duplicates.component.html @@ -28,6 +28,7 @@

icon="fas fa-ellipsis-vertical" raised variant="outlined" + [ariaLabel]="'common.buttons.more' | translate" (onClick)="componentActionMenu.toggle($event)" > diff --git a/src/app/features/institutions/pages/institutions-list/institutions-list.component.html b/src/app/features/institutions/pages/institutions-list/institutions-list.component.html index 8e6ce79b2..6e2b8f855 100644 --- a/src/app/features/institutions/pages/institutions-list/institutions-list.component.html +++ b/src/app/features/institutions/pages/institutions-list/institutions-list.component.html @@ -18,13 +18,7 @@ @for (institution of institutions(); track $index) {
- +

{{ institution.name }}

diff --git a/src/app/features/moderation/components/moderators-table/moderators-table.component.html b/src/app/features/moderation/components/moderators-table/moderators-table.component.html index 6930ab39c..715289e7f 100644 --- a/src/app/features/moderation/components/moderators-table/moderators-table.component.html +++ b/src/app/features/moderation/components/moderators-table/moderators-table.component.html @@ -96,7 +96,8 @@ icon="fas fa-trash" severity="danger" text - (click)="removeModerator(item)" + (onClick)="removeModerator(item)" + [ariaLabel]="'common.buttons.delete' | translate" [disabled]="!isCurrentUserAdminModerator() && currentUserId() !== item.id" /> } diff --git a/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.html b/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.html index 0b7a98b9b..e29db002e 100644 --- a/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.html +++ b/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.html @@ -5,13 +5,20 @@
@if (formArrayControls.length > 1) { - + }
}

- +
diff --git a/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.ts b/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.ts index a65ad89f2..327841ee1 100644 --- a/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.ts +++ b/src/app/features/preprints/components/stepper/author-assertion-step/array-input/array-input.component.ts @@ -1,3 +1,5 @@ +import { TranslatePipe } from '@ngx-translate/core'; + import { Button } from 'primeng/button'; import { ChangeDetectionStrategy, Component, input } from '@angular/core'; @@ -7,7 +9,7 @@ import { TextInputComponent } from '@shared/components'; @Component({ selector: 'osf-array-input', - imports: [ReactiveFormsModule, Button, TextInputComponent], + imports: [ReactiveFormsModule, Button, TextInputComponent, TranslatePipe], templateUrl: './array-input.component.html', styleUrl: './array-input.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/src/app/features/preprints/components/stepper/file-step/file-step.component.html b/src/app/features/preprints/components/stepper/file-step/file-step.component.html index 10a2d87ab..2b6b6a399 100644 --- a/src/app/features/preprints/components/stepper/file-step/file-step.component.html +++ b/src/app/features/preprints/components/stepper/file-step/file-step.component.html @@ -111,7 +111,14 @@

{{ 'preprints.preprintStepper.file.title' | translate }}

{{ file.name }}

- + } } diff --git a/src/app/features/preprints/components/stepper/supplements-step/supplements-step.component.html b/src/app/features/preprints/components/stepper/supplements-step/supplements-step.component.html index 31cc9a65a..13b28e730 100644 --- a/src/app/features/preprints/components/stepper/supplements-step/supplements-step.component.html +++ b/src/app/features/preprints/components/stepper/supplements-step/supplements-step.component.html @@ -69,7 +69,14 @@

{{ 'preprints.preprintStepper.supplements.title' | translate }}

{{ preprintProject()?.name }}

- +
} diff --git a/src/app/features/project/overview/components/linked-resources/linked-resources.component.html b/src/app/features/project/overview/components/linked-resources/linked-resources.component.html index 68da00521..44fff2ec1 100644 --- a/src/app/features/project/overview/components/linked-resources/linked-resources.component.html +++ b/src/app/features/project/overview/components/linked-resources/linked-resources.component.html @@ -28,6 +28,7 @@

icon="fas fa-trash" severity="danger" text + [ariaLabel]="'common.buttons.delete' | translate" (onClick)="openDeleteResourceModal(linkedResource.id)" > diff --git a/src/app/features/project/overview/components/overview-components/overview-components.component.html b/src/app/features/project/overview/components/overview-components/overview-components.component.html index 7c208c1dd..a1e265639 100644 --- a/src/app/features/project/overview/components/overview-components/overview-components.component.html +++ b/src/app/features/project/overview/components/overview-components/overview-components.component.html @@ -31,6 +31,7 @@

icon="fas fa-ellipsis-vertical" raised variant="outlined" + [ariaLabel]="'common.buttons.more' | translate" (onClick)="componentActionMenu.toggle($event)" > diff --git a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html index 4267d9a10..41d706d50 100644 --- a/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html +++ b/src/app/features/project/overview/components/overview-toolbar/overview-toolbar.component.html @@ -9,7 +9,12 @@

{{ 'project.overview.header.privateProject' | translate }}

- +
@@ -47,6 +52,7 @@ [pTooltip]="'project.overview.tooltips.viewOnlyLinks' | translate" tooltipPosition="bottom" [routerLink]="'../contributors'" + [ariaLabel]="'project.overview.tooltips.viewOnlyLinks' | translate" > {{ resource.viewOnlyLinksCount }} @@ -59,6 +65,7 @@ (click)="forkActionMenu.toggle($event)" [pTooltip]="'project.overview.tooltips.duplicate' | translate" tooltipPosition="bottom" + [ariaLabel]="'project.overview.tooltips.duplicate' | translate" > {{ resource.forksCount }} @@ -79,6 +86,7 @@ class="flex" (onClick)="toggleBookmark()" [loading]="isBookmarksLoading() || isBookmarksSubmitting()" + [ariaLabel]="'project.overview.tooltips.bookmarks' | translate" > @if (!isBookmarksLoading() && !isBookmarksSubmitting()) { @@ -92,6 +100,7 @@ (onClick)="socialsActionMenu.toggle($event)" [pTooltip]="'project.overview.tooltips.share' | translate" tooltipPosition="bottom" + [ariaLabel]="'project.overview.tooltips.share' | translate" > {{ socialsActionItems().length }} diff --git a/src/app/features/project/settings/components/settings-project-affiliation/settings-project-affiliation.component.html b/src/app/features/project/settings/components/settings-project-affiliation/settings-project-affiliation.component.html index af179c1e5..f4107a9c1 100644 --- a/src/app/features/project/settings/components/settings-project-affiliation/settings-project-affiliation.component.html +++ b/src/app/features/project/settings/components/settings-project-affiliation/settings-project-affiliation.component.html @@ -31,6 +31,7 @@

{{ 'myProjects.settings.projectAffiliation' | translate icon="fas fa-trash" severity="danger" text + [ariaLabel]="'common.buttons.delete' | translate" (onClick)="removeAffiliation(affiliation)" >

diff --git a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html index e87261521..4d53364a0 100644 --- a/src/app/shared/components/contributors/contributors-list/contributors-list.component.html +++ b/src/app/shared/components/contributors/contributors-list/contributors-list.component.html @@ -163,9 +163,9 @@

{{ 'project.contributors.curatorInfo.heading' | translate }}

icon="fas fa-trash" severity="danger" text - (click)="removeContributor(contributor)" - > - + [ariaLabel]="'common.buttons.delete' | translate" + (onClick)="removeContributor(contributor)" + /> } @else { diff --git a/src/app/shared/components/subjects/subjects.component.html b/src/app/shared/components/subjects/subjects.component.html index 39fc1c960..875f46413 100644 --- a/src/app/shared/components/subjects/subjects.component.html +++ b/src/app/shared/components/subjects/subjects.component.html @@ -64,6 +64,7 @@

{{ 'shared.subjects.title' | translate }}

(onNodeCollapse)="collapseNode($event.node)" (onNodeSelect)="selectSubject($event.node.data)" (onNodeUnselect)="removeSubject($event.node.data)" + ariaLabel="{{ 'shared.subjects.subjectTree' | translate }}" > } diff --git a/src/app/shared/components/tags-input/tags-input.component.html b/src/app/shared/components/tags-input/tags-input.component.html index 02f8c1488..c26071ca4 100644 --- a/src/app/shared/components/tags-input/tags-input.component.html +++ b/src/app/shared/components/tags-input/tags-input.component.html @@ -21,6 +21,7 @@ [readOnly]="readonly()" (keydown)="onInputKeydown($event)" (blur)="onInputBlur($event)" + [attr.aria-label]="'common.placeholder.addTag' | translate" class="tag-input-field" /> diff --git a/src/app/shared/components/view-only-table/view-only-table.component.html b/src/app/shared/components/view-only-table/view-only-table.component.html index fef65dfba..90d274386 100644 --- a/src/app/shared/components/view-only-table/view-only-table.component.html +++ b/src/app/shared/components/view-only-table/view-only-table.component.html @@ -64,9 +64,9 @@ icon="fas fa-trash" severity="danger" text - (click)="deleteLink.emit(item)" - > - + [ariaLabel]="'common.buttons.delete' | translate" + (onClick)="deleteLink.emit(item)" + /> } @else { diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 5f1de6869..c50bda463 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -47,7 +47,8 @@ "continueUpdate": "Continue Update", "editAndResubmit": "Edit And Resubmit", "createNewVersion": "Create New Version", - "leaveThisView": "Leave this view" + "leaveThisView": "Leave this view", + "addOneMore": "Add One More" }, "accessibility": { "help": "Help", @@ -2896,4 +2897,4 @@ "software": "Software", "other": "Other" } -} +} \ No newline at end of file From aeca3208b33ff7e0472cd18e5c88f34062253dee Mon Sep 17 00:00:00 2001 From: Nazar Semets Date: Thu, 11 Sep 2025 00:03:52 +0300 Subject: [PATCH 03/10] fix(updates): clean up code --- .../institutions-users.component.ts | 4 ++-- .../home/pages/dashboard/dashboard.component.ts | 6 +++--- .../institutions-list.component.ts | 4 ++-- .../meetings-landing.component.spec.ts | 6 +++--- .../meetings-landing.component.ts | 6 +++--- .../moderators-table.component.ts | 4 ++-- .../create-project-dialog.component.spec.ts | 4 ++-- .../create-project-dialog.component.ts | 4 ++-- .../my-projects/my-projects.component.ts | 10 +++++----- .../my-preprints/my-preprints.component.ts | 6 +++--- .../add-project-form.component.spec.ts | 4 ++-- .../add-contributor-dialog.component.scss | 5 ++--- .../add-contributor-item.component.html | 2 +- .../add-contributor-item.component.scss | 10 +--------- .../contributors-list.component.ts | 4 ++-- .../files-tree/files-tree.component.scss | 17 ++++++++--------- .../password-input-hint.component.scss | 6 ++---- .../registration-card.component.html | 2 +- .../registration-card.component.scss | 13 ------------- .../resource-card/resource-card.component.scss | 14 ++++++-------- .../search-help-tutorial.component.scss | 5 ++--- .../search-results-container.component.scss | 8 +++----- .../components/stepper/stepper.component.scss | 1 + ...nts.ts => default-table-params.constants.ts} | 2 +- src/app/shared/constants/index.ts | 4 +--- .../constants/my-projects-table.constants.ts | 12 ------------ src/app/shared/models/index.ts | 1 - 27 files changed, 60 insertions(+), 104 deletions(-) rename src/app/shared/constants/{meetings-table.constants.ts => default-table-params.constants.ts} (80%) delete mode 100644 src/app/shared/constants/my-projects-table.constants.ts diff --git a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts index 28f251217..5c0bf0d1a 100644 --- a/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts +++ b/src/app/features/admin-institutions/pages/institutions-users/institutions-users.component.ts @@ -14,7 +14,7 @@ import { FormsModule } from '@angular/forms'; import { UserSelectors } from '@osf/core/store/user'; import { SelectComponent } from '@osf/shared/components'; -import { TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { Primitive } from '@osf/shared/helpers'; import { SearchFilters } from '@osf/shared/models'; import { ToastService } from '@osf/shared/services'; @@ -49,7 +49,7 @@ export class InstitutionsUsersComponent { }); currentPage = signal(1); - currentPageSize = signal(TABLE_PARAMS.rows); + currentPageSize = signal(DEFAULT_TABLE_PARAMS.rows); first = signal(0); selectedDepartment = signal(null); diff --git a/src/app/features/home/pages/dashboard/dashboard.component.ts b/src/app/features/home/pages/dashboard/dashboard.component.ts index ab1603af8..72cf98d6b 100644 --- a/src/app/features/home/pages/dashboard/dashboard.component.ts +++ b/src/app/features/home/pages/dashboard/dashboard.component.ts @@ -16,7 +16,7 @@ import { ActivatedRoute, Router, RouterLink } from '@angular/router'; import { CreateProjectDialogComponent } from '@osf/features/my-projects/components'; import { IconComponent, MyProjectsTableComponent, SubHeaderComponent } from '@osf/shared/components'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { SortOrder } from '@osf/shared/enums'; import { IS_MEDIUM } from '@osf/shared/helpers'; import { MyResourcesItem, MyResourcesSearchFilters, TableParameters } from '@osf/shared/models'; @@ -44,7 +44,7 @@ export class DashboardComponent implements OnInit { readonly activeProject = signal(null); readonly sortColumn = signal(undefined); readonly sortOrder = signal(SortOrder.Asc); - readonly tableParams = signal({ ...MY_PROJECTS_TABLE_PARAMS }); + readonly tableParams = signal({ ...DEFAULT_TABLE_PARAMS }); readonly projects = select(MyResourcesSelectors.getProjects); readonly totalProjectsCount = select(MyResourcesSelectors.getTotalProjects); @@ -73,7 +73,7 @@ export class DashboardComponent implements OnInit { setupQueryParamsSubscription(): void { this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((params) => { const page = Number(params['page']) || 1; - const rows = Number(params['rows']) || MY_PROJECTS_TABLE_PARAMS.rows; + const rows = Number(params['rows']) || DEFAULT_TABLE_PARAMS.rows; const sortField = params['sortField']; const sortOrder = params['sortOrder'] as SortOrder; const search = params['search'] || ''; diff --git a/src/app/features/institutions/pages/institutions-list/institutions-list.component.ts b/src/app/features/institutions/pages/institutions-list/institutions-list.component.ts index bca6e1bf7..6314795a1 100644 --- a/src/app/features/institutions/pages/institutions-list/institutions-list.component.ts +++ b/src/app/features/institutions/pages/institutions-list/institutions-list.component.ts @@ -27,7 +27,7 @@ import { SearchInputComponent, SubHeaderComponent, } from '@osf/shared/components'; -import { TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { parseQueryFilterParams } from '@osf/shared/helpers'; import { QueryParams } from '@osf/shared/models'; import { FetchInstitutions, InstitutionsSelectors } from '@osf/shared/stores'; @@ -59,7 +59,7 @@ export class InstitutionsListComponent { queryParams = toSignal(this.route.queryParams); currentPage = signal(1); - currentPageSize = signal(TABLE_PARAMS.rows); + currentPageSize = signal(DEFAULT_TABLE_PARAMS.rows); first = signal(0); institutions = select(InstitutionsSelectors.getInstitutions); diff --git a/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.spec.ts b/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.spec.ts index ab90affb3..ee103da92 100644 --- a/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.spec.ts +++ b/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.spec.ts @@ -15,7 +15,7 @@ import { MeetingsState } from '@osf/features/meetings/store'; import { parseQueryFilterParams } from '@osf/shared/helpers'; import { MOCK_MEETING } from '@osf/shared/mocks'; import { SearchInputComponent, SubHeaderComponent } from '@shared/components'; -import { TABLE_PARAMS } from '@shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@shared/constants'; import { SortOrder } from '@shared/enums'; import { MeetingsFeatureCardComponent } from '../../components'; @@ -73,10 +73,10 @@ describe('MeetingsLandingComponent', () => { expect(component.partnerOrganizations).toEqual(PARTNER_ORGANIZATIONS); expect(component.meetingsFeatureCards).toEqual(MEETINGS_FEATURE_CARDS); expect(component.skeletonData).toHaveLength(10); - expect(component.tableParams().rows).toBe(TABLE_PARAMS.rows); + expect(component.tableParams().rows).toBe(DEFAULT_TABLE_PARAMS.rows); expect(component.tableParams().firstRowIndex).toBe(0); expect(component.currentPage()).toBe(1); - expect(component.currentPageSize()).toBe(TABLE_PARAMS.rows); + expect(component.currentPageSize()).toBe(DEFAULT_TABLE_PARAMS.rows); expect(component.sortColumn()).toBe(''); expect(component.sortOrder()).toBe(SortOrder.Asc); }); diff --git a/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.ts b/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.ts index 52bba1a88..1ecbbecd2 100644 --- a/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.ts +++ b/src/app/features/meetings/pages/meetings-landing/meetings-landing.component.ts @@ -26,7 +26,7 @@ import { ActivatedRoute, Router } from '@angular/router'; import { Meeting } from '@osf/features/meetings/models'; import { GetAllMeetings, MeetingsSelectors } from '@osf/features/meetings/store'; import { SearchInputComponent, SubHeaderComponent } from '@shared/components'; -import { TABLE_PARAMS } from '@shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@shared/constants'; import { SortOrder } from '@shared/enums'; import { parseQueryFilterParams } from '@shared/helpers'; import { QueryParams, SearchFilters, TableParameters } from '@shared/models'; @@ -62,9 +62,9 @@ export class MeetingsLandingComponent { sortColumn = signal(''); sortOrder = signal(SortOrder.Asc); currentPage = signal(1); - currentPageSize = signal(TABLE_PARAMS.rows); + currentPageSize = signal(DEFAULT_TABLE_PARAMS.rows); tableParams = signal({ - ...TABLE_PARAMS, + ...DEFAULT_TABLE_PARAMS, firstRowIndex: 0, }); diff --git a/src/app/features/moderation/components/moderators-table/moderators-table.component.ts b/src/app/features/moderation/components/moderators-table/moderators-table.component.ts index fc857a840..e3c721fd9 100644 --- a/src/app/features/moderation/components/moderators-table/moderators-table.component.ts +++ b/src/app/features/moderation/components/moderators-table/moderators-table.component.ts @@ -16,7 +16,7 @@ import { EmploymentHistoryDialogComponent, SelectComponent, } from '@osf/shared/components'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { TableParameters } from '@osf/shared/models'; @Component({ @@ -39,7 +39,7 @@ export class ModeratorsTableComponent { dialogService = inject(DialogService); translateService = inject(TranslateService); - readonly tableParams = signal({ ...MY_PROJECTS_TABLE_PARAMS }); + readonly tableParams = signal({ ...DEFAULT_TABLE_PARAMS }); readonly permissionsOptions = MODERATION_PERMISSIONS; readonly ModeratorPermission = ModeratorPermission; diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts index 8352284b6..5ce6e3647 100644 --- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts +++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.spec.ts @@ -8,7 +8,7 @@ import { of } from 'rxjs'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { ProjectFormControls } from '@osf/shared/enums'; import { MOCK_STORE } from '@osf/shared/mocks'; import { CreateProject, GetMyProjects, MyResourcesSelectors } from '@osf/shared/stores'; @@ -83,7 +83,7 @@ describe('CreateProjectDialogComponent', () => { component.submitForm(); expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new CreateProject('Title', 'Desc', 'Tpl', 'Storage', ['a1'])); - expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {})); + expect(MOCK_STORE.dispatch).toHaveBeenCalledWith(new GetMyProjects(1, DEFAULT_TABLE_PARAMS.rows, {})); expect((dialogRef as any).close).toHaveBeenCalled(); }); }); diff --git a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts index d9a1d4fa3..6f74d333a 100644 --- a/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts +++ b/src/app/features/my-projects/components/create-project-dialog/create-project-dialog.component.ts @@ -9,7 +9,7 @@ import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { AddProjectFormComponent } from '@osf/shared/components'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { ProjectFormControls } from '@osf/shared/enums'; import { CustomValidators } from '@osf/shared/helpers'; import { ProjectForm } from '@osf/shared/models'; @@ -73,7 +73,7 @@ export class CreateProjectDialogComponent { next: () => { const projects = this.store.selectSnapshot(MyResourcesSelectors.getProjects); const newProject = projects[0]; - this.actions.getMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {}); + this.actions.getMyProjects(1, DEFAULT_TABLE_PARAMS.rows, {}); this.dialogRef.close({ project: newProject }); }, }); diff --git a/src/app/features/my-projects/my-projects.component.ts b/src/app/features/my-projects/my-projects.component.ts index df2eef8fe..63ee108d7 100644 --- a/src/app/features/my-projects/my-projects.component.ts +++ b/src/app/features/my-projects/my-projects.component.ts @@ -24,7 +24,7 @@ import { FormControl, FormsModule } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { MyProjectsTableComponent, SelectComponent, SubHeaderComponent } from '@osf/shared/components'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { ResourceType, SortOrder } from '@osf/shared/enums'; import { IS_MEDIUM, parseQueryFilterParams } from '@osf/shared/helpers'; import { MyResourcesItem, MyResourcesSearchFilters, QueryParams, TableParameters } from '@osf/shared/models'; @@ -80,12 +80,12 @@ export class MyProjectsComponent implements OnInit { readonly queryParams = toSignal(this.route.queryParams); readonly currentPage = signal(1); - readonly currentPageSize = signal(MY_PROJECTS_TABLE_PARAMS.rows); + readonly currentPageSize = signal(DEFAULT_TABLE_PARAMS.rows); readonly selectedTab = signal(MyProjectsTab.Projects); readonly activeProject = signal(null); readonly sortColumn = signal(undefined); readonly sortOrder = signal(SortOrder.Asc); - readonly tableParams = signal({ ...MY_PROJECTS_TABLE_PARAMS, firstRowIndex: 0 }); + readonly tableParams = signal({ ...DEFAULT_TABLE_PARAMS, firstRowIndex: 0 }); readonly projects = select(MyResourcesSelectors.getProjects); readonly registrations = select(MyResourcesSelectors.getRegistrations); @@ -174,7 +174,7 @@ export class MyProjectsComponent implements OnInit { updateComponentState(params: QueryParams): void { untracked(() => { - const size = params.size || MY_PROJECTS_TABLE_PARAMS.rows; + const size = params.size || DEFAULT_TABLE_PARAMS.rows; this.currentPage.set(params.page ?? 1); this.currentPageSize.set(size); @@ -200,7 +200,7 @@ export class MyProjectsComponent implements OnInit { this.isLoading.set(true); const filters = this.createFilters(params); const pageNumber = params.page ?? 1; - const pageSize = params.size ?? MY_PROJECTS_TABLE_PARAMS.rows; + const pageSize = params.size ?? DEFAULT_TABLE_PARAMS.rows; let action$; switch (this.selectedTab()) { diff --git a/src/app/features/preprints/pages/my-preprints/my-preprints.component.ts b/src/app/features/preprints/pages/my-preprints/my-preprints.component.ts index 6e12c9e42..400431522 100644 --- a/src/app/features/preprints/pages/my-preprints/my-preprints.component.ts +++ b/src/app/features/preprints/pages/my-preprints/my-preprints.component.ts @@ -24,7 +24,7 @@ import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { ListInfoShortenerComponent, SearchInputComponent, SubHeaderComponent } from '@osf/shared/components'; -import { TABLE_PARAMS } from '@osf/shared/constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants'; import { SortOrder } from '@osf/shared/enums'; import { parseQueryFilterParams } from '@osf/shared/helpers'; import { QueryParams, SearchFilters, TableParameters } from '@osf/shared/models'; @@ -61,8 +61,8 @@ export class MyPreprintsComponent { sortColumn = signal(''); sortOrder = signal(SortOrder.Asc); currentPage = signal(1); - currentPageSize = signal(TABLE_PARAMS.rows); - tableParams = signal({ ...TABLE_PARAMS, firstRowIndex: 0 }); + currentPageSize = signal(DEFAULT_TABLE_PARAMS.rows); + tableParams = signal({ ...DEFAULT_TABLE_PARAMS, firstRowIndex: 0 }); preprints = select(PreprintSelectors.getMyPreprints); preprintsTotalCount = select(PreprintSelectors.getMyPreprintsTotalCount); diff --git a/src/app/shared/components/add-project-form/add-project-form.component.spec.ts b/src/app/shared/components/add-project-form/add-project-form.component.spec.ts index d9ab2dc53..012bbd277 100644 --- a/src/app/shared/components/add-project-form/add-project-form.component.spec.ts +++ b/src/app/shared/components/add-project-form/add-project-form.component.spec.ts @@ -12,7 +12,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { UserSelectors, UserState } from '@core/store/user'; -import { MY_PROJECTS_TABLE_PARAMS } from '@osf/shared/constants/my-projects-table.constants'; +import { DEFAULT_TABLE_PARAMS } from '@osf/shared/constants/my-projects-table.constants'; import { ProjectFormControls } from '@osf/shared/enums/create-project-form-controls.enum'; import { CustomValidators } from '@osf/shared/helpers'; import { MOCK_STORE, MOCK_USER } from '@osf/shared/mocks'; @@ -107,7 +107,7 @@ describe('AddProjectFormComponent', () => { it('should load projects on init', () => { const dispatchSpy = jest.spyOn(store, 'dispatch'); - const action = new GetMyProjects(1, MY_PROJECTS_TABLE_PARAMS.rows, {}); + const action = new GetMyProjects(1, DEFAULT_TABLE_PARAMS.rows, {}); store.dispatch(action); expect(dispatchSpy).toHaveBeenCalledWith(action); diff --git a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.scss b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.scss index 59134fadc..a4c3a31e5 100644 --- a/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.scss +++ b/src/app/shared/components/contributors/add-contributor-dialog/add-contributor-dialog.component.scss @@ -1,8 +1,7 @@ -@use "styles/variables" as var; @use "styles/mixins" as mix; .label { - color: var.$dark-blue-1; + color: var(--dark-blue-1); margin: 0; cursor: pointer; } @@ -13,5 +12,5 @@ } .border-divider { - border-bottom: 1px solid var.$grey-2; + border-bottom: 1px solid var(--grey-2); } diff --git a/src/app/shared/components/contributors/add-contributor-item/add-contributor-item.component.html b/src/app/shared/components/contributors/add-contributor-item/add-contributor-item.component.html index c9de4d79c..239a1b4c2 100644 --- a/src/app/shared/components/contributors/add-contributor-item/add-contributor-item.component.html +++ b/src/app/shared/components/contributors/add-contributor-item/add-contributor-item.component.html @@ -2,7 +2,7 @@

{{ contributor().fullName }}

-

{{ 'project.overview.metadata.contributors' | translate }}: @for (contributor of registrationData().contributors; track contributor) { - {{ contributor.fullName }} + {{ contributor.fullName }} @if (!$last) { , } diff --git a/src/app/shared/components/registration-card/registration-card.component.scss b/src/app/shared/components/registration-card/registration-card.component.scss index 498d5c14a..e69de29bb 100644 --- a/src/app/shared/components/registration-card/registration-card.component.scss +++ b/src/app/shared/components/registration-card/registration-card.component.scss @@ -1,13 +0,0 @@ -@use "styles/mixins" as mix; - -:host { - .icon-container { - color: black; - @include mix.flex-align-center; - gap: 0.8rem; - - h3 { - white-space: nowrap; - } - } -} diff --git a/src/app/shared/components/resource-card/resource-card.component.scss b/src/app/shared/components/resource-card/resource-card.component.scss index 522c1163b..9c523c659 100644 --- a/src/app/shared/components/resource-card/resource-card.component.scss +++ b/src/app/shared/components/resource-card/resource-card.component.scss @@ -1,9 +1,7 @@ -@use "styles/variables" as var; - .resource { display: flex; flex-direction: column; - border: 1px solid var.$grey-2; + border: 1px solid var(--grey-2); border-radius: 8px; padding: 1.7rem; row-gap: 0.85rem; @@ -12,7 +10,7 @@ line-height: 28px; a { - color: var.$dark-blue-1; + color: var(--dark-blue-1); } } @@ -33,14 +31,14 @@ .type { width: fit-content; - background: var.$grey-3; + background: var(--grey-3); font-weight: bold; - padding: 4px 12px 4px 12px; + padding: 4px 12px; border-radius: 4px; } p { - color: var.$dark-blue-1; + color: var(--dark-blue-1); font-weight: 400; display: inline; overflow: hidden; @@ -52,6 +50,6 @@ .break-line { border: none; - border-top: 1px solid var.$grey-2; + border-top: 1px solid var(--grey-2); } } diff --git a/src/app/shared/components/search-help-tutorial/search-help-tutorial.component.scss b/src/app/shared/components/search-help-tutorial/search-help-tutorial.component.scss index 62f1bd329..5f2aff79f 100644 --- a/src/app/shared/components/search-help-tutorial/search-help-tutorial.component.scss +++ b/src/app/shared/components/search-help-tutorial/search-help-tutorial.component.scss @@ -1,12 +1,11 @@ -@use "styles/variables" as var; @use "styles/mixins" as mix; .stepper { position: absolute; display: flex; flex-direction: column; - background: var.$white; - border: 1px solid var.$grey-2; + background: var(--white); + border: 1px solid var(--grey-2); border-radius: 12px; row-gap: mix.rem(24px); padding: mix.rem(24px); diff --git a/src/app/shared/components/search-results-container/search-results-container.component.scss b/src/app/shared/components/search-results-container/search-results-container.component.scss index feaeacc4d..68b2f7a86 100644 --- a/src/app/shared/components/search-results-container/search-results-container.component.scss +++ b/src/app/shared/components/search-results-container/search-results-container.component.scss @@ -1,5 +1,3 @@ -@use "styles/variables" as var; - .result-count { color: var(--pr-blue-1); } @@ -10,12 +8,12 @@ justify-content: center; width: 100%; height: 44px; - border: 1px solid var.$grey-2; + border: 1px solid var(--grey-2); border-radius: 12px; - padding: 0 24px 0 24px; + padding: 0 1.5rem; cursor: pointer; } .card-selected { - background: var.$bg-blue-2; + background: var(--bg-blue-2); } diff --git a/src/app/shared/components/stepper/stepper.component.scss b/src/app/shared/components/stepper/stepper.component.scss index 1ae17b641..90c570f4f 100644 --- a/src/app/shared/components/stepper/stepper.component.scss +++ b/src/app/shared/components/stepper/stepper.component.scss @@ -1,4 +1,5 @@ @use "styles/mixins" as mix; + :host { max-width: 100%; overflow: auto; diff --git a/src/app/shared/constants/meetings-table.constants.ts b/src/app/shared/constants/default-table-params.constants.ts similarity index 80% rename from src/app/shared/constants/meetings-table.constants.ts rename to src/app/shared/constants/default-table-params.constants.ts index 769587a07..34bfb03dc 100644 --- a/src/app/shared/constants/meetings-table.constants.ts +++ b/src/app/shared/constants/default-table-params.constants.ts @@ -1,6 +1,6 @@ import { TableParameters } from '@shared/models'; -export const TABLE_PARAMS: TableParameters = { +export const DEFAULT_TABLE_PARAMS: TableParameters = { rows: 10, paginator: true, scrollable: false, diff --git a/src/app/shared/constants/index.ts b/src/app/shared/constants/index.ts index 23069ad60..243495732 100644 --- a/src/app/shared/constants/index.ts +++ b/src/app/shared/constants/index.ts @@ -3,13 +3,11 @@ export * from './addons-category-options.const'; export * from './addons-tab-options.const'; export * from './contributors.constants'; export * from './default-citation-titles.const'; +export * from './default-table-params.constants'; export * from './filter-placeholders'; export * from './input-limits.const'; export * from './input-validation-messages.const'; export * from './language.const'; -export * from './meetings-table.constants'; -export * from './my-projects-table.constants'; -export * from './pie-chart-palette'; export * from './pie-chart-palette'; export * from './registry-services-icons.const'; export * from './resource-card-labels.const'; diff --git a/src/app/shared/constants/my-projects-table.constants.ts b/src/app/shared/constants/my-projects-table.constants.ts deleted file mode 100644 index a3d485202..000000000 --- a/src/app/shared/constants/my-projects-table.constants.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { TableParameters } from '../models'; - -export const MY_PROJECTS_TABLE_PARAMS: TableParameters = { - rows: 10, - paginator: true, - scrollable: false, - rowsPerPageOptions: [5, 10, 25], - totalRecords: 0, - firstRowIndex: 0, - defaultSortColumn: null, - defaultSortOrder: null, -}; diff --git a/src/app/shared/models/index.ts b/src/app/shared/models/index.ts index 395386811..e6902177d 100644 --- a/src/app/shared/models/index.ts +++ b/src/app/shared/models/index.ts @@ -21,7 +21,6 @@ export * from './institutions'; export * from './language-code.model'; export * from './license'; export * from './license.model'; -export * from './license.model'; export * from './licenses-json-api.model'; export * from './meta-tags'; export * from './metadata-tabs.model'; From ffce019b623ecf1bed3c754f25f55b672baed5db Mon Sep 17 00:00:00 2001 From: Nazar Semets Date: Thu, 11 Sep 2025 00:09:24 +0300 Subject: [PATCH 04/10] fix(routes): removed unused route --- src/app/app.routes.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index ff46345b1..f3537c4f8 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -35,11 +35,6 @@ export const routes: Routes = [ canActivate: [authGuard], providers: [provideStates([ProjectsState])], }, - { - path: 'confirm/:userId/:token', - loadComponent: () => import('./features/home/home.component').then((mod) => mod.HomeComponent), - data: { skipBreadcrumbs: true }, - }, { path: 'register', canActivate: [redirectIfLoggedInGuard], From fa83eac8be1721ff857255293693dcf9a8a3283e Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 11 Sep 2025 12:27:08 +0300 Subject: [PATCH 05/10] fix(accessibility): added aria labels to institutions --- .../admin-table/admin-table.component.html | 27 +++++++++++++------ ...stitution-preprint-to-table-data.mapper.ts | 8 ++---- ...nstitution-project-to-table-data.mapper.ts | 10 +++---- ...ution-registration-to-table-data.mapper.ts | 6 +---- .../institution-user-to-table-data.mapper.ts | 10 ++----- .../institutions-preprints.component.html | 2 +- .../institutions-projects.component.html | 6 +++-- .../institutions-projects.component.scss | 3 --- .../institutions-registrations.component.html | 2 +- .../overview-toolbar.component.html | 2 +- .../education/education.component.html | 2 +- .../tags-input/tags-input.component.html | 2 +- src/assets/i18n/en.json | 10 ++++--- src/styles/overrides/tag.scss | 2 +- 14 files changed, 45 insertions(+), 47 deletions(-) diff --git a/src/app/features/admin-institutions/components/admin-table/admin-table.component.html b/src/app/features/admin-institutions/components/admin-table/admin-table.component.html index 6a6600616..8a14efc91 100644 --- a/src/app/features/admin-institutions/components/admin-table/admin-table.component.html +++ b/src/app/features/admin-institutions/components/admin-table/admin-table.component.html @@ -32,11 +32,12 @@ [showToggleAll]="false" [showClear]="false" [dropdownIcon]="'hidden'" + [ariaLabel]="'common.accessibility.customizeOptions' | translate" >
- - {{ 'adminInstitutions.institutionUsers.customize' | translate }} + + {{ 'adminInstitutions.institutionUsers.customize' | translate }}
@@ -49,6 +50,7 @@ icon="fa fa-download text-primary text-xl" outlined styleClass="grey-border-color" + [ariaLabel]="'common.buttons.download' | translate" (onClick)="downloadMenu.toggle($event)" /> @@ -56,11 +58,11 @@ - - + [attr.aria-label]="'common.buttons.reportsLink' | translate" + > }

@@ -112,7 +114,7 @@ @if (col.dateFormat) { {{ getCellValue(rowData[col.field]) | date: col.dateFormat }} @@ -135,6 +137,7 @@ [icon]="col.iconClass" variant="text" severity="info" + [ariaLabel]="'common.accessibility.tooltipBtn' | translate" (onClick)="onIconClick(rowData, col)" /> } @@ -158,7 +161,13 @@ @if (isNextPreviousPagination()) {
@if (firstLink() && prevLink()) { - + } @@ -174,6 +184,7 @@ severity="contrast" text [disabled]="!nextLink()" + [ariaLabel]="'common.accessibility.goToNextPage' | translate" (onClick)="switchPage(nextLink())" />
diff --git a/src/app/features/admin-institutions/mappers/institution-preprint-to-table-data.mapper.ts b/src/app/features/admin-institutions/mappers/institution-preprint-to-table-data.mapper.ts index f988e5823..81973bcb9 100644 --- a/src/app/features/admin-institutions/mappers/institution-preprint-to-table-data.mapper.ts +++ b/src/app/features/admin-institutions/mappers/institution-preprint-to-table-data.mapper.ts @@ -1,15 +1,11 @@ -import { extractPathAfterDomain } from '@osf/features/admin-institutions/helpers'; import { ResourceModel } from '@shared/models'; +import { extractPathAfterDomain } from '../helpers'; import { TableCellData, TableCellLink } from '../models'; export function mapPreprintResourceToTableData(preprint: ResourceModel): TableCellData { return { - title: { - text: preprint.title, - url: preprint.absoluteUrl, - target: '_blank', - } as TableCellLink, + title: preprint.title, link: { text: preprint.absoluteUrl.split('/').pop() || preprint.absoluteUrl, url: preprint.absoluteUrl, diff --git a/src/app/features/admin-institutions/mappers/institution-project-to-table-data.mapper.ts b/src/app/features/admin-institutions/mappers/institution-project-to-table-data.mapper.ts index f795c9f23..1e5e9bfd7 100644 --- a/src/app/features/admin-institutions/mappers/institution-project-to-table-data.mapper.ts +++ b/src/app/features/admin-institutions/mappers/institution-project-to-table-data.mapper.ts @@ -1,13 +1,11 @@ -import { extractPathAfterDomain } from '@osf/features/admin-institutions/helpers'; -import { TableCellData, TableCellLink } from '@osf/features/admin-institutions/models'; import { ResourceModel } from '@shared/models'; +import { extractPathAfterDomain } from '../helpers'; +import { TableCellData, TableCellLink } from '../models'; + export function mapProjectResourceToTableCellData(project: ResourceModel): TableCellData { return { - title: { - url: project.absoluteUrl, - text: project.title, - } as TableCellLink, + title: project.title, link: { url: project.absoluteUrl, text: project.absoluteUrl.split('/').pop() || project.absoluteUrl, diff --git a/src/app/features/admin-institutions/mappers/institution-registration-to-table-data.mapper.ts b/src/app/features/admin-institutions/mappers/institution-registration-to-table-data.mapper.ts index dfba289d1..8dbd650cf 100644 --- a/src/app/features/admin-institutions/mappers/institution-registration-to-table-data.mapper.ts +++ b/src/app/features/admin-institutions/mappers/institution-registration-to-table-data.mapper.ts @@ -5,11 +5,7 @@ import { TableCellData, TableCellLink } from '../models'; export function mapRegistrationResourceToTableData(registration: ResourceModel): TableCellData { return { - title: { - text: registration.title, - url: registration.absoluteUrl, - target: '_blank', - } as TableCellLink, + title: registration.title, link: { text: registration.absoluteUrl.split('/').pop() || registration.absoluteUrl, url: registration.absoluteUrl, diff --git a/src/app/features/admin-institutions/mappers/institution-user-to-table-data.mapper.ts b/src/app/features/admin-institutions/mappers/institution-user-to-table-data.mapper.ts index 7f86ec86e..914c4f62a 100644 --- a/src/app/features/admin-institutions/mappers/institution-user-to-table-data.mapper.ts +++ b/src/app/features/admin-institutions/mappers/institution-user-to-table-data.mapper.ts @@ -1,17 +1,11 @@ -import { InstitutionUser, TableCellData } from '@osf/features/admin-institutions/models'; +import { InstitutionUser, TableCellData } from '../models'; import { environment } from 'src/environments/environment'; export function mapUserToTableCellData(user: InstitutionUser): TableCellData { return { id: user.id, - userName: user.userName - ? { - text: user.userName, - url: `${environment.webUrl}/${user.userId}`, - target: '_blank', - } - : '-', + userName: user.userName || '-', department: user.department || '-', userLink: { text: user.userId, diff --git a/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.html b/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.html index d8adbe5ba..f3c504b3b 100644 --- a/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.html +++ b/src/app/features/admin-institutions/pages/institutions-preprints/institutions-preprints.component.html @@ -18,7 +18,7 @@

-

{{ resourcesCount() }} {{ 'adminInstitutions.projects.totalProjects' | translate }}

+

+ {{ resourcesCount() }} {{ 'adminInstitutions.projects.totalProjects' | translate }} +

diff --git a/src/app/features/settings/profile-settings/components/education/education.component.html b/src/app/features/settings/profile-settings/components/education/education.component.html index 7e09a236b..aadd8fda0 100644 --- a/src/app/features/settings/profile-settings/components/education/education.component.html +++ b/src/app/features/settings/profile-settings/components/education/education.component.html @@ -14,7 +14,7 @@
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index c50bda463..713d2d4eb 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -59,7 +59,12 @@ "goToNextPage": "Go to next page", "mainNavigation": "Main navigation", "searchHelp": "Search help", - "confirmationDialog": "Confirmation dialog" + "confirmationDialog": "Confirmation dialog", + "reportsLink": "Reports link", + "tooltipBtn": "Tooltip button", + "customizeOptions": "Customize options", + "toggleProjectVisibility": "Toggle project visibility", + "tagInput": "Tag input" }, "dialogs": { "confirmation": "Confirmation" @@ -1678,7 +1683,6 @@ "startDate": "Start Date", "endDate": "End Date", "ongoing": "Ongoing", - "addMore": "Add One More", "successUpdate": "Education successfully updated." }, "changesDiscarded": "Changes discarded successfully.", @@ -2897,4 +2901,4 @@ "software": "Software", "other": "Other" } -} \ No newline at end of file +} diff --git a/src/styles/overrides/tag.scss b/src/styles/overrides/tag.scss index 9a6e145aa..c0fb70971 100644 --- a/src/styles/overrides/tag.scss +++ b/src/styles/overrides/tag.scss @@ -5,7 +5,7 @@ --p-tag-warn-background: var(--yellow-2); --p-tag-warn-color: var(--yellow-1); - --p-tag-secondary-background: var(--dark-blue-1); + --p-tag-secondary-background: var(--grey-1); --p-tag-secondary-color: var(--white); --p-tag-info-background: var(--bg-blue-3); From 2e2a35272723c8e35522091f23808e9a7b7ac8cb Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 11 Sep 2025 13:46:16 +0300 Subject: [PATCH 06/10] fix(accessibility): removed aria label for header button --- src/app/core/components/header/header.component.html | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/app/core/components/header/header.component.html b/src/app/core/components/header/header.component.html index ccb4cb26a..c76adec66 100644 --- a/src/app/core/components/header/header.component.html +++ b/src/app/core/components/header/header.component.html @@ -18,11 +18,7 @@ } @else { - + }
From 5e3d8b8f66b87969d6c5a400dc0439108a95781a Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 11 Sep 2025 14:39:34 +0300 Subject: [PATCH 07/10] fix(metadata): fixed spacing --- ...ata-affiliated-institutions.component.html | 6 ++-- .../metadata-contributors.component.html | 6 ++-- .../metadata-description.component.html | 6 +--- .../metadata-funding.component.html | 6 ++-- .../metadata-license.component.html | 12 ++------ .../metadata-publication-doi.component.html | 15 +++++----- ...tadata-resource-information.component.html | 30 ++++++++++--------- .../shared-metadata.component.html | 4 +-- .../subjects/subjects.component.html | 2 +- 9 files changed, 41 insertions(+), 46 deletions(-) diff --git a/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html b/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html index 4a994d1a5..21b111021 100644 --- a/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html +++ b/src/app/features/metadata/components/metadata-affiliated-institutions/metadata-affiliated-institutions.component.html @@ -6,10 +6,12 @@

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

}
- +
+ +
diff --git a/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html b/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html index f1f26d9a2..a65f57fb3 100644 --- a/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html +++ b/src/app/features/metadata/components/metadata-contributors/metadata-contributors.component.html @@ -1,10 +1,10 @@ - +

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

@if (!readonly()) { @@ -12,7 +12,7 @@

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

@if (contributors()) { -
+
@for (contributor of contributors(); track contributor.id) {
{{ contributor.fullName }} diff --git a/src/app/features/metadata/components/metadata-description/metadata-description.component.html b/src/app/features/metadata/components/metadata-description/metadata-description.component.html index 845f1d4bd..69fdc299b 100644 --- a/src/app/features/metadata/components/metadata-description/metadata-description.component.html +++ b/src/app/features/metadata/components/metadata-description/metadata-description.component.html @@ -11,9 +11,5 @@

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

}
- @if (description()) { -

{{ description() }}

- } @else { -

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

- } +

{{ description() || ('project.overview.metadata.noDescription' | translate) }}

diff --git a/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html b/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html index 67f7d77ca..5fa7fa5e7 100644 --- a/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html +++ b/src/app/features/metadata/components/metadata-funding/metadata-funding.component.html @@ -12,7 +12,7 @@

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

@if (funders()?.length) { -
+
@for (funder of funders(); track funder.funderIdentifier) {

{{ 'files.detail.resourceMetadata.fields.funder' | translate }}: {{ funder.funderName }}

@@ -35,8 +35,8 @@

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

}
} @else { -
-

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

+
+

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

} diff --git a/src/app/features/metadata/components/metadata-license/metadata-license.component.html b/src/app/features/metadata/components/metadata-license/metadata-license.component.html index 91982195f..d4a993b05 100644 --- a/src/app/features/metadata/components/metadata-license/metadata-license.component.html +++ b/src/app/features/metadata/components/metadata-license/metadata-license.component.html @@ -11,13 +11,7 @@

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

}
- @if (license()) { -
-

{{ license()?.name }}

-
- } @else { -
-

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

-
- } +
+

{{ license()?.name || ('project.overview.metadata.noLicense' | translate) }}

+
diff --git a/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html b/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html index 52681361c..477b6f458 100644 --- a/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html +++ b/src/app/features/metadata/components/metadata-publication-doi/metadata-publication-doi.component.html @@ -10,30 +10,31 @@

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

> }
+ @if (resourceType() === ResourceType.Project) { @if (identifiers() && identifiers().length) { -
+
@for (identifier of identifiers()!; track identifier.id) { @if (identifier.category === 'doi') { - + {{ doiHost + identifier.value }} } }
} @else { -
-

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

+
+

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

} } @else { -
+
@if (publicationDoi()) { - + {{ doiHost + publicationDoi() }} } @else { -

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

+

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

}
} diff --git a/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html b/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html index b31512d64..5f2621417 100644 --- a/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html +++ b/src/app/features/metadata/components/metadata-resource-information/metadata-resource-information.component.html @@ -19,19 +19,21 @@

}

- @if (customItemMetadata()?.resourceTypeGeneral) { -
-

- {{ 'project.overview.metadata.resourceType' | translate }}: - {{ getResourceTypeName(customItemMetadata()?.resourceTypeGeneral!) }} -

+
+ @if (customItemMetadata()?.resourceTypeGeneral) { +
+

+ {{ 'project.overview.metadata.resourceType' | translate }}: + {{ getResourceTypeName(customItemMetadata()?.resourceTypeGeneral!) }} +

-

- {{ 'project.overview.metadata.resourceLanguage' | translate }}: - {{ getLanguageName(customItemMetadata()?.language || '') }} -

-
- } @else { -

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

- } +

+ {{ 'project.overview.metadata.resourceLanguage' | translate }}: + {{ getLanguageName(customItemMetadata()?.language || '') }} +

+
+ } @else { +

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

+ } +
diff --git a/src/app/features/metadata/components/shared-metadata/shared-metadata.component.html b/src/app/features/metadata/components/shared-metadata/shared-metadata.component.html index cfd856d73..b89107798 100644 --- a/src/app/features/metadata/components/shared-metadata/shared-metadata.component.html +++ b/src/app/features/metadata/components/shared-metadata/shared-metadata.component.html @@ -7,7 +7,7 @@

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

-

+

{{ metadata()?.dateCreated | date: 'MMM d, y, h:mm a' }}

@@ -17,7 +17,7 @@

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

-

+

{{ metadata()?.dateModified | date: 'MMM d, y, h:mm a' }}

diff --git a/src/app/shared/components/subjects/subjects.component.html b/src/app/shared/components/subjects/subjects.component.html index 875f46413..fcd77e332 100644 --- a/src/app/shared/components/subjects/subjects.component.html +++ b/src/app/shared/components/subjects/subjects.component.html @@ -64,7 +64,7 @@

{{ 'shared.subjects.title' | translate }}

(onNodeCollapse)="collapseNode($event.node)" (onNodeSelect)="selectSubject($event.node.data)" (onNodeUnselect)="removeSubject($event.node.data)" - ariaLabel="{{ 'shared.subjects.subjectTree' | translate }}" + [ariaLabel]="'shared.subjects.subjectTree' | translate" > } From 44c49d6dd2c127a4c084ce854a9d6f6fe788043b Mon Sep 17 00:00:00 2001 From: nsemets Date: Thu, 11 Sep 2025 15:08:13 +0300 Subject: [PATCH 08/10] fix(profile): combined user and my profiles into one --- src/app/app.routes.ts | 8 +- .../my-profile/my-profile.component.html | 7 -- .../my-profile/my-profile.component.spec.ts | 26 ------- .../pages/my-profile/my-profile.component.ts | 44 ----------- .../user-profile/user-profile.component.html | 11 --- .../user-profile/user-profile.component.scss | 0 .../user-profile.component.spec.ts | 31 -------- .../user-profile/user-profile.component.ts | 46 ----------- .../features/profile/profile.component.html | 11 +++ ....component.scss => profile.component.scss} | 0 .../profile/profile.component.spec.ts | 25 ++++++ src/app/features/profile/profile.component.ts | 78 +++++++++++++++++++ 12 files changed, 116 insertions(+), 171 deletions(-) delete mode 100644 src/app/features/profile/pages/my-profile/my-profile.component.html delete mode 100644 src/app/features/profile/pages/my-profile/my-profile.component.spec.ts delete mode 100644 src/app/features/profile/pages/my-profile/my-profile.component.ts delete mode 100644 src/app/features/profile/pages/user-profile/user-profile.component.html delete mode 100644 src/app/features/profile/pages/user-profile/user-profile.component.scss delete mode 100644 src/app/features/profile/pages/user-profile/user-profile.component.spec.ts delete mode 100644 src/app/features/profile/pages/user-profile/user-profile.component.ts create mode 100644 src/app/features/profile/profile.component.html rename src/app/features/profile/{pages/my-profile/my-profile.component.scss => profile.component.scss} (100%) create mode 100644 src/app/features/profile/profile.component.spec.ts create mode 100644 src/app/features/profile/profile.component.ts diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index f3537c4f8..fb3bfff07 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -108,17 +108,13 @@ export const routes: Routes = [ }, { path: 'my-profile', - loadComponent: () => - import('./features/profile/pages/my-profile/my-profile.component').then((mod) => mod.MyProfileComponent), + loadComponent: () => import('./features/profile/profile.component').then((mod) => mod.ProfileComponent), providers: [provideStates([ProfileState])], canActivate: [authGuard], }, { path: 'user/:id', - loadComponent: () => - import('./features/profile/pages/user-profile/user-profile.component').then( - (mod) => mod.UserProfileComponent - ), + loadComponent: () => import('./features/profile/profile.component').then((mod) => mod.ProfileComponent), providers: [provideStates([ProfileState])], }, { diff --git a/src/app/features/profile/pages/my-profile/my-profile.component.html b/src/app/features/profile/pages/my-profile/my-profile.component.html deleted file mode 100644 index 013f43e57..000000000 --- a/src/app/features/profile/pages/my-profile/my-profile.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - -@if (currentUser()) { -
- -
-} diff --git a/src/app/features/profile/pages/my-profile/my-profile.component.spec.ts b/src/app/features/profile/pages/my-profile/my-profile.component.spec.ts deleted file mode 100644 index 3e3efec9a..000000000 --- a/src/app/features/profile/pages/my-profile/my-profile.component.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GlobalSearchComponent } from '@osf/shared/components'; - -import { ProfileInformationComponent } from '../../components'; - -import { MyProfileComponent } from './my-profile.component'; - -describe.skip('MyProfileComponent', () => { - let component: MyProfileComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [MyProfileComponent, [ProfileInformationComponent, GlobalSearchComponent]], - }).compileComponents(); - - fixture = TestBed.createComponent(MyProfileComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/features/profile/pages/my-profile/my-profile.component.ts b/src/app/features/profile/pages/my-profile/my-profile.component.ts deleted file mode 100644 index 358adfbe1..000000000 --- a/src/app/features/profile/pages/my-profile/my-profile.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { createDispatchMap, select } from '@ngxs/store'; - -import { ChangeDetectionStrategy, Component, inject, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; - -import { UserSelectors } from '@core/store/user'; -import { GlobalSearchComponent } from '@osf/shared/components'; -import { SEARCH_TAB_OPTIONS } from '@osf/shared/constants'; -import { ResourceType } from '@osf/shared/enums'; -import { SetDefaultFilterValue, UpdateFilterValue } from '@osf/shared/stores/global-search'; - -import { ProfileInformationComponent } from '../../components'; -import { SetUserProfile } from '../../store'; - -@Component({ - selector: 'osf-my-profile', - imports: [ProfileInformationComponent, GlobalSearchComponent], - templateUrl: './my-profile.component.html', - styleUrl: './my-profile.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class MyProfileComponent implements OnInit { - private router = inject(Router); - private actions = createDispatchMap({ - setUserProfile: SetUserProfile, - updateFilterValue: UpdateFilterValue, - setDefaultFilterValue: SetDefaultFilterValue, - }); - - currentUser = select(UserSelectors.getCurrentUser); - - resourceTabOptions = SEARCH_TAB_OPTIONS.filter((x) => x.value !== ResourceType.Agent); - - ngOnInit(): void { - const user = this.currentUser(); - if (user) { - this.actions.setDefaultFilterValue('creator', user.iri!); - } - } - - toProfileSettings() { - this.router.navigate(['settings/profile']); - } -} diff --git a/src/app/features/profile/pages/user-profile/user-profile.component.html b/src/app/features/profile/pages/user-profile/user-profile.component.html deleted file mode 100644 index c62db7f8d..000000000 --- a/src/app/features/profile/pages/user-profile/user-profile.component.html +++ /dev/null @@ -1,11 +0,0 @@ -@if (isUserLoading()) { - -} @else { - @if (currentUser()) { - - -
- -
- } -} diff --git a/src/app/features/profile/pages/user-profile/user-profile.component.scss b/src/app/features/profile/pages/user-profile/user-profile.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/app/features/profile/pages/user-profile/user-profile.component.spec.ts b/src/app/features/profile/pages/user-profile/user-profile.component.spec.ts deleted file mode 100644 index b357490cf..000000000 --- a/src/app/features/profile/pages/user-profile/user-profile.component.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { MockComponents } from 'ng-mocks'; - -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GlobalSearchComponent, LoadingSpinnerComponent } from '@osf/shared/components'; - -import { ProfileInformationComponent } from '../../components'; - -import { UserProfileComponent } from './user-profile.component'; - -describe.skip('UserProfileComponent', () => { - let component: UserProfileComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - UserProfileComponent, - ...MockComponents(ProfileInformationComponent, GlobalSearchComponent, LoadingSpinnerComponent), - ], - }).compileComponents(); - - fixture = TestBed.createComponent(UserProfileComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/features/profile/pages/user-profile/user-profile.component.ts b/src/app/features/profile/pages/user-profile/user-profile.component.ts deleted file mode 100644 index e34b0baef..000000000 --- a/src/app/features/profile/pages/user-profile/user-profile.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { createDispatchMap, select } from '@ngxs/store'; - -import { ChangeDetectionStrategy, Component, HostBinding, inject, OnInit } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; - -import { GlobalSearchComponent, LoadingSpinnerComponent } from '@osf/shared/components'; -import { SEARCH_TAB_OPTIONS } from '@osf/shared/constants'; -import { ResourceType } from '@osf/shared/enums'; -import { SetDefaultFilterValue } from '@osf/shared/stores/global-search'; - -import { ProfileInformationComponent } from '../../components'; -import { FetchUserProfile, ProfileSelectors } from '../../store'; - -@Component({ - selector: 'osf-user-profile', - imports: [ProfileInformationComponent, GlobalSearchComponent, LoadingSpinnerComponent], - templateUrl: './user-profile.component.html', - styleUrl: './user-profile.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class UserProfileComponent implements OnInit { - @HostBinding('class') classes = 'flex-1'; - - private route = inject(ActivatedRoute); - private actions = createDispatchMap({ - fetchUserProfile: FetchUserProfile, - setDefaultFilterValue: SetDefaultFilterValue, - }); - - currentUser = select(ProfileSelectors.getUserProfile); - isUserLoading = select(ProfileSelectors.isUserProfileLoading); - - resourceTabOptions = SEARCH_TAB_OPTIONS.filter((x) => x.value !== ResourceType.Agent); - - ngOnInit(): void { - const userId = this.route.snapshot.params['id']; - - if (userId) { - this.actions.fetchUserProfile(userId).subscribe({ - next: () => { - this.actions.setDefaultFilterValue('creator', this.currentUser()!.iri!); - }, - }); - } - } -} diff --git a/src/app/features/profile/profile.component.html b/src/app/features/profile/profile.component.html new file mode 100644 index 000000000..1df872629 --- /dev/null +++ b/src/app/features/profile/profile.component.html @@ -0,0 +1,11 @@ +@if (isUserLoading() && !isMyProfile()) { + +} @else { + @if (user()) { + + +
+ +
+ } +} diff --git a/src/app/features/profile/pages/my-profile/my-profile.component.scss b/src/app/features/profile/profile.component.scss similarity index 100% rename from src/app/features/profile/pages/my-profile/my-profile.component.scss rename to src/app/features/profile/profile.component.scss diff --git a/src/app/features/profile/profile.component.spec.ts b/src/app/features/profile/profile.component.spec.ts new file mode 100644 index 000000000..f50fed4e1 --- /dev/null +++ b/src/app/features/profile/profile.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GlobalSearchComponent } from '@osf/shared/components'; + +import { ProfileInformationComponent } from './components'; +import { ProfileComponent } from './profile.component'; + +describe.skip('ProfileComponent', () => { + let component: ProfileComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ProfileComponent, [ProfileInformationComponent, GlobalSearchComponent]], + }).compileComponents(); + + fixture = TestBed.createComponent(ProfileComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/profile/profile.component.ts b/src/app/features/profile/profile.component.ts new file mode 100644 index 000000000..3720c18c0 --- /dev/null +++ b/src/app/features/profile/profile.component.ts @@ -0,0 +1,78 @@ +import { createDispatchMap, select } from '@ngxs/store'; + +import { ChangeDetectionStrategy, Component, computed, DestroyRef, inject, OnInit } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { ActivatedRoute, Router } from '@angular/router'; + +import { UserSelectors } from '@core/store/user'; +import { GlobalSearchComponent, LoadingSpinnerComponent } from '@osf/shared/components'; +import { SEARCH_TAB_OPTIONS } from '@osf/shared/constants'; +import { ResourceType } from '@osf/shared/enums'; +import { User } from '@osf/shared/models'; +import { SetDefaultFilterValue } from '@osf/shared/stores/global-search'; + +import { ProfileInformationComponent } from './components'; +import { FetchUserProfile, ProfileSelectors, SetUserProfile } from './store'; + +@Component({ + selector: 'osf-profile', + templateUrl: './profile.component.html', + styleUrl: './profile.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ProfileInformationComponent, GlobalSearchComponent, LoadingSpinnerComponent], +}) +export class ProfileComponent implements OnInit { + private router = inject(Router); + private route = inject(ActivatedRoute); + private destroyRef = inject(DestroyRef); + private actions = createDispatchMap({ + fetchUserProfile: FetchUserProfile, + setDefaultFilterValue: SetDefaultFilterValue, + setUserProfile: SetUserProfile, + }); + + private loggedInUser = select(UserSelectors.getCurrentUser); + private userProfile = select(ProfileSelectors.getUserProfile); + + isUserLoading = select(ProfileSelectors.isUserProfileLoading); + resourceTabOptions = SEARCH_TAB_OPTIONS.filter((x) => x.value !== ResourceType.Agent); + + isMyProfile = computed(() => !this.route.snapshot.params['id']); + user = computed(() => (this.isMyProfile() ? this.loggedInUser() : this.userProfile())); + + ngOnInit(): void { + const userId = this.route.snapshot.params['id']; + const currentUser = this.loggedInUser(); + + if (userId) { + this.loadUserProfile(userId); + } else if (currentUser) { + this.setupMyProfile(currentUser); + } + } + + toProfileSettings(): void { + this.router.navigate(['settings/profile']); + } + + private loadUserProfile(userId: string): void { + this.actions + .fetchUserProfile(userId) + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => this.setSearchFilter()); + } + + private setupMyProfile(user: User): void { + this.actions.setUserProfile(user); + if (user?.iri) { + this.actions.setDefaultFilterValue('creator', user.iri); + } + } + + private setSearchFilter(): void { + const currentUser = this.user(); + if (currentUser?.iri) { + this.actions.setDefaultFilterValue('creator', currentUser.iri); + } + } +} From 6b9bb2016ac7f8ac5fe9dbc03fb9a0fa98b42ccc Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 17 Sep 2025 17:42:53 +0300 Subject: [PATCH 09/10] fix(profile): updated profile links --- src/app/app.routes.ts | 2 +- .../components/header/header.component.ts | 2 +- src/app/core/constants/nav-items.constant.ts | 2 +- src/app/core/store/user/user.actions.ts | 4 +- src/app/core/store/user/user.selectors.ts | 4 +- src/app/core/store/user/user.state.ts | 4 +- .../models/registry-json-api.model.ts | 15 +----- .../models/registry-moderation.model.ts | 2 +- .../profile-information.component.html | 51 ++----------------- .../profile-information.component.ts | 5 ++ src/app/features/profile/helpers/index.ts | 1 + .../profile/helpers/user-socials.helper.ts | 39 ++++++++++++++ .../social-form/social-form.component.html | 2 +- .../social-form/social-form.component.ts | 1 + .../components/social/social.component.ts | 9 ++-- .../profile-settings/constants/index.ts | 1 - .../helpers/social-comparison.helper.ts | 12 ++--- .../settings/profile-settings/models/index.ts | 1 - src/app/shared/constants/index.ts | 2 + .../constants/social-links.const.ts} | 17 ++++++- .../models/profile-settings-update.model.ts | 4 +- .../registration-node-json-api.model.ts | 4 +- src/app/shared/models/user/index.ts | 2 + .../models/user/social-link-view.model.ts | 5 ++ .../models/user/social-links.model.ts} | 6 ++- src/app/shared/models/user/social.model.ts | 2 +- src/app/shared/models/user/user.models.ts | 6 +-- src/assets/icons/socials/orcid.svg | 9 ++++ 28 files changed, 116 insertions(+), 98 deletions(-) create mode 100644 src/app/features/profile/helpers/index.ts create mode 100644 src/app/features/profile/helpers/user-socials.helper.ts rename src/app/{features/settings/profile-settings/constants/socials.ts => shared/constants/social-links.const.ts} (85%) create mode 100644 src/app/shared/models/user/social-link-view.model.ts rename src/app/{features/settings/profile-settings/models/social.model.ts => shared/models/user/social-links.model.ts} (76%) create mode 100644 src/assets/icons/socials/orcid.svg diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index fb3bfff07..f08ca7a23 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -107,7 +107,7 @@ export const routes: Routes = [ loadChildren: () => import('./features/registries/registries.routes').then((mod) => mod.registriesRoutes), }, { - path: 'my-profile', + path: 'profile', loadComponent: () => import('./features/profile/profile.component').then((mod) => mod.ProfileComponent), providers: [provideStates([ProfileState])], canActivate: [authGuard], diff --git a/src/app/core/components/header/header.component.ts b/src/app/core/components/header/header.component.ts index a599fcefd..52f04a1fd 100644 --- a/src/app/core/components/header/header.component.ts +++ b/src/app/core/components/header/header.component.ts @@ -29,7 +29,7 @@ export class HeaderComponent { items = [ { label: 'navigation.myProfile', - command: () => this.router.navigate(['my-profile']), + command: () => this.router.navigate(['profile']), }, { label: 'navigation.settings', command: () => this.router.navigate(['settings']) }, { diff --git a/src/app/core/constants/nav-items.constant.ts b/src/app/core/constants/nav-items.constant.ts index 5537cda8a..b5b1d2fc4 100644 --- a/src/app/core/constants/nav-items.constant.ts +++ b/src/app/core/constants/nav-items.constant.ts @@ -352,7 +352,7 @@ export const MENU_ITEMS: MenuItem[] = [ }, { id: 'my-profile', - routerLink: '/my-profile', + routerLink: '/profile', label: 'navigation.profile', icon: 'fas fa-user', visible: false, diff --git a/src/app/core/store/user/user.actions.ts b/src/app/core/store/user/user.actions.ts index b76a8b834..ca346fc2c 100644 --- a/src/app/core/store/user/user.actions.ts +++ b/src/app/core/store/user/user.actions.ts @@ -1,4 +1,4 @@ -import { Education, Employment, Social, User, UserSettings } from '@osf/shared/models'; +import { Education, Employment, SocialModel, User, UserSettings } from '@osf/shared/models'; export class GetCurrentUser { static readonly type = '[User] Get Current User'; @@ -36,7 +36,7 @@ export class UpdateProfileSettingsEducation { export class UpdateProfileSettingsSocialLinks { static readonly type = '[Profile Settings] Update Social Links'; - constructor(public payload: Partial[]) {} + constructor(public payload: Partial[]) {} } export class UpdateProfileSettingsUser { diff --git a/src/app/core/store/user/user.selectors.ts b/src/app/core/store/user/user.selectors.ts index 5aad4c852..096406d80 100644 --- a/src/app/core/store/user/user.selectors.ts +++ b/src/app/core/store/user/user.selectors.ts @@ -1,6 +1,6 @@ import { Selector } from '@ngxs/store'; -import { Education, Employment, Social, User, UserSettings } from '@osf/shared/models'; +import { Education, Employment, SocialModel, User, UserSettings } from '@osf/shared/models'; import { UserStateModel } from './user.model'; import { UserState } from './user.state'; @@ -54,7 +54,7 @@ export class UserSelectors { } @Selector([UserState]) - static getSocialLinks(state: UserStateModel): Social | undefined { + static getSocialLinks(state: UserStateModel): SocialModel | undefined { return state.currentUser.data?.social; } diff --git a/src/app/core/store/user/user.state.ts b/src/app/core/store/user/user.state.ts index 8404141ec..93d135ef6 100644 --- a/src/app/core/store/user/user.state.ts +++ b/src/app/core/store/user/user.state.ts @@ -8,7 +8,7 @@ import { inject, Injectable } from '@angular/core'; import { ProfileSettingsKey } from '@osf/shared/enums'; import { removeNullable } from '@osf/shared/helpers'; import { UserMapper } from '@osf/shared/mappers'; -import { Social, User } from '@osf/shared/models'; +import { SocialModel, User } from '@osf/shared/models'; import { UserService } from '../../services'; @@ -210,7 +210,7 @@ export class UserState { return; } - let social = {} as Partial; + let social = {} as Partial; payload.forEach((item) => { social = { diff --git a/src/app/features/moderation/models/registry-json-api.model.ts b/src/app/features/moderation/models/registry-json-api.model.ts index 0b47f96df..ebd568026 100644 --- a/src/app/features/moderation/models/registry-json-api.model.ts +++ b/src/app/features/moderation/models/registry-json-api.model.ts @@ -1,24 +1,13 @@ -import { RegistrationReviewStates, RevisionReviewStates } from '@osf/shared/enums'; -import { ResponseJsonApi } from '@osf/shared/models'; +import { RegistrationNodeAttributesJsonApi, ResponseJsonApi } from '@osf/shared/models'; export type RegistryResponseJsonApi = ResponseJsonApi; export interface RegistryDataJsonApi { id: string; - attributes: RegistryAttributesJsonApi; + attributes: RegistrationNodeAttributesJsonApi; embeds: RegistryEmbedsJsonApi; } -export interface RegistryAttributesJsonApi { - id: string; - title: string; - revision_state: RevisionReviewStates; - reviews_state: RegistrationReviewStates; - public: boolean; - embargoed: boolean; - embargo_end_date: string; -} - export interface RegistryEmbedsJsonApi { schema_responses: { data: { id: string }[]; diff --git a/src/app/features/moderation/models/registry-moderation.model.ts b/src/app/features/moderation/models/registry-moderation.model.ts index 9e47b8d81..1a5054ec0 100644 --- a/src/app/features/moderation/models/registry-moderation.model.ts +++ b/src/app/features/moderation/models/registry-moderation.model.ts @@ -9,7 +9,7 @@ export interface RegistryModeration { reviewsState: RegistrationReviewStates; public: boolean; embargoed: boolean; - embargoEndDate?: string; + embargoEndDate: string | null; actions: ReviewAction[]; revisionId?: string | null; } diff --git a/src/app/features/profile/components/profile-information/profile-information.component.html b/src/app/features/profile/components/profile-information/profile-information.component.html index 37308942a..4f99329ca 100644 --- a/src/app/features/profile/components/profile-information/profile-information.component.html +++ b/src/app/features/profile/components/profile-information/profile-information.component.html @@ -61,54 +61,9 @@

}
- @if (currentUser()?.social?.github) { - - github - - } - @if (currentUser()?.social?.scholar) { - - scholar - - } - @if (currentUser()?.social?.twitter) { - - x(twitter) - - } - @if (currentUser()?.social?.linkedIn) { - - linkedin - - } - @if (currentUser()?.social?.impactStory) { - - impactstory - - } - @if (currentUser()?.social?.baiduScholar) { - - baidu - - } - @if (currentUser()?.social?.researchGate) { - - researchGate - - } - @if (currentUser()?.social?.researcherId) { - - researchId - - } - @if (currentUser()?.social?.ssrn) { - - ssrn - - } - @if (currentUser()?.social?.academiaProfileID) { - - academia + @for (social of userSocials(); track social.alt) { + + }
diff --git a/src/app/features/profile/components/profile-information/profile-information.component.ts b/src/app/features/profile/components/profile-information/profile-information.component.ts index e1fbc0b7d..404d2d05e 100644 --- a/src/app/features/profile/components/profile-information/profile-information.component.ts +++ b/src/app/features/profile/components/profile-information/profile-information.component.ts @@ -7,9 +7,12 @@ import { ChangeDetectionStrategy, Component, computed, inject, input, output } f import { toSignal } from '@angular/core/rxjs-interop'; import { EducationHistoryComponent, EmploymentHistoryComponent } from '@osf/shared/components'; +import { SOCIAL_LINKS } from '@osf/shared/constants'; import { IS_MEDIUM } from '@osf/shared/helpers'; import { User } from '@osf/shared/models'; +import { mapUserSocials } from '../../helpers'; + @Component({ selector: 'osf-profile-information', imports: [Button, EmploymentHistoryComponent, EducationHistoryComponent, TranslatePipe, DatePipe, NgOptimizedImage], @@ -28,6 +31,8 @@ export class ProfileInformationComponent { () => this.currentUser()?.employment?.length || this.currentUser()?.education?.length ); + userSocials = computed(() => mapUserSocials(this.currentUser()?.social, SOCIAL_LINKS)); + toProfileSettings() { this.editProfile.emit(); } diff --git a/src/app/features/profile/helpers/index.ts b/src/app/features/profile/helpers/index.ts new file mode 100644 index 000000000..01a1e8a30 --- /dev/null +++ b/src/app/features/profile/helpers/index.ts @@ -0,0 +1 @@ +export * from './user-socials.helper'; diff --git a/src/app/features/profile/helpers/user-socials.helper.ts b/src/app/features/profile/helpers/user-socials.helper.ts new file mode 100644 index 000000000..e4fd979f1 --- /dev/null +++ b/src/app/features/profile/helpers/user-socials.helper.ts @@ -0,0 +1,39 @@ +import { SocialLinksModel, SocialLinkViewModel, SocialModel } from '@osf/shared/models'; + +export function mapUserSocials( + socialData: SocialModel | undefined, + socialLinks: SocialLinksModel[] +): SocialLinkViewModel[] { + if (!socialData) { + return []; + } + + return socialLinks.reduce((acc, social) => { + const socialValue = socialData[social.key]; + + if (!socialValue || (Array.isArray(socialValue) && socialValue.length === 0)) { + return acc; + } + + let url; + if (social.linkedField) { + const linkedValue = socialData[social.linkedField.key]; + if (linkedValue) { + url = `${social.address}${socialValue}${social.linkedField.address}${linkedValue}`; + } + } else { + const value = Array.isArray(socialValue) ? socialValue[0] : socialValue; + url = social.address + value; + } + + if (url && social.key !== 'profileWebsites') { + acc.push({ + url, + icon: `assets/icons/socials/${social.icon}`, + alt: social.label, + }); + } + + return acc; + }, []); +} diff --git a/src/app/features/settings/profile-settings/components/social-form/social-form.component.html b/src/app/features/settings/profile-settings/components/social-form/social-form.component.html index 878722f7f..b322b464c 100644 --- a/src/app/features/settings/profile-settings/components/social-form/social-form.component.html +++ b/src/app/features/settings/profile-settings/components/social-form/social-form.component.html @@ -22,7 +22,7 @@

@if (hasLinkedField()) { - .academia.edu/ + {{ linkedDomain() }} !!this.socialOutput()?.linkedField); readonly linkedLabel = computed(() => this.socialOutput()?.linkedField?.label); + readonly linkedDomain = computed(() => this.socialOutput()?.linkedField?.address); readonly linkedPlaceholder = computed(() => this.socialOutput()?.linkedField?.placeholder); } diff --git a/src/app/features/settings/profile-settings/components/social/social.component.ts b/src/app/features/settings/profile-settings/components/social/social.component.ts index b98815a4e..bb6c24ad7 100644 --- a/src/app/features/settings/profile-settings/components/social/social.component.ts +++ b/src/app/features/settings/profile-settings/components/social/social.component.ts @@ -17,12 +17,11 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { FormArray, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms'; import { UpdateProfileSettingsSocialLinks, UserSelectors } from '@osf/core/store/user'; -import { Social } from '@osf/shared/models'; +import { SOCIAL_LINKS } from '@osf/shared/constants'; +import { SocialLinksForm, SocialModel } from '@osf/shared/models'; import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services'; -import { SOCIALS } from '../../constants/socials'; import { hasSocialLinkChanges, mapSocialLinkToPayload } from '../../helpers'; -import { SocialLinksForm } from '../../models'; import { SocialFormComponent } from '../social-form/social-form.component'; @Component({ @@ -42,7 +41,7 @@ export class SocialComponent { private readonly cd = inject(ChangeDetectorRef); private readonly fb = inject(FormBuilder); - private readonly socials = SOCIALS; + private readonly socials = SOCIAL_LINKS; readonly actions = createDispatchMap({ updateProfileSettingsSocialLinks: UpdateProfileSettingsSocialLinks }); readonly socialLinks = select(UserSelectors.getSocialLinks); @@ -80,7 +79,7 @@ export class SocialComponent { } const links = this.socialLinksForm.value.links as SocialLinksForm[]; - const mappedLinks = links.map((link) => mapSocialLinkToPayload(link)) satisfies Partial[]; + const mappedLinks = links.map((link) => mapSocialLinkToPayload(link)) satisfies Partial[]; this.loaderService.show(); this.actions diff --git a/src/app/features/settings/profile-settings/constants/index.ts b/src/app/features/settings/profile-settings/constants/index.ts index 90c8b6c16..1b98ec922 100644 --- a/src/app/features/settings/profile-settings/constants/index.ts +++ b/src/app/features/settings/profile-settings/constants/index.ts @@ -1,3 +1,2 @@ export * from './date-limits.const'; export * from './profile-settings-tab-options.const'; -export * from './socials'; diff --git a/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts b/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts index fc82bf595..174625d82 100644 --- a/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts +++ b/src/app/features/settings/profile-settings/helpers/social-comparison.helper.ts @@ -1,6 +1,4 @@ -import { Social } from '@osf/shared/models'; - -import { SOCIAL_KEYS, SocialLinksForm, SocialLinksKeys, SocialLinksModel } from '../models'; +import { SOCIAL_KEYS, SocialLinksForm, SocialLinksKeys, SocialLinksModel, SocialModel } from '@osf/shared/models'; export function normalizeValue(value: unknown, key: SocialLinksKeys): unknown { if (SOCIAL_KEYS.includes(key)) { @@ -9,7 +7,7 @@ export function normalizeValue(value: unknown, key: SocialLinksKeys): unknown { return value; } -export function mapSocialLinkToPayload(link: SocialLinksForm): Partial { +export function mapSocialLinkToPayload(link: SocialLinksForm): Partial { const key = link.socialOutput.key as SocialLinksKeys; const linkedKey = link.socialOutput.linkedField?.key as SocialLinksKeys; @@ -19,7 +17,7 @@ export function mapSocialLinkToPayload(link: SocialLinksForm): Partial { : [link.webAddress].filter(Boolean) : link.webAddress; - const result: Partial = { [key]: value }; + const result: Partial = { [key]: value }; if (linkedKey) { const typeSafeResult = result as Record; @@ -31,7 +29,7 @@ export function mapSocialLinkToPayload(link: SocialLinksForm): Partial { export function hasSocialLinkChanges( link: SocialLinksForm, - initialSocialLinks: Social, + initialSocialLinks: SocialModel, socialIndex: number, socials: SocialLinksModel[] ): boolean { @@ -41,7 +39,7 @@ export function hasSocialLinkChanges( const mappedLink = mapSocialLinkToPayload(link); const { key, linkedField } = social; - const hasChanged = (currentKey: keyof Social) => { + const hasChanged = (currentKey: keyof SocialModel) => { const current = mappedLink[currentKey]; const initial = normalizeValue(initialSocialLinks[currentKey], currentKey); diff --git a/src/app/features/settings/profile-settings/models/index.ts b/src/app/features/settings/profile-settings/models/index.ts index 3118024c6..67a239ca7 100644 --- a/src/app/features/settings/profile-settings/models/index.ts +++ b/src/app/features/settings/profile-settings/models/index.ts @@ -1,5 +1,4 @@ export * from './education-form.model'; export * from './employment-form.model'; export * from './name-form.model'; -export * from './social.model'; export * from './user-social-link.model'; diff --git a/src/app/shared/constants/index.ts b/src/app/shared/constants/index.ts index e8aadc9a5..2b610609d 100644 --- a/src/app/shared/constants/index.ts +++ b/src/app/shared/constants/index.ts @@ -18,5 +18,7 @@ export * from './scientists.const'; export * from './search-sort-options.const'; export * from './search-tab-options.const'; export * from './search-tutorial-steps.const'; +export * from './social-links.const'; +export * from './social-links.const'; export * from './social-share.config'; export * from './sort-options.const'; diff --git a/src/app/features/settings/profile-settings/constants/socials.ts b/src/app/shared/constants/social-links.const.ts similarity index 85% rename from src/app/features/settings/profile-settings/constants/socials.ts rename to src/app/shared/constants/social-links.const.ts index 385e0fbe5..d97563bc6 100644 --- a/src/app/features/settings/profile-settings/constants/socials.ts +++ b/src/app/shared/constants/social-links.const.ts @@ -1,12 +1,13 @@ import { SocialLinksModel } from '../models'; -export const SOCIALS: SocialLinksModel[] = [ +export const SOCIAL_LINKS: SocialLinksModel[] = [ { id: 0, label: 'settings.profileSettings.social.labels.researcherId', address: 'http://researchers.com/rid/', placeholder: 'x-xxxx-xxxx', key: 'researcherId', + icon: 'researcherID.png', }, { id: 1, @@ -14,6 +15,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'http://orcid.org/', placeholder: 'xxxx-xxxx-xxxx', key: 'orcid', + icon: 'orcid.svg', }, { id: 2, @@ -21,13 +23,15 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'https://linkedin.com/', placeholder: 'in/userID, profie/view?profileID, or pub/pubID', key: 'linkedIn', + icon: 'linkedin.svg', }, { id: 3, label: 'settings.profileSettings.social.labels.twitter', - address: '@', + address: 'https://x.com/', placeholder: 'twitterhandle', key: 'twitter', + icon: 'x.svg', }, { id: 4, @@ -35,6 +39,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'https://github.com/', placeholder: 'username', key: 'github', + icon: 'github.svg', }, { id: 5, @@ -42,6 +47,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'https://impactstory.org/u/', placeholder: 'profileID', key: 'impactStory', + icon: 'impactStory.svg', }, { id: 6, @@ -49,6 +55,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'http://scholar.google.com/citations?user=', placeholder: 'profileID', key: 'scholar', + icon: 'scholar.svg', }, { id: 7, @@ -56,6 +63,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'https://researchgate.net/profile/', placeholder: 'profileID', key: 'researchGate', + icon: 'researchGate.svg', }, { id: 8, @@ -63,6 +71,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'http://xueshu.baidu.com/scholarID/', placeholder: 'profileID', key: 'baiduScholar', + icon: 'baiduScholar.png', }, { id: 9, @@ -70,6 +79,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'http://papers.ssrn.com/sol3/cf_dev/AbsByAuth.cfm?per_id=', placeholder: 'profileID', key: 'ssrn', + icon: 'ssrn.svg', }, { id: 10, @@ -77,6 +87,7 @@ export const SOCIALS: SocialLinksModel[] = [ address: '', placeholder: 'https://yourwebsite.com', key: 'profileWebsites', + icon: '', }, { id: 11, @@ -84,10 +95,12 @@ export const SOCIALS: SocialLinksModel[] = [ address: 'https://', placeholder: 'institution', key: 'academiaInstitution', + icon: 'academia.svg', linkedField: { key: 'academiaProfileID', label: 'settings.profileSettings.social.labels.academiaProfileId', placeholder: 'profileId', + address: '.academia.edu/', }, }, ]; diff --git a/src/app/shared/models/profile-settings-update.model.ts b/src/app/shared/models/profile-settings-update.model.ts index a9a758472..b2deafe4e 100644 --- a/src/app/shared/models/profile-settings-update.model.ts +++ b/src/app/shared/models/profile-settings-update.model.ts @@ -1,3 +1,3 @@ -import { Education, Employment, Social, User } from './user'; +import { Education, Employment, SocialModel, User } from './user'; -export type ProfileSettingsUpdate = Partial[] | Partial[] | Partial | Partial; +export type ProfileSettingsUpdate = Partial[] | Partial[] | Partial | Partial; diff --git a/src/app/shared/models/registration/registration-node-json-api.model.ts b/src/app/shared/models/registration/registration-node-json-api.model.ts index 7ca3eb716..d4796801d 100644 --- a/src/app/shared/models/registration/registration-node-json-api.model.ts +++ b/src/app/shared/models/registration/registration-node-json-api.model.ts @@ -1,4 +1,4 @@ -import { RegistrationReviewStates } from '@osf/shared/enums'; +import { RegistrationReviewStates, RevisionReviewStates } from '@osf/shared/enums'; import { BaseNodeAttributesJsonApi } from '../nodes'; @@ -25,7 +25,7 @@ export interface RegistrationNodeAttributesJsonApi extends BaseNodeAttributesJso registration_responses: RegistrationResponses; registration_supplement: string; reviews_state: RegistrationReviewStates; - revision_state: string; + revision_state: RevisionReviewStates; withdrawal_justification: string | null; withdrawn: boolean; } diff --git a/src/app/shared/models/user/index.ts b/src/app/shared/models/user/index.ts index f80fe3921..f937689f8 100644 --- a/src/app/shared/models/user/index.ts +++ b/src/app/shared/models/user/index.ts @@ -1,4 +1,6 @@ export * from './education.model'; export * from './employment.model'; export * from './social.model'; +export * from './social-link-view.model'; +export * from './social-links.model'; export * from './user.models'; diff --git a/src/app/shared/models/user/social-link-view.model.ts b/src/app/shared/models/user/social-link-view.model.ts new file mode 100644 index 000000000..78f157145 --- /dev/null +++ b/src/app/shared/models/user/social-link-view.model.ts @@ -0,0 +1,5 @@ +export interface SocialLinkViewModel { + url: string; + icon: string; + alt: string; +} diff --git a/src/app/features/settings/profile-settings/models/social.model.ts b/src/app/shared/models/user/social-links.model.ts similarity index 76% rename from src/app/features/settings/profile-settings/models/social.model.ts rename to src/app/shared/models/user/social-links.model.ts index fd78d72c5..f8ffb3ba3 100644 --- a/src/app/features/settings/profile-settings/models/social.model.ts +++ b/src/app/shared/models/user/social-links.model.ts @@ -1,6 +1,6 @@ -import { Social } from '@osf/shared/models'; +import { SocialModel } from '@osf/shared/models'; -export type SocialLinksKeys = keyof Social; +export type SocialLinksKeys = keyof SocialModel; export const SOCIAL_KEYS: SocialLinksKeys[] = ['github', 'twitter', 'linkedIn', 'profileWebsites']; @@ -10,10 +10,12 @@ export interface SocialLinksModel { address: string; placeholder: string; key: SocialLinksKeys; + icon: string; linkedField?: { key: SocialLinksKeys; label: string; placeholder: string; + address: string; }; } diff --git a/src/app/shared/models/user/social.model.ts b/src/app/shared/models/user/social.model.ts index 7b61b9e1c..d4304fb3b 100644 --- a/src/app/shared/models/user/social.model.ts +++ b/src/app/shared/models/user/social.model.ts @@ -1,4 +1,4 @@ -export interface Social { +export interface SocialModel { ssrn: string; orcid: string; github: string[]; diff --git a/src/app/shared/models/user/user.models.ts b/src/app/shared/models/user/user.models.ts index 49bb58567..3667fa21f 100644 --- a/src/app/shared/models/user/user.models.ts +++ b/src/app/shared/models/user/user.models.ts @@ -2,7 +2,7 @@ import { JsonApiResponse } from '@shared/models'; import { Education } from './education.model'; import { Employment } from './employment.model'; -import { Social } from './social.model'; +import { SocialModel } from './social.model'; export type UserResponseJsonApi = JsonApiResponse; @@ -16,7 +16,7 @@ export interface User { suffix?: string; education: Education[]; employment: Employment[]; - social: Social; + social: SocialModel; dateRegistered: Date; link?: string; iri?: string; @@ -44,7 +44,7 @@ export interface UserDataJsonApi { education: Education[]; middle_names?: string; suffix?: string; - social: Social; + social: SocialModel; date_registered: string; allow_indexing?: boolean; can_view_reviews: boolean; diff --git a/src/assets/icons/socials/orcid.svg b/src/assets/icons/socials/orcid.svg new file mode 100644 index 000000000..6d2bd412a --- /dev/null +++ b/src/assets/icons/socials/orcid.svg @@ -0,0 +1,9 @@ + + + + + + + + + From b3c3e4df522c54b527321b9e06789c13d0cc25d1 Mon Sep 17 00:00:00 2001 From: nsemets Date: Wed, 17 Sep 2025 17:51:39 +0300 Subject: [PATCH 10/10] fix(profile): fixed styles --- .../profile-information/profile-information.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/profile/components/profile-information/profile-information.component.html b/src/app/features/profile/components/profile-information/profile-information.component.html index 4f99329ca..cf79c532d 100644 --- a/src/app/features/profile/components/profile-information/profile-information.component.html +++ b/src/app/features/profile/components/profile-information/profile-information.component.html @@ -21,7 +21,7 @@

{{ currentUser()?.fullName }}

-
+
@if (currentUser()?.social?.orcid) {