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
8 changes: 7 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
"sourceMap": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
}
},
"defaultConfiguration": "production"
Expand Down
7 changes: 6 additions & 1 deletion src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ import Aura from '@primeng/themes/aura';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideHttpClient } from '@angular/common/http';
import { ConfirmationService } from 'primeng/api';
import { AuthState } from '@core/store/auth';
import { HomeState } from '@core/store/home';

export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideStore([], withNgxsReduxDevtoolsPlugin({ disabled: false })),
provideStore(
[AuthState, HomeState],
withNgxsReduxDevtoolsPlugin({ disabled: false }),
),
providePrimeNG({
theme: {
preset: Aura,
Expand Down
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { NgModule } from '@angular/core';
import { NgxsModule } from '@ngxs/store';
import { AuthState } from '@core/store/auth';
import { HomeState } from '@core/store/home';

@NgModule({
imports: [NgxsModule.forRoot([AuthState])],
imports: [NgxsModule.forRoot([AuthState, HomeState])],
})
export class AppModule {}
13 changes: 9 additions & 4 deletions src/app/core/services/json-api/json-api.entity.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
export interface JsonApiResponse<T> {
data: ApiData<T> | ApiData<T>[];
data: T;
}

export interface ApiData<T> {
id: string | number;
attributes: T;
export interface JsonApiArrayResponse<T> {
data: T[];
}

export interface ApiData<Attributes, Embeds> {
id: string;
attributes: Attributes;
embeds: Embeds;
}
56 changes: 45 additions & 11 deletions src/app/core/services/json-api/json-api.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { map, Observable } from 'rxjs';
import {
ApiData,
JsonApiArrayResponse,
JsonApiResponse,
} from '@core/services/json-api/json-api.entity';

Expand All @@ -12,19 +12,53 @@ import {
export class JsonApiService {
http: HttpClient = inject(HttpClient);

get<T>(url: string): Observable<T> {
get<T>(url: string, params?: Record<string, unknown>): Observable<T> {
let httpParams = new HttpParams();

if (params) {
for (const key in params) {
const value = params[key];

if (Array.isArray(value)) {
value.forEach((item) => {
httpParams = httpParams.append(`${key}[]`, item); // Handles arrays
});
} else {
httpParams = httpParams.set(key, value as string);
}
}
}

return this.http
.get<JsonApiResponse<T>>(url)
.pipe(map((response) => (response.data as ApiData<T>).attributes));
.pipe(map((response) => response.data));
}

getArray<T>(url: string): Observable<T[]> {
getArray<T>(url: string, params?: Record<string, unknown>): Observable<T[]> {
let httpParams = new HttpParams();

if (params) {
for (const key in params) {
const value = params[key];

if (Array.isArray(value)) {
value.forEach((item) => {
httpParams = httpParams.append(`${key}[]`, item); // Handles arrays
});
} else {
httpParams = httpParams.set(key, value as string);
}
}
}

const headers = new HttpHeaders({
Authorization: `Bearer UlO9O9GNKgVzJD7pUeY53jiQTKJ4U2znXVWNvh0KZQruoENuILx0IIYf9LoDz7Duq72EIm`,
});

return this.http
.get<JsonApiResponse<T>>(url)
.pipe(
map((response) =>
(response.data as ApiData<T>[]).map((item) => item.attributes),
),
);
.get<
JsonApiArrayResponse<T>
>(url, { params: httpParams, headers: headers })
.pipe(map((response) => response.data));
}
}
1 change: 1 addition & 0 deletions src/app/core/services/user/user.entity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface User {
fullName: string;
givenName: string;
familyName: string;
}
14 changes: 5 additions & 9 deletions src/app/core/services/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import { inject, Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';
import { JsonApiService } from '@core/services/json-api/json-api.service';
import { User } from '@core/services/user/user.entity';
import { UserUS } from '@core/services/json-api/underscore-entites/user/user-us.entity';
import { mapUserUStoUser } from '@core/services/mappers/users/users.mapper';

@Injectable({
providedIn: 'root',
})
export class UserService {
jsonApiService = inject(JsonApiService);

getMe(): Observable<User> {
return this.jsonApiService
.get<UserUS>('https://api.test.osf.io/v2/users/me')
.pipe(map((user) => mapUserUStoUser(user)));
}
// getMe(): Observable<User> {
// return this.jsonApiService
// .get<UserUS>('https://api.test.osf.io/v2/users/me')
// .pipe(map((user) => mapUserUStoUser(user)));
// }
}
11 changes: 11 additions & 0 deletions src/app/core/store/home/home.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class GetProjects {
static readonly type = '[Home] Get Projects';
}

export class GetNoteworthy {
static readonly type = '[Home] Get Noteworthy';
}

export class GetMostPopular {
static readonly type = '[Home] Get Most Popular';
}
7 changes: 7 additions & 0 deletions src/app/core/store/home/home.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Project } from '@osf/features/home/models/project.entity';

export interface HomeStateModel {
projects: Project[];
noteworthy: Project[];
mostPopular: Project[];
}
21 changes: 21 additions & 0 deletions src/app/core/store/home/home.selectors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Selector } from '@ngxs/store';
import { HomeStateModel } from '@core/store/home/home.model';
import { HomeState } from '@core/store/home/home.state';
import { Project } from '@osf/features/home/models/project.entity';

export class HomeSelectors {
@Selector([HomeState])
static getProjects(state: HomeStateModel): Project[] {
return state.projects;
}

@Selector([HomeState])
static getNoteworthy(state: HomeStateModel): Project[] {
return state.noteworthy;
}

@Selector([HomeState])
static getMostPopular(state: HomeStateModel): Project[] {
return state.mostPopular;
}
}
50 changes: 50 additions & 0 deletions src/app/core/store/home/home.state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { HomeStateModel } from '@core/store/home/home.model';
import { Action, State, StateContext } from '@ngxs/store';
import { inject, Injectable } from '@angular/core';
import { DashboardService } from '@osf/features/home/dashboard.service';
import {
GetMostPopular,
GetNoteworthy,
GetProjects,
} from '@core/store/home/home.actions';
import { tap } from 'rxjs';

@State<HomeStateModel>({
name: 'home',
defaults: {
projects: [],
noteworthy: [],
mostPopular: [],
},
})
@Injectable()
export class HomeState {
homeService = inject(DashboardService);

@Action(GetProjects)
getProjects(ctx: StateContext<HomeStateModel>) {
return this.homeService.getProjects().pipe(
tap((projects) => {
ctx.patchState({ projects: projects });
}),
);
}

@Action(GetMostPopular)
getMostPopular(ctx: StateContext<HomeStateModel>) {
return this.homeService.getMostPopular().pipe(
tap((mostPopular) => {
ctx.patchState({ mostPopular: mostPopular });
}),
);
}

@Action(GetNoteworthy)
GetNoteworthy(ctx: StateContext<HomeStateModel>) {
return this.homeService.getNoteworthy().pipe(
tap((noteworthy) => {
ctx.patchState({ noteworthy: noteworthy });
}),
);
}
}
4 changes: 4 additions & 0 deletions src/app/core/store/home/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './home.actions';
export * from './home.model';
export * from './home.selectors';
export * from './home.state';
60 changes: 60 additions & 0 deletions src/app/features/home/dashboard.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { inject, Injectable } from '@angular/core';
import { JsonApiService } from '@core/services/json-api/json-api.service';
import { map, Observable } from 'rxjs';
import { Project } from '@osf/features/home/models/project.entity';
import { mapProjectUStoProject } from '@osf/features/home/mappers/dashboard.mapper';
import { ProjectItem } from '@osf/features/home/models/raw-models/ProjectItem.entity';
import { environment } from '../../../environments/environment';

@Injectable({
providedIn: 'root',
})
export class DashboardService {
jsonApiService = inject(JsonApiService);

getProjects(): Observable<Project[]> {
const userId = 'k9p2t';
const params = {
embed: ['bibliographic_contributors', 'parent', 'root'],
page: 1,
sort: '-last_logged',
};

return this.jsonApiService
.getArray<ProjectItem>(
`${environment.apiUrl}/sparse/users/${userId}/nodes/`,
params,
)
.pipe(map((projects) => projects.map(mapProjectUStoProject)));
}

getNoteworthy(): Observable<Project[]> {
const projectId = 'pf5z9';
const params = {
embed: 'bibliographic_contributors',
'page[size]': 5,
};

return this.jsonApiService
.getArray<ProjectItem>(
`${environment.apiUrl}/nodes/${projectId}/linked_nodes`,
params,
)
.pipe(map((projects) => projects.map(mapProjectUStoProject)));
}

getMostPopular(): Observable<Project[]> {
const projectId = 'kvw3y';
const params = {
embed: 'bibliographic_contributors',
'page[size]': 5,
};

return this.jsonApiService
.getArray<ProjectItem>(
`${environment.apiUrl}/nodes/${projectId}/linked_nodes`,
params,
)
.pipe(map((projects) => projects.map(mapProjectUStoProject)));
}
}
Loading