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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bun.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"": {
"name": "osf",
"dependencies": {
"@angular/animations": "^19.2.0",
"@angular/cdk": "^19.2.1",
"@angular/cli": "^19.2.0",
"@angular/common": "^19.2.0",
Expand Down
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = tseslint.config(
],
processor: angular.processInlineTemplates,
rules: {
"@typescript-eslint/no-unused-vars": "warn",
"@angular-eslint/directive-selector": [
"error",
{
Expand Down
8 changes: 5 additions & 3 deletions src/app/core/constants/ngxs-states.constant.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { AuthState } from '@core/store/auth';
import { UserState } from '@core/store/user';
import { SearchState } from '@osf/features/search/store';
import { ProfileSettingsState } from '@osf/features/settings/profile-settings/profile-settings.state';
import { DeveloperAppsState } from '@osf/features/settings/developer-apps/store';
import { TokensState } from '@osf/features/settings/tokens/store';
import { AddonsState } from '@osf/features/settings/addons/store';
import { UserState } from '@core/store/user';
import { MyProjectsState } from '@osf/features/my-projects/store';
import { SearchState } from '@osf/features/search/store';
import { InstitutionsState } from '@osf/features/institutions/store';
import { DeveloperAppsState } from '@osf/features/settings/developer-apps/store';

export const STATES = [
AuthState,
Expand All @@ -15,5 +16,6 @@ export const STATES = [
SearchState,
MyProjectsState,
InstitutionsState,
ProfileSettingsState,
DeveloperAppsState,
];
6 changes: 6 additions & 0 deletions src/app/core/services/json-api/json-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export class JsonApiService {
.pipe(map((response) => response.data));
}

put<T>(url: string, body: unknown): Observable<T> {
return this.http
.put<JsonApiResponse<T, null>>(url, body, { headers: this.#headers })
.pipe(map((response) => response.data));
}

delete(url: string): Observable<void> {
return this.http.delete<void>(url, { headers: this.#headers });
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,21 @@
import { Employment } from '@osf/features/settings/profile-settings/employment/employment.entities';
import { Education } from '@osf/features/settings/profile-settings/education/educations.entities';
import { Social } from '@osf/features/settings/profile-settings/social/social.entities';

export interface UserUS {
id: string;
type: string;
attributes: {
full_name: string;
given_name: string;
family_name: string;
email: string;
email?: string;
employment: Employment[];
education: Education[];
middle_names?: string;
suffix?: string;
social: Social;
date_registered: string;
social: {
orcid: string;
github: string;
scholar: string;
twitter: string;
linkedIn: string;
impactStory: string;
researcherId: string;
};
employment: {
title: string;
endYear: number;
ongoing: boolean;
endMonth: number;
startYear: number;
department: string;
startMonth: number;
institution: string;
}[];
education: {
degree: string;
department: string;
institution: string;
startYear: number;
startMonth: number;
endYear: number;
endMonth: number;
ongoing: boolean;
}[];
};
relationships: Record<string, unknown>;
links: {
Expand Down
26 changes: 5 additions & 21 deletions src/app/core/services/mappers/users/users.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,15 @@ export function mapUserUStoUser(user: UserUS): User {
id: user.id,
fullName: user.attributes.full_name,
givenName: user.attributes.given_name,
middleNames: user.attributes.middle_names,
suffix: user.attributes.suffix,
familyName: user.attributes.family_name,
email: user.attributes.email,
dateRegistered: new Date(user.attributes.date_registered),
link: user.links.html,
education: user.attributes.education,
employment: user.attributes.employment,
iri: user.links.iri,
socials: user.attributes.social,
employment: user.attributes.employment?.map((emp) => ({
title: emp.title,
department: emp.department,
institution: emp.institution,
startDate: new Date(emp.startYear, emp.startMonth - 1),
endDate: emp.ongoing
? new Date()
: new Date(emp.endYear, emp.endMonth - 1),
ongoing: emp.ongoing,
})),
education: user.attributes.education?.map((edu) => ({
degree: edu.degree,
department: edu.department,
institution: edu.institution,
startDate: new Date(edu.startYear, edu.startMonth - 1),
endDate: edu.ongoing
? new Date()
: new Date(edu.endYear, edu.endMonth - 1),
ongoing: edu.ongoing,
})),
social: user.attributes.social,
};
}
25 changes: 9 additions & 16 deletions src/app/core/services/user/user.entity.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { Education } from '@osf/features/settings/profile-settings/education/educations.entities';
import { Employment } from '@osf/features/settings/profile-settings/employment/employment.entities';
import { Social } from '@osf/features/settings/profile-settings/social/social.entities';

export interface User {
id: string;
fullName: string;
givenName: string;
familyName: string;
email?: string;
middleNames?: string;
suffix?: string;
education: Education[];
employment: Employment[];
social: Social;
dateRegistered: Date;
link?: string;
iri?: string;
Expand All @@ -16,20 +25,4 @@ export interface User {
impactStory?: string;
researcherId?: string;
};
employment?: {
title: string;
department: string;
institution: string;
startDate: Date;
endDate: Date;
ongoing: boolean;
}[];
education?: {
degree: string;
department: string;
institution: string;
startDate: Date;
endDate: Date;
ongoing: boolean;
}[];
}
20 changes: 20 additions & 0 deletions src/app/core/store/user/user.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,30 @@ import { Selector } from '@ngxs/store';
import { UserStateModel } from '@core/store/user/user.models';
import { User } from '@core/services/user/user.entity';
import { UserState } from '@core/store/user/user.state';
import { ProfileSettingsStateModel } from '@osf/features/settings/profile-settings/profile-settings.entities';
import { Social } from '@osf/features/settings/profile-settings/social/social.entities';

export class UserSelectors {
@Selector([UserState])
static getCurrentUser(state: UserStateModel): User | null {
return state.currentUser;
}

@Selector([UserState])
static getProfileSettings(state: UserStateModel): ProfileSettingsStateModel {
return {
education: state.currentUser?.education ?? [],
employment: state.currentUser?.employment ?? [],
social: state.currentUser?.social ?? ({} as Social),
user: {
middleNames: state.currentUser?.middleNames ?? '',
suffix: state.currentUser?.suffix ?? '',
id: state.currentUser?.id ?? '',
fullName: state.currentUser?.fullName ?? '',
email: state.currentUser?.email ?? '',
givenName: state.currentUser?.givenName ?? '',
familyName: state.currentUser?.familyName ?? '',
},
} satisfies ProfileSettingsStateModel;
}
}
2 changes: 2 additions & 0 deletions src/app/core/store/user/user.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { UserStateModel } from './user.models';
import { GetCurrentUser, SetCurrentUser } from './user.actions';
import { UserService } from '@core/services/user/user.service';
import { tap } from 'rxjs';
import { SetupProfileSettings } from '@osf/features/settings/profile-settings/profile-settings.actions';

@State<UserStateModel>({
name: 'user',
Expand All @@ -20,6 +21,7 @@ export class UserState {
return this.userService.getCurrentUser().pipe(
tap((user) => {
ctx.dispatch(new SetCurrentUser(user));
ctx.dispatch(new SetupProfileSettings());
}),
);
}
Expand Down
16 changes: 8 additions & 8 deletions src/app/features/my-profile/my-profile.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ <h2 class="mb-3">Employment</h2>
<div class="title-date">
<p>{{ employment.institution }}</p>
<p class="font-normal ml-auto mr-5">
{{ employment.startDate | date: "MMM yyyy" }} -
{{ employment.endDate | date: "MMM yyyy" }}
<!-- {{ employment.startDate | date: "MMM yyyy" }} - -->
<!-- {{ employment.endDate | date: "MMM yyyy" }}-->
</p>
</div>
</p-accordion-header>
Expand All @@ -123,12 +123,12 @@ <h2 class="mb-3">Education</h2>
<div class="title-date">
<p>{{ education.institution }}</p>
<p class="font-normal ml-auto mr-5">
{{ education.startDate | date: "MMM yyyy" }} -
@if (education.ongoing) {
ongoing
} @else {
{{ education.endDate | date: "MMM yyyy" }}
}
<!-- {{ education.startDate | date: "MMM yyyy" }} - -->
<!-- @if (education.ongoing) {-->
<!-- ongoing-->
<!-- } @else {-->
<!-- {{ education.endDate | date: "MMM yyyy" }}-->
<!-- }-->
</p>
</div>
</p-accordion-header>
Expand Down
2 changes: 2 additions & 0 deletions src/app/features/my-profile/my-profile.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ChangeDetectionStrategy,
Component,
computed,
effect,
inject,
OnDestroy,
Expand Down Expand Up @@ -43,6 +44,7 @@ export class MyProfileComponent implements OnDestroy {
readonly #store = inject(Store);
readonly #router = inject(Router);
readonly currentUser = this.#store.selectSignal(UserSelectors.getCurrentUser);

readonly isMobile = toSignal(inject(IS_XSMALL));

protected searchValue = signal('');
Expand Down
14 changes: 13 additions & 1 deletion src/app/features/settings/profile-settings/data.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,74 @@
export const socials = [
import { SocialLinksEntity } from '@osf/features/settings/profile-settings/social/social.entities';

export const socials: SocialLinksEntity[] = [
{
id: 0,
label: 'ResearcherID',
address: 'http://researchers.com/rid/',
placeholder: 'x-xxxx-xxxx',
key: 'researcherId',
},
{
id: 1,
label: 'LinkedIn',
address: 'https://linkedin.com/',
placeholder: 'in/userID, profie/view?profileID, or pub/pubID',
key: 'linkedIn',
},
{
id: 2,
label: 'ORCID',
address: 'http://orcid.org/',
placeholder: 'xxxx-xxxx-xxxx',
key: 'orcid',
},
{
id: 3,
label: 'Twitter',
address: '@',
placeholder: 'twitterhandle',
key: 'twitter',
},
{
id: 4,
label: 'GitHub',
address: 'https://github.com/',
placeholder: 'username',
key: 'github',
},
{
id: 5,
label: 'ImpactStory',
address: 'https://impactstory.org/u/',
placeholder: 'profileID',
key: 'impactStory',
},
{
id: 6,
label: 'Google Scholar',
address: 'http://scholar.google.com/citations?user=',
placeholder: 'profileID',
key: 'scholar',
},
{
id: 7,
label: 'ResearchGate',
address: 'https://researchgate.net/profile/',
placeholder: 'profileID',
key: 'researchGate',
},
{
id: 8,
label: 'Baidu Scholar',
address: 'http://xueshu.baidu.com/scholarID/',
placeholder: 'profileID',
key: 'baiduScholar',
},
{
id: 9,
label: 'SSRN',
address: 'http://papers.ssrn.com/sol3/cf_dev/AbsByAuth.cfm?per_id=',
placeholder: 'profileID',
key: 'ssrn',
},
];
Loading