From b2e80f4bda88562e791e15eb3db39e81858c3a7b Mon Sep 17 00:00:00 2001 From: nsemets Date: Mon, 22 Sep 2025 15:10:18 +0300 Subject: [PATCH 1/2] fix(user-model): updated user model --- src/app/core/services/user.service.ts | 8 ++++---- src/app/core/store/user/user.actions.ts | 6 +++--- src/app/core/store/user/user.model.ts | 4 ++-- src/app/core/store/user/user.selectors.ts | 6 +++--- src/app/core/store/user/user.state.ts | 6 +++--- .../profile-information/profile-information.component.ts | 4 ++-- src/app/features/profile/profile.component.ts | 4 ++-- src/app/features/profile/store/profile.actions.ts | 4 ++-- src/app/features/profile/store/profile.model.ts | 4 ++-- src/app/features/profile/store/profile.selectors.ts | 4 ++-- .../account-settings/services/account-settings.service.ts | 6 +++--- .../citation-preview/citation-preview.component.ts | 4 ++-- .../profile-settings/components/name/name.component.ts | 6 +++--- .../profile-settings/helpers/name-comparison.helper.ts | 4 ++-- src/app/shared/mappers/user/user.mapper.ts | 8 ++++---- src/app/shared/mocks/data.mock.ts | 4 ++-- src/app/shared/models/profile-settings-update.model.ts | 8 ++++++-- src/app/shared/models/user/user.models.ts | 4 ++-- src/app/shared/pipes/citation-format.pipe.ts | 4 ++-- 19 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/app/core/services/user.service.ts b/src/app/core/services/user.service.ts index b4e15af1a..737e94823 100644 --- a/src/app/core/services/user.service.ts +++ b/src/app/core/services/user.service.ts @@ -8,11 +8,11 @@ import { UserMapper } from '@osf/shared/mappers'; import { JsonApiResponse, ProfileSettingsUpdate, - User, UserAcceptedTermsOfServiceJsonApi, UserData, UserDataJsonApi, UserDataResponseJsonApi, + UserModel, UserResponseJsonApi, UserSettings, UserSettingsGetResponse, @@ -30,7 +30,7 @@ export class UserService { return `${this.environment.apiDomainUrl}/v2`; } - getUserById(userId: string): Observable { + getUserById(userId: string): Observable { return this.jsonApiService .get(`${this.apiUrl}/users/${userId}/`) .pipe(map((response) => UserMapper.fromUserGetResponse(response.data))); @@ -56,7 +56,7 @@ export class UserService { .pipe(map((response) => UserMapper.fromUserSettingsGetResponse(response))); } - updateUserProfile(userId: string, key: string, data: ProfileSettingsUpdate): Observable { + updateUserProfile(userId: string, key: string, data: ProfileSettingsUpdate): Observable { const data_formatted = // eslint-disable-next-line no-prototype-builtins ProfileSettingsKey.User && data.hasOwnProperty('acceptedTermsOfService') @@ -71,7 +71,7 @@ export class UserService { .pipe(map((response) => UserMapper.fromUserGetResponse(response))); } - updateUserAcceptedTermsOfService(userId: string, data: UserAcceptedTermsOfServiceJsonApi): Observable { + updateUserAcceptedTermsOfService(userId: string, data: UserAcceptedTermsOfServiceJsonApi): Observable { return this.jsonApiService .patch(`${this.apiUrl}/users/${userId}/`, { data: { type: 'users', id: userId, attributes: data }, diff --git a/src/app/core/store/user/user.actions.ts b/src/app/core/store/user/user.actions.ts index ca346fc2c..3c49fc8a6 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, SocialModel, User, UserSettings } from '@osf/shared/models'; +import { Education, Employment, SocialModel, UserModel, UserSettings } from '@osf/shared/models'; export class GetCurrentUser { static readonly type = '[User] Get Current User'; @@ -6,7 +6,7 @@ export class GetCurrentUser { export class SetCurrentUser { static readonly type = '[User] Set Current User'; - constructor(public user: User) {} + constructor(public user: UserModel) {} } export class GetCurrentUserSettings { @@ -42,7 +42,7 @@ export class UpdateProfileSettingsSocialLinks { export class UpdateProfileSettingsUser { static readonly type = '[Profile Settings] Update User'; - constructor(public payload: Partial) {} + constructor(public payload: Partial) {} } export class AcceptTermsOfServiceByUser { diff --git a/src/app/core/store/user/user.model.ts b/src/app/core/store/user/user.model.ts index bdae49d6d..051da41af 100644 --- a/src/app/core/store/user/user.model.ts +++ b/src/app/core/store/user/user.model.ts @@ -1,7 +1,7 @@ -import { AsyncStateModel, User, UserSettings } from '@osf/shared/models'; +import { AsyncStateModel, UserModel, UserSettings } from '@osf/shared/models'; export interface UserStateModel { - currentUser: AsyncStateModel; + currentUser: AsyncStateModel; currentUserSettings: AsyncStateModel; activeFlags: string[]; } diff --git a/src/app/core/store/user/user.selectors.ts b/src/app/core/store/user/user.selectors.ts index 096406d80..4acdab20d 100644 --- a/src/app/core/store/user/user.selectors.ts +++ b/src/app/core/store/user/user.selectors.ts @@ -1,13 +1,13 @@ import { Selector } from '@ngxs/store'; -import { Education, Employment, SocialModel, User, UserSettings } from '@osf/shared/models'; +import { Education, Employment, SocialModel, UserModel, UserSettings } from '@osf/shared/models'; import { UserStateModel } from './user.model'; import { UserState } from './user.state'; export class UserSelectors { @Selector([UserState]) - static getCurrentUser(state: UserStateModel): User | null { + static getCurrentUser(state: UserStateModel): UserModel | null { return state.currentUser.data || localStorage.getItem('currentUser') ? JSON.parse(localStorage.getItem('currentUser')!) : null; @@ -39,7 +39,7 @@ export class UserSelectors { } @Selector([UserState]) - static getUserNames(state: UserStateModel): Partial | null { + static getUserNames(state: UserStateModel): Partial | null { return state.currentUser.data; } diff --git a/src/app/core/store/user/user.state.ts b/src/app/core/store/user/user.state.ts index 0c5e6a21e..d8cf3e728 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 { SocialModel, User } from '@osf/shared/models'; +import { SocialModel, UserModel } from '@osf/shared/models'; import { UserService } from '../../services'; @@ -242,13 +242,13 @@ export class UserState { return; } - const updatePayload: Partial = { + const updatePayload: Partial = { acceptedTermsOfService: true, }; const apiRequest = UserMapper.toAcceptedTermsOfServiceRequest(updatePayload); return this.userService.updateUserAcceptedTermsOfService(currentUser.id, apiRequest).pipe( - tap((response: User): void => { + tap((response: UserModel): void => { if (response.acceptedTermsOfService) { ctx.patchState({ currentUser: { 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 404d2d05e..bf0735973 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 @@ -9,7 +9,7 @@ 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 { UserModel } from '@osf/shared/models'; import { mapUserSocials } from '../../helpers'; @@ -21,7 +21,7 @@ import { mapUserSocials } from '../../helpers'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProfileInformationComponent { - currentUser = input(); + currentUser = input(); showEdit = input(false); editProfile = output(); diff --git a/src/app/features/profile/profile.component.ts b/src/app/features/profile/profile.component.ts index 577e5f215..142bc5f0d 100644 --- a/src/app/features/profile/profile.component.ts +++ b/src/app/features/profile/profile.component.ts @@ -8,7 +8,7 @@ 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 { UserModel } from '@osf/shared/models'; import { SetDefaultFilterValue } from '@osf/shared/stores/global-search'; import { ProfileInformationComponent } from './components'; @@ -62,7 +62,7 @@ export class ProfileComponent implements OnInit { .subscribe(() => this.setSearchFilter()); } - private setupMyProfile(user: User): void { + private setupMyProfile(user: UserModel): void { this.actions.setUserProfile(user); if (user?.iri) { this.actions.setDefaultFilterValue('creator,isContainedBy.creator', user.iri); diff --git a/src/app/features/profile/store/profile.actions.ts b/src/app/features/profile/store/profile.actions.ts index a21cfe687..f6598603c 100644 --- a/src/app/features/profile/store/profile.actions.ts +++ b/src/app/features/profile/store/profile.actions.ts @@ -1,4 +1,4 @@ -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; export class FetchUserProfile { static readonly type = '[Profile] Fetch User Profile'; @@ -9,5 +9,5 @@ export class FetchUserProfile { export class SetUserProfile { static readonly type = '[Profile] Set User Profile'; - constructor(public userProfile: User) {} + constructor(public userProfile: UserModel) {} } diff --git a/src/app/features/profile/store/profile.model.ts b/src/app/features/profile/store/profile.model.ts index 250784c0f..6533a0323 100644 --- a/src/app/features/profile/store/profile.model.ts +++ b/src/app/features/profile/store/profile.model.ts @@ -1,7 +1,7 @@ -import { AsyncStateModel, User } from '@osf/shared/models'; +import { AsyncStateModel, UserModel } from '@osf/shared/models'; export interface ProfileStateModel { - userProfile: AsyncStateModel; + userProfile: AsyncStateModel; } export const PROFILE_STATE_DEFAULTS: ProfileStateModel = { diff --git a/src/app/features/profile/store/profile.selectors.ts b/src/app/features/profile/store/profile.selectors.ts index 07b1b6c83..f35eba217 100644 --- a/src/app/features/profile/store/profile.selectors.ts +++ b/src/app/features/profile/store/profile.selectors.ts @@ -1,13 +1,13 @@ import { Selector } from '@ngxs/store'; -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { ProfileStateModel } from './profile.model'; import { ProfileState } from '.'; export class ProfileSelectors { @Selector([ProfileState]) - static getUserProfile(state: ProfileStateModel): User | null { + static getUserProfile(state: ProfileStateModel): UserModel | null { return state.userProfile.data; } diff --git a/src/app/features/settings/account-settings/services/account-settings.service.ts b/src/app/features/settings/account-settings/services/account-settings.service.ts index 20e94078f..c94279688 100644 --- a/src/app/features/settings/account-settings/services/account-settings.service.ts +++ b/src/app/features/settings/account-settings/services/account-settings.service.ts @@ -4,7 +4,7 @@ import { inject, Injectable } from '@angular/core'; import { ENVIRONMENT } from '@core/provider/environment.provider'; import { UserMapper } from '@osf/shared/mappers'; -import { JsonApiResponse, User, UserDataJsonApi } from '@osf/shared/models'; +import { JsonApiResponse, UserDataJsonApi, UserModel } from '@osf/shared/models'; import { JsonApiService } from '@osf/shared/services'; import { MapAccountSettings, MapExternalIdentities } from '../mappers'; @@ -26,7 +26,7 @@ export class AccountSettingsService { return `${this.environment.apiDomainUrl}/v2`; } - updateLocation(userId: string, locationId: string): Observable { + updateLocation(userId: string, locationId: string): Observable { const body = { data: { id: userId, @@ -48,7 +48,7 @@ export class AccountSettingsService { .pipe(map((user) => UserMapper.fromUserGetResponse(user))); } - updateIndexing(userId: string, allowIndexing: boolean): Observable { + updateIndexing(userId: string, allowIndexing: boolean): Observable { const body = { data: { id: userId, diff --git a/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.ts b/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.ts index 2f8555331..0bd778274 100644 --- a/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.ts +++ b/src/app/features/settings/profile-settings/components/citation-preview/citation-preview.component.ts @@ -2,7 +2,7 @@ import { TranslatePipe } from '@ngx-translate/core'; import { ChangeDetectionStrategy, Component, input } from '@angular/core'; -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { CitationFormatPipe } from '@osf/shared/pipes'; @Component({ @@ -13,5 +13,5 @@ import { CitationFormatPipe } from '@osf/shared/pipes'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class CitationPreviewComponent { - currentUser = input.required>(); + currentUser = input.required>(); } diff --git a/src/app/features/settings/profile-settings/components/name/name.component.ts b/src/app/features/settings/profile-settings/components/name/name.component.ts index 5d75a5d01..5f299caef 100644 --- a/src/app/features/settings/profile-settings/components/name/name.component.ts +++ b/src/app/features/settings/profile-settings/components/name/name.component.ts @@ -10,7 +10,7 @@ import { FormBuilder } from '@angular/forms'; import { UpdateProfileSettingsUser, UserSelectors } from '@osf/core/store/user'; import { CustomValidators } from '@osf/shared/helpers'; -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { CustomConfirmationService, LoaderService, ToastService } from '@osf/shared/services'; import { hasNameChanges } from '../../helpers'; @@ -35,7 +35,7 @@ export class NameComponent { readonly actions = createDispatchMap({ updateProfileSettingsUser: UpdateProfileSettingsUser }); readonly currentUser = select(UserSelectors.getUserNames); - readonly previewUser = signal>({}); + readonly previewUser = signal>({}); readonly fb = inject(FormBuilder); readonly form = this.fb.group({ @@ -110,7 +110,7 @@ export class NameComponent { return hasNameChanges(this.form.controls, user); } - private updateForm(user: Partial) { + private updateForm(user: Partial) { this.form.patchValue({ fullName: user.fullName, givenName: user.givenName, diff --git a/src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts b/src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts index 05cd51977..cfb982861 100644 --- a/src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts +++ b/src/app/features/settings/profile-settings/helpers/name-comparison.helper.ts @@ -1,9 +1,9 @@ import { findChangedFields } from '@osf/shared/helpers'; -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { NameForm } from '../models'; -export function hasNameChanges(formValue: NameForm, initialUser: Partial): boolean { +export function hasNameChanges(formValue: NameForm, initialUser: Partial): boolean { const currentValues = { fullName: formValue.fullName.value, givenName: formValue.givenName.value, diff --git a/src/app/shared/mappers/user/user.mapper.ts b/src/app/shared/mappers/user/user.mapper.ts index f26a27793..ce9bea756 100644 --- a/src/app/shared/mappers/user/user.mapper.ts +++ b/src/app/shared/mappers/user/user.mapper.ts @@ -1,9 +1,9 @@ import { - User, UserAcceptedTermsOfServiceJsonApi, UserData, UserDataJsonApi, UserDataResponseJsonApi, + UserModel, UserNamesJsonApi, UserSettings, UserSettingsGetResponse, @@ -18,7 +18,7 @@ export class UserMapper { }; } - static fromUserGetResponse(user: UserDataJsonApi): User { + static fromUserGetResponse(user: UserDataJsonApi): UserModel { return { id: user.id, fullName: user.attributes.full_name, @@ -60,7 +60,7 @@ export class UserMapper { }; } - static toNamesRequest(name: Partial): UserNamesJsonApi { + static toNamesRequest(name: Partial): UserNamesJsonApi { return { full_name: name.fullName ?? '', given_name: name.givenName ?? '', @@ -70,7 +70,7 @@ export class UserMapper { }; } - static toAcceptedTermsOfServiceRequest(name: Partial): UserAcceptedTermsOfServiceJsonApi { + static toAcceptedTermsOfServiceRequest(name: Partial): UserAcceptedTermsOfServiceJsonApi { return { accepted_terms_of_service: name.acceptedTermsOfService ?? false, }; diff --git a/src/app/shared/mocks/data.mock.ts b/src/app/shared/mocks/data.mock.ts index 4450e0d60..342e0127c 100644 --- a/src/app/shared/mocks/data.mock.ts +++ b/src/app/shared/mocks/data.mock.ts @@ -1,7 +1,7 @@ -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { UserRelatedCounts } from '@shared/models'; -export const MOCK_USER: User = { +export const MOCK_USER: UserModel = { iri: '', id: '1', fullName: 'John Doe', diff --git a/src/app/shared/models/profile-settings-update.model.ts b/src/app/shared/models/profile-settings-update.model.ts index b2deafe4e..df4068c77 100644 --- a/src/app/shared/models/profile-settings-update.model.ts +++ b/src/app/shared/models/profile-settings-update.model.ts @@ -1,3 +1,7 @@ -import { Education, Employment, SocialModel, User } from './user'; +import { Education, Employment, SocialModel, UserModel } from './user'; -export type ProfileSettingsUpdate = Partial[] | Partial[] | Partial | Partial; +export type ProfileSettingsUpdate = + | Partial[] + | Partial[] + | Partial + | Partial; diff --git a/src/app/shared/models/user/user.models.ts b/src/app/shared/models/user/user.models.ts index 3667fa21f..516186326 100644 --- a/src/app/shared/models/user/user.models.ts +++ b/src/app/shared/models/user/user.models.ts @@ -6,7 +6,7 @@ import { SocialModel } from './social.model'; export type UserResponseJsonApi = JsonApiResponse; -export interface User { +export interface UserModel { id: string; fullName: string; givenName: string; @@ -103,7 +103,7 @@ export interface UserDataResponseJsonApi { export interface UserData { activeFlags: string[]; - currentUser: User | null; + currentUser: UserModel | null; } export interface UserAcceptedTermsOfServiceJsonApi { diff --git a/src/app/shared/pipes/citation-format.pipe.ts b/src/app/shared/pipes/citation-format.pipe.ts index aa551475a..2be2ecfa7 100644 --- a/src/app/shared/pipes/citation-format.pipe.ts +++ b/src/app/shared/pipes/citation-format.pipe.ts @@ -1,6 +1,6 @@ import { Pipe, PipeTransform } from '@angular/core'; -import { User } from '@osf/shared/models'; +import { UserModel } from '@osf/shared/models'; import { GENERATIONAL_SUFFIXES, ORDINAL_SUFFIXES } from '../constants/citation-suffix.const'; @@ -8,7 +8,7 @@ import { GENERATIONAL_SUFFIXES, ORDINAL_SUFFIXES } from '../constants/citation-s name: 'citationFormat', }) export class CitationFormatPipe implements PipeTransform { - transform(user: Partial | null | undefined, format: 'apa' | 'mla' = 'apa'): string { + transform(user: Partial | null | undefined, format: 'apa' | 'mla' = 'apa'): string { if (!user) return ''; const familyName = user.familyName ?? ''; From 47b03083058b6fc0f1af652c9f842a2b4fdf30f4 Mon Sep 17 00:00:00 2001 From: nsemets Date: Mon, 22 Sep 2025 18:27:14 +0300 Subject: [PATCH 2/2] fix(styles): fixed some styles --- .../cookie-consent-banner.component.html | 6 +-- .../resource-card.component.html | 17 ++++---- .../resource-card.component.scss | 40 ++----------------- .../resource-card/resource-card.component.ts | 6 ++- .../wiki/wiki-list/wiki-list.component.ts | 33 +++++++-------- 5 files changed, 37 insertions(+), 65 deletions(-) diff --git a/src/app/core/components/osf-banners/cookie-consent-banner/cookie-consent-banner.component.html b/src/app/core/components/osf-banners/cookie-consent-banner/cookie-consent-banner.component.html index 5a5fa4692..7cd8bf69e 100644 --- a/src/app/core/components/osf-banners/cookie-consent-banner/cookie-consent-banner.component.html +++ b/src/app/core/components/osf-banners/cookie-consent-banner/cookie-consent-banner.component.html @@ -1,4 +1,4 @@ -@if (this.displayBanner()) { +@if (displayBanner()) {