From 285d37d79f6aa472d22087bb4f4e097f076232e2 Mon Sep 17 00:00:00 2001 From: SDaian Date: Fri, 27 May 2022 15:47:30 -0300 Subject: [PATCH 1/8] feat(angular-ngrx-scss): Get gists from Github API --- .../src/app/home/home.component.html | 11 ++++++-- .../src/app/home/home.component.scss | 9 +++++- .../src/app/home/home.component.ts | 3 ++ angular-ngrx-scss/src/app/home/home.module.ts | 2 ++ .../home/user-gists/user-gists.component.html | 16 +++++++++++ .../home/user-gists/user-gists.component.scss | 16 +++++++++++ .../home/user-gists/user-gists.component.ts | 15 ++++++++++ .../src/app/shared/styles/variables.scss | 2 ++ .../src/app/state/profile/profile.reducer.ts | 5 ++++ .../app/state/profile/profile.selectors.ts | 5 ++++ .../src/app/state/profile/profile.state.ts | 28 +++++++++++++++++++ .../src/app/state/user/user.actions.ts | 16 +++++++++++ .../src/app/state/user/user.effects.ts | 14 ++++++++++ .../src/app/user/services/user.service.ts | 18 ++++++++++++ 14 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html create mode 100644 angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss create mode 100644 angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts diff --git a/angular-ngrx-scss/src/app/home/home.component.html b/angular-ngrx-scss/src/app/home/home.component.html index 56e596cff..133455189 100644 --- a/angular-ngrx-scss/src/app/home/home.component.html +++ b/angular-ngrx-scss/src/app/home/home.component.html @@ -2,7 +2,12 @@ -
-
Main content!
-
+ +
+ +
Main content!
+
+
diff --git a/angular-ngrx-scss/src/app/home/home.component.scss b/angular-ngrx-scss/src/app/home/home.component.scss index 3c73cead2..58cb5fec4 100644 --- a/angular-ngrx-scss/src/app/home/home.component.scss +++ b/angular-ngrx-scss/src/app/home/home.component.scss @@ -5,7 +5,7 @@ grid-template-rows: auto 1fr; grid-template-columns: 30% 1fr; width: 100%; - height: 100%; + height: 100vh; } .nav { @@ -14,7 +14,14 @@ } .main { + display: grid; + grid-template-columns: 1fr 2fr; grid-row: 2 / 3; grid-column: 1 / 3; background: variables.$gray100; } + +aside { + background: variables.$white; + padding: 2rem; +} diff --git a/angular-ngrx-scss/src/app/home/home.component.ts b/angular-ngrx-scss/src/app/home/home.component.ts index a53f629fd..202525fda 100644 --- a/angular-ngrx-scss/src/app/home/home.component.ts +++ b/angular-ngrx-scss/src/app/home/home.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; +import { selectUserLoginName } from '../state/user'; import { fetchUserData } from '../state/user/user.actions'; @Component({ @@ -8,6 +9,8 @@ import { fetchUserData } from '../state/user/user.actions'; styleUrls: ['./home.component.scss'], }) export class HomeComponent implements OnInit { + user$ = this.store.select(selectUserLoginName); + constructor(private store: Store) {} ngOnInit() { diff --git a/angular-ngrx-scss/src/app/home/home.module.ts b/angular-ngrx-scss/src/app/home/home.module.ts index 13aec5bc8..90c221bac 100644 --- a/angular-ngrx-scss/src/app/home/home.module.ts +++ b/angular-ngrx-scss/src/app/home/home.module.ts @@ -10,6 +10,7 @@ import { ProfileAboutComponent } from './profile/profile-about/profile-about.com import { ProfileReposComponent } from './profile/profile-repos/profile-repos.component'; import { RelativeTimePipe } from '../shared/pipes/relative-time.pipe'; import { RepoCardComponent } from '../shared/components/repo-card/repo-card.component'; +import { UserGistsComponent } from './user-gists/user-gists.component'; @NgModule({ declarations: [ @@ -22,6 +23,7 @@ import { RepoCardComponent } from '../shared/components/repo-card/repo-card.comp ProfileReposComponent, RepoCardComponent, RelativeTimePipe, + UserGistsComponent, ], imports: [CommonModule, HomeRoutingModule], }) diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html new file mode 100644 index 000000000..bf85f1faa --- /dev/null +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html @@ -0,0 +1,16 @@ +
+

Gists

+ + + + + +
+ + +

User does not have any gists

+
diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss new file mode 100644 index 000000000..f7e6e91b4 --- /dev/null +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss @@ -0,0 +1,16 @@ +@use '../../shared/styles/variables'; + +.container { + padding: 2rem 0; + border-top: 1px solid variables.$gray300; + border-bottom: 1px solid variables.$gray300; + h3 { + font-weight: 600; + } + a.link{ + color: variables.$black; + &:hover { + color: variables.$blue300; + } + } +} diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts new file mode 100644 index 000000000..b51f56a02 --- /dev/null +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts @@ -0,0 +1,15 @@ +import { Component } from '@angular/core'; +import { Store } from '@ngrx/store'; + +import { selectGists } from 'src/app/state/profile/profile.selectors'; + +@Component({ + selector: 'app-user-gists', + templateUrl: './user-gists.component.html', + styleUrls: ['./user-gists.component.scss'], +}) +export class UserGistsComponent { + userGists$ = this.store.select(selectGists); + + constructor(private store: Store) {} +} diff --git a/angular-ngrx-scss/src/app/shared/styles/variables.scss b/angular-ngrx-scss/src/app/shared/styles/variables.scss index d32a9fb38..56a4d2ec5 100644 --- a/angular-ngrx-scss/src/app/shared/styles/variables.scss +++ b/angular-ngrx-scss/src/app/shared/styles/variables.scss @@ -1,9 +1,11 @@ // colors $white: rgb(255 255 255); $gray100: rgb(243 244 246); +$gray300: rgb(229,231,235); $gray500: rgb(107 114 128); $gray900: rgb(17, 24, 39); $black: rgb(0 0 0); +$blue300: rgb(59,130,246); $blue600: rgb(37 99 235); // breakpoints diff --git a/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts b/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts index 85894f427..2b8486ffc 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts @@ -1,4 +1,5 @@ import { Action, createReducer, on } from '@ngrx/store'; +import { getUserGistsSuccess } from '../user/user.actions'; import { fetchProfileSuccess } from './profile.actions'; import { ProfileState } from './profile.state'; @@ -11,6 +12,10 @@ const reducer = createReducer( ...state, ...data, })), + on(getUserGistsSuccess, (state, { userData }) => ({ + ...state, + gists: userData, + })), ); export function profileReducer( diff --git a/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts b/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts index 03c48af2f..d385027a9 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts @@ -9,3 +9,8 @@ export const selectProfile = createSelector( selectProfileState, (state: ProfileState) => state, ); + +export const selectGists = createSelector( + selectProfileState, + (state: ProfileState) => state.gists, +); diff --git a/angular-ngrx-scss/src/app/state/profile/profile.state.ts b/angular-ngrx-scss/src/app/state/profile/profile.state.ts index 484faa724..d485600e7 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.state.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.state.ts @@ -4,8 +4,36 @@ export interface ProfileState { user?: UserState; orgs?: UserOrgsState[]; repos?: UserReposState[]; + gists?: UserGistsState[]; } +export interface UserGistsState { + url: string; + fileName: string; +} + +interface Files { + filename: string; +} +export interface UserGist { + comments: number; + comments_url: string; + commits_url: string; + created_at: string; + forks_url: string; + git_pull_url: string; + git_push_url: string; + html_url: string; + id: string; + node_id: string; + public: boolean; + truncated: false; + updated_at: string; + url: string; + files: Files; +} + +export type UserGistsApiResponse = UserGist[]; export interface UserOrgsState { id: number; login: string; diff --git a/angular-ngrx-scss/src/app/state/user/user.actions.ts b/angular-ngrx-scss/src/app/state/user/user.actions.ts index 4fe8a5132..6d601c06c 100644 --- a/angular-ngrx-scss/src/app/state/user/user.actions.ts +++ b/angular-ngrx-scss/src/app/state/user/user.actions.ts @@ -1,4 +1,5 @@ import { createAction, props } from '@ngrx/store'; +import { UserGistsState } from '../profile/profile.state'; import { UserState } from './user.state'; export const fetchUserData = createAction('[User API] User data requested'); @@ -12,3 +13,18 @@ export const fetchUserDataError = createAction( '[User API] User Data fetch unsuccessful', props<{ error: object }>(), ); + +export const getUserGists = createAction( + '[User API] User gists requested', + props<{ username: string }>(), +); + +export const getUserGistsSuccess = createAction( + '[User API] User gists successfully received', + props<{ userData: UserGistsState[] }>(), +); + +export const getUserGistsError = createAction( + '[User API] User gists unsuccessful', + props<{ error: object }>(), +); diff --git a/angular-ngrx-scss/src/app/state/user/user.effects.ts b/angular-ngrx-scss/src/app/state/user/user.effects.ts index 720ebd794..e65a8ba4a 100644 --- a/angular-ngrx-scss/src/app/state/user/user.effects.ts +++ b/angular-ngrx-scss/src/app/state/user/user.effects.ts @@ -7,6 +7,8 @@ import { fetchUserData, fetchUserDataError, fetchUserDataSuccess, + getUserGistsError, + getUserGistsSuccess, } from './user.actions'; @Injectable() @@ -23,5 +25,17 @@ export class UserEffects { ); }); + loadUserGists$ = createEffect(() => { + return this.actions$.pipe( + ofType(fetchUserDataSuccess), + switchMap(({ userData: { username } }) => + this.userService.getUserGists(username).pipe( + map((data) => getUserGistsSuccess({ userData: data })), + catchError((error) => of(getUserGistsError({ error }))), + ), + ), + ); + }); + constructor(public actions$: Actions, private userService: UserService) {} } diff --git a/angular-ngrx-scss/src/app/user/services/user.service.ts b/angular-ngrx-scss/src/app/user/services/user.service.ts index 283d43ed1..158c4790c 100644 --- a/angular-ngrx-scss/src/app/user/services/user.service.ts +++ b/angular-ngrx-scss/src/app/user/services/user.service.ts @@ -2,6 +2,9 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { map, Observable } from 'rxjs'; import { + UserGist, + UserGistsApiResponse, + UserGistsState, UserOrgsApiResponse, UserOrgsState, UserReposApiResponse, @@ -105,4 +108,19 @@ export class UserService { ), ); } + + getUserGists(username: string): Observable { + const url = `${environment.githubUrl}/users/${encodeURIComponent( + username, + )}/gists`; + + return this.http.get(url).pipe( + map((data) => + data.map((gist: UserGist) => ({ + url: gist.html_url, + fileName: Object.keys(gist.files)[0], + })), + ), + ); + } } From 27c7bb6bc7d3cf4eb93819c2d1952c3734bd9767 Mon Sep 17 00:00:00 2001 From: SDaian Date: Tue, 14 Jun 2022 12:33:56 -0300 Subject: [PATCH 2/8] [fix/issue/106] - Add main page layout --- angular-ngrx-scss/src/app/home/home.component.html | 2 +- angular-ngrx-scss/src/app/home/home.component.scss | 2 +- angular-ngrx-scss/src/app/home/home.module.ts | 2 ++ .../top-repositories/top-repositories.component.html | 3 +++ .../top-repositories/top-repositories.component.scss | 11 +++++++++++ .../top-repositories/top-repositories.component.ts | 12 ++++++++++++ 6 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html create mode 100644 angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss create mode 100644 angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts diff --git a/angular-ngrx-scss/src/app/home/home.component.html b/angular-ngrx-scss/src/app/home/home.component.html index 133455189..bf1eeef87 100644 --- a/angular-ngrx-scss/src/app/home/home.component.html +++ b/angular-ngrx-scss/src/app/home/home.component.html @@ -7,7 +7,7 @@ -
Main content!
+ diff --git a/angular-ngrx-scss/src/app/home/home.component.scss b/angular-ngrx-scss/src/app/home/home.component.scss index 58cb5fec4..45dba192e 100644 --- a/angular-ngrx-scss/src/app/home/home.component.scss +++ b/angular-ngrx-scss/src/app/home/home.component.scss @@ -15,7 +15,7 @@ .main { display: grid; - grid-template-columns: 1fr 2fr; + grid-template-columns: 24rem 1fr; grid-row: 2 / 3; grid-column: 1 / 3; background: variables.$gray100; diff --git a/angular-ngrx-scss/src/app/home/home.module.ts b/angular-ngrx-scss/src/app/home/home.module.ts index 90c221bac..f040094b2 100644 --- a/angular-ngrx-scss/src/app/home/home.module.ts +++ b/angular-ngrx-scss/src/app/home/home.module.ts @@ -11,6 +11,7 @@ import { ProfileReposComponent } from './profile/profile-repos/profile-repos.com import { RelativeTimePipe } from '../shared/pipes/relative-time.pipe'; import { RepoCardComponent } from '../shared/components/repo-card/repo-card.component'; import { UserGistsComponent } from './user-gists/user-gists.component'; +import { TopRepositoriesComponent } from './top-repositories/top-repositories.component'; @NgModule({ declarations: [ @@ -24,6 +25,7 @@ import { UserGistsComponent } from './user-gists/user-gists.component'; RepoCardComponent, RelativeTimePipe, UserGistsComponent, + TopRepositoriesComponent, ], imports: [CommonModule, HomeRoutingModule], }) diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html new file mode 100644 index 000000000..49e936c21 --- /dev/null +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html @@ -0,0 +1,3 @@ +
+

Top Repositories

+
diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss new file mode 100644 index 000000000..42c93f8a3 --- /dev/null +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss @@ -0,0 +1,11 @@ +@use '../../shared/styles/variables'; + +.top-repositories-container { + padding: 3rem; + h2 { + font-size: 18px; + line-height: 28px; + font-weight: 500; + margin-bottom: 16px; + } +} diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts new file mode 100644 index 000000000..0f86893ab --- /dev/null +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts @@ -0,0 +1,12 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-top-repositories', + templateUrl: './top-repositories.component.html', + styleUrls: ['./top-repositories.component.scss'], +}) +export class TopRepositoriesComponent implements OnInit { + constructor() { } + + ngOnInit(): void { } +} From 2627196be42aba42cf2e5c963ff30ec7ffe12ea4 Mon Sep 17 00:00:00 2001 From: SDaian Date: Fri, 17 Jun 2022 16:10:37 -0300 Subject: [PATCH 3/8] [fix/issue-106] - Create main page layout --- .../top-repositories.component.html | 12 + .../top-repositories.component.scss | 20 ++ .../top-repositories.component.ts | 16 +- .../home/user-gists/user-gists.component.html | 10 +- .../home/user-gists/user-gists.component.scss | 2 +- .../home/user-gists/user-gists.component.ts | 3 +- .../src/app/shared/styles/variables.scss | 6 +- .../src/app/state/profile/profile.reducer.ts | 5 - .../app/state/profile/profile.selectors.ts | 5 - .../src/app/state/profile/profile.state.ts | 2 +- .../src/app/state/user/user.actions.ts | 27 ++- .../src/app/state/user/user.effects.spec.ts | 101 ++++++++- .../src/app/state/user/user.effects.ts | 22 +- .../src/app/state/user/user.reducer.ts | 14 +- .../src/app/state/user/user.selectors.ts | 10 + .../src/app/state/user/user.state.ts | 4 + .../app/user/services/user.service.spec.ts | 207 +++++++++++++++++- .../src/app/user/services/user.service.ts | 30 +++ 18 files changed, 452 insertions(+), 44 deletions(-) diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html index 49e936c21..b00a56a32 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html @@ -1,3 +1,15 @@

Top Repositories

+
+ + +
+ +
+ +
+
+
diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss index 42c93f8a3..ddbc3ddcd 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss @@ -8,4 +8,24 @@ font-weight: 500; margin-bottom: 16px; } + .repo-container { + background-color: variables.$white; + border-radius: 0.5rem; + border-width: 1px; + padding-left: 2rem; + } + .repo-section { + padding: 2rem 0; + border-bottom: 1px solid variables.$gray300; + } + .view-all-link { + padding: 1.25rem; + background-color: variables.$gray200; + display: grid; + place-items: center; + a { + color: inherit; + font-weight: 600; + } + } } diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts index 0f86893ab..5122bb211 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts @@ -1,12 +1,20 @@ -import { Component, OnInit } from '@angular/core'; +import { Component } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { selectTopRepos, selectUserLoginName } from 'src/app/state/user'; +import languageColors from 'src/assets/language-colors.json'; @Component({ selector: 'app-top-repositories', templateUrl: './top-repositories.component.html', styleUrls: ['./top-repositories.component.scss'], }) -export class TopRepositoriesComponent implements OnInit { - constructor() { } +export class TopRepositoriesComponent { + username$ = this.store.select(selectUserLoginName); + repos$ = this.store.select(selectTopRepos); - ngOnInit(): void { } + constructor(private store: Store) {} + + getColor(language: string): string { + return languageColors[language] ?? '#000'; + } } diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html index bf85f1faa..be7e700d4 100644 --- a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.html @@ -1,16 +1,14 @@ - - -

User does not have any gists

-
diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss index f7e6e91b4..2d777c505 100644 --- a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.scss @@ -7,7 +7,7 @@ h3 { font-weight: 600; } - a.link{ + a.link { color: variables.$black; &:hover { color: variables.$blue300; diff --git a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts index b51f56a02..7525d7e17 100644 --- a/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts +++ b/angular-ngrx-scss/src/app/home/user-gists/user-gists.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; - -import { selectGists } from 'src/app/state/profile/profile.selectors'; +import { selectGists } from 'src/app/state/user'; @Component({ selector: 'app-user-gists', diff --git a/angular-ngrx-scss/src/app/shared/styles/variables.scss b/angular-ngrx-scss/src/app/shared/styles/variables.scss index 56a4d2ec5..68f42daf1 100644 --- a/angular-ngrx-scss/src/app/shared/styles/variables.scss +++ b/angular-ngrx-scss/src/app/shared/styles/variables.scss @@ -1,11 +1,13 @@ // colors $white: rgb(255 255 255); $gray100: rgb(243 244 246); -$gray300: rgb(229,231,235); +$gray200: rgb(249, 250, 251); +$gray300: rgb(229, 231, 235); $gray500: rgb(107 114 128); +$gray700: rgb(75 85 99); $gray900: rgb(17, 24, 39); $black: rgb(0 0 0); -$blue300: rgb(59,130,246); +$blue300: rgb(59, 130, 246); $blue600: rgb(37 99 235); // breakpoints diff --git a/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts b/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts index 2b8486ffc..85894f427 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.reducer.ts @@ -1,5 +1,4 @@ import { Action, createReducer, on } from '@ngrx/store'; -import { getUserGistsSuccess } from '../user/user.actions'; import { fetchProfileSuccess } from './profile.actions'; import { ProfileState } from './profile.state'; @@ -12,10 +11,6 @@ const reducer = createReducer( ...state, ...data, })), - on(getUserGistsSuccess, (state, { userData }) => ({ - ...state, - gists: userData, - })), ); export function profileReducer( diff --git a/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts b/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts index d385027a9..03c48af2f 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.selectors.ts @@ -9,8 +9,3 @@ export const selectProfile = createSelector( selectProfileState, (state: ProfileState) => state, ); - -export const selectGists = createSelector( - selectProfileState, - (state: ProfileState) => state.gists, -); diff --git a/angular-ngrx-scss/src/app/state/profile/profile.state.ts b/angular-ngrx-scss/src/app/state/profile/profile.state.ts index d485600e7..698a9b557 100644 --- a/angular-ngrx-scss/src/app/state/profile/profile.state.ts +++ b/angular-ngrx-scss/src/app/state/profile/profile.state.ts @@ -13,7 +13,7 @@ export interface UserGistsState { } interface Files { - filename: string; + [key: string]: { filename: string }; } export interface UserGist { comments: number; diff --git a/angular-ngrx-scss/src/app/state/user/user.actions.ts b/angular-ngrx-scss/src/app/state/user/user.actions.ts index 6d601c06c..12e3d1dc5 100644 --- a/angular-ngrx-scss/src/app/state/user/user.actions.ts +++ b/angular-ngrx-scss/src/app/state/user/user.actions.ts @@ -1,5 +1,5 @@ import { createAction, props } from '@ngrx/store'; -import { UserGistsState } from '../profile/profile.state'; +import { UserGistsState, UserReposState } from '../profile/profile.state'; import { UserState } from './user.state'; export const fetchUserData = createAction('[User API] User data requested'); @@ -14,17 +14,32 @@ export const fetchUserDataError = createAction( props<{ error: object }>(), ); -export const getUserGists = createAction( +export const fetchUserGists = createAction( '[User API] User gists requested', props<{ username: string }>(), ); -export const getUserGistsSuccess = createAction( +export const fetchUserTopRepos = createAction( + '[User API] User top repos requested', + props<{ username: string }>(), +); + +export const fetchUserTopReposSuccess = createAction( + '[User API] User top repos successfully received', + props<{ topRepos: UserReposState[] }>(), +); + +export const fetchUserTopReposError = createAction( + '[User API] User top repos fetch unsuccessful', + props<{ error: object }>(), +); + +export const fetchUserGistsSuccess = createAction( '[User API] User gists successfully received', - props<{ userData: UserGistsState[] }>(), + props<{ gists: UserGistsState[] }>(), ); -export const getUserGistsError = createAction( - '[User API] User gists unsuccessful', +export const fetchUserGistsError = createAction( + '[User API] User gists fetch unsuccessful', props<{ error: object }>(), ); diff --git a/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts b/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts index a7c207b72..7e38e2cb4 100644 --- a/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts +++ b/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts @@ -2,10 +2,30 @@ import { TestBed } from '@angular/core/testing'; import { provideMockActions } from '@ngrx/effects/testing'; import { Action } from '@ngrx/store'; import { Observable, of } from 'rxjs'; -import { fetchUserData, fetchUserDataSuccess } from './user.actions'; +import { + fetchUserData, + fetchUserDataSuccess, + fetchUserGistsSuccess, + fetchUserTopReposSuccess, +} from './user.actions'; import { UserService } from '../../user/services/user.service'; import { UserEffects } from './user.effects'; import { UserState } from './user.state'; +import { UserGistsState, UserReposState } from '../profile/profile.state'; + +const userStateMock: UserState = { + username: 'thisdot', + avatar: '', + bio: '', + blog: '', + company: '', + email: '', + followers: 0, + following: 0, + location: '', + name: '', + twitter_username: '', +}; describe('UserEffects', () => { let actions$: Observable; @@ -17,6 +37,12 @@ describe('UserEffects', () => { getAuthenticatedUserInfo: () => { return of(); }, + getUserGists: () => { + return of(); + }, + getUserTopRepos: () => { + return of(); + }, }); TestBed.configureTestingModule({ imports: [], @@ -64,4 +90,77 @@ describe('UserEffects', () => { done(); }); }); + + it('should get the user gists from the Github API', (done) => { + actions$ = of(fetchUserDataSuccess({ userData: userStateMock })); + const expectedUserData: UserGistsState[] = [ + { + url: 'github.com/gists', + fileName: 'textfile1.txt', + }, + ]; + + userServiceMock.getUserGists.and.returnValue(of(expectedUserData)); + + effects.loadUserGists$.subscribe((action) => { + expect(action).toEqual( + fetchUserGistsSuccess({ gists: expectedUserData }), + ); + done(); + }); + }); + + it('should get the top repositories from the Github API', (done) => { + actions$ = of(fetchUserDataSuccess({ userData: userStateMock })); + const expectedUserData: UserReposState[] = [ + { + name: 'Repo-test', + description: 'This is a repo test', + language: 'TypeScript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + { + name: 'Repo-test-2', + description: 'This is a repo test 2', + language: 'Javascript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + { + name: 'Repo-test-3', + description: 'This is a repo test 2', + language: 'Javascript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + ]; + + userServiceMock.getUserTopRepos.and.returnValue(of(expectedUserData)); + + effects.loadUserTopRepos$.subscribe((action) => { + expect(action).toEqual( + fetchUserTopReposSuccess({ topRepos: expectedUserData }), + ); + done(); + }); + }); }); diff --git a/angular-ngrx-scss/src/app/state/user/user.effects.ts b/angular-ngrx-scss/src/app/state/user/user.effects.ts index e65a8ba4a..b789596ec 100644 --- a/angular-ngrx-scss/src/app/state/user/user.effects.ts +++ b/angular-ngrx-scss/src/app/state/user/user.effects.ts @@ -7,8 +7,10 @@ import { fetchUserData, fetchUserDataError, fetchUserDataSuccess, - getUserGistsError, - getUserGistsSuccess, + fetchUserGistsError, + fetchUserGistsSuccess, + fetchUserTopReposError, + fetchUserTopReposSuccess, } from './user.actions'; @Injectable() @@ -30,8 +32,20 @@ export class UserEffects { ofType(fetchUserDataSuccess), switchMap(({ userData: { username } }) => this.userService.getUserGists(username).pipe( - map((data) => getUserGistsSuccess({ userData: data })), - catchError((error) => of(getUserGistsError({ error }))), + map((data) => fetchUserGistsSuccess({ gists: data })), + catchError((error) => of(fetchUserGistsError({ error }))), + ), + ), + ); + }); + + loadUserTopRepos$ = createEffect(() => { + return this.actions$.pipe( + ofType(fetchUserDataSuccess), + switchMap(() => + this.userService.getUserTopRepos().pipe( + map((data) => fetchUserTopReposSuccess({ topRepos: data })), + catchError((error) => of(fetchUserTopReposError({ error }))), ), ), ); diff --git a/angular-ngrx-scss/src/app/state/user/user.reducer.ts b/angular-ngrx-scss/src/app/state/user/user.reducer.ts index d5d851dfb..0632a784b 100644 --- a/angular-ngrx-scss/src/app/state/user/user.reducer.ts +++ b/angular-ngrx-scss/src/app/state/user/user.reducer.ts @@ -1,6 +1,10 @@ import { Action, createReducer, on } from '@ngrx/store'; import { UserState } from './user.state'; -import { fetchUserDataSuccess } from './user.actions'; +import { + fetchUserDataSuccess, + fetchUserGistsSuccess, + fetchUserTopReposSuccess, +} from './user.actions'; const initialUserState: UserState = { avatar: '', @@ -23,6 +27,14 @@ const reducer = createReducer( ...state, ...userData, })), + on(fetchUserGistsSuccess, (state, { gists }) => ({ + ...state, + gists, + })), + on(fetchUserTopReposSuccess, (state, { topRepos }) => ({ + ...state, + topRepos, + })), ); export function userReducer(state: UserState | undefined, action: Action) { diff --git a/angular-ngrx-scss/src/app/state/user/user.selectors.ts b/angular-ngrx-scss/src/app/state/user/user.selectors.ts index 0ae351414..a095a887d 100644 --- a/angular-ngrx-scss/src/app/state/user/user.selectors.ts +++ b/angular-ngrx-scss/src/app/state/user/user.selectors.ts @@ -13,3 +13,13 @@ export const selectUserLoginName = createSelector( selectUserState, (state: UserState) => state.username, ); + +export const selectGists = createSelector( + selectUserState, + (state: UserState) => state.gists, +); + +export const selectTopRepos = createSelector( + selectUserState, + (state: UserState) => state.topRepos, +); diff --git a/angular-ngrx-scss/src/app/state/user/user.state.ts b/angular-ngrx-scss/src/app/state/user/user.state.ts index 1fa0dc949..b042f8f5e 100644 --- a/angular-ngrx-scss/src/app/state/user/user.state.ts +++ b/angular-ngrx-scss/src/app/state/user/user.state.ts @@ -1,3 +1,5 @@ +import { UserGistsState, UserReposState } from '../profile/profile.state'; + export interface UserState { avatar: string; bio: string; @@ -10,6 +12,8 @@ export interface UserState { name: string; twitter_username: string; username: string; + topRepos?: UserReposState[]; + gists?: UserGistsState[]; } export interface UserApiResponse { diff --git a/angular-ngrx-scss/src/app/user/services/user.service.spec.ts b/angular-ngrx-scss/src/app/user/services/user.service.spec.ts index 55ee684a3..6425d5550 100644 --- a/angular-ngrx-scss/src/app/user/services/user.service.spec.ts +++ b/angular-ngrx-scss/src/app/user/services/user.service.spec.ts @@ -1,6 +1,12 @@ import { HttpClient } from '@angular/common/http'; +import { fakeAsync, tick } from '@angular/core/testing'; import { of } from 'rxjs'; -import { delay } from 'rxjs/operators'; +import { + UserGist, + UserGistsState, + UserRepo, + UserReposState, +} from 'src/app/state/profile/profile.state'; import { UserApiResponse, UserState } from 'src/app/state/user'; import { UserService } from './user.service'; @@ -17,7 +23,7 @@ describe('UserService', () => { expect(userService).toBeTruthy(); }); - it('should return user data from the GitHub API', (done) => { + it('should return user data from the GitHub API', fakeAsync(() => { const expectedResponse: UserState = { avatar: 'lindakatcodes_url', bio: '', @@ -46,13 +52,202 @@ describe('UserService', () => { twitter_username: '', }; - httpClientSpy.get.and.returnValue(of(expectedHttpResponse).pipe(delay(0))); + httpClientSpy.get.and.returnValue(of(expectedHttpResponse)); + + const result = {}; userService.getAuthenticatedUserInfo().subscribe((res) => { - expect(res).toEqual(expectedResponse); - done(); + Object.assign(result, res); }); + tick(1000); + expect(result).toEqual(expectedResponse); expect(httpClientSpy.get.calls.count()).withContext('called once').toBe(1); - }); + })); + + it('should return the top repositories from the Github API', fakeAsync(() => { + const expectedResponse: UserReposState[] = [ + { + name: 'Repo-test', + description: 'This is a repo test', + language: 'TypeScript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + { + name: 'Repo-test-2', + description: 'This is a repo test 2', + language: 'Javascript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + { + name: 'Repo-test-3', + description: 'This is a repo test 2', + language: 'Javascript', + stargazers_count: 0, + forks_count: 0, + private: false, + updated_at: '2022-06-17T09:54:38Z', + license: null, + owner: { + login: 'thisdot', + }, + }, + ]; + const expectedHttpResponse: Partial[] = [ + { + name: 'Repo-test', + description: 'This is a repo test', + language: 'TypeScript', + license: null, + private: false, + stargazers_count: 0, + forks_count: 0, + updated_at: '2022-06-17T09:54:38Z', + owner: { + avatar_url: 'https://avatars.githubusercontent.com/u/22839396?v=4', + events_url: 'https://api.github.com/users/thisdot/events{/privacy}', + followers_url: 'https://api.github.com/users/thisdot/followers', + following_url: + 'https://api.github.com/users/thisdot/following{/other_user}', + gists_url: 'https://api.github.com/users/thisdot/gists{/gist_id}', + gravatar_id: '', + html_url: 'https://github.com/thisdot', + id: 22839396, + login: 'thisdot', + node_id: 'MDEyOk9yZ2FuaXphdGlvbjIyODM5Mzk2', + organizations_url: 'https://api.github.com/users/thisdot/orgs', + received_events_url: + 'https://api.github.com/users/thisdot/received_events', + repos_url: 'https://api.github.com/users/thisdot/repos', + site_admin: false, + starred_url: + 'https://api.github.com/users/thisdot/starred{/owner}{/repo}', + subscriptions_url: + 'https://api.github.com/users/thisdot/subscriptions', + type: 'Organization', + url: 'https://api.github.com/users/thisdot', + }, + }, + { + name: 'Repo-test-2', + description: 'This is a repo test 2', + language: 'Javascript', + license: null, + private: false, + stargazers_count: 0, + forks_count: 0, + updated_at: '2022-06-17T09:54:38Z', + owner: { + avatar_url: 'https://avatars.githubusercontent.com/u/22839396?v=4', + events_url: 'https://api.github.com/users/thisdot/events{/privacy}', + followers_url: 'https://api.github.com/users/thisdot/followers', + following_url: + 'https://api.github.com/users/thisdot/following{/other_user}', + gists_url: 'https://api.github.com/users/thisdot/gists{/gist_id}', + gravatar_id: '', + html_url: 'https://github.com/thisdot', + id: 22839396, + login: 'thisdot', + node_id: 'MDEyOk9yZ2FuaXphdGlvbjIyODM5Mzk2', + organizations_url: 'https://api.github.com/users/thisdot/orgs', + received_events_url: + 'https://api.github.com/users/thisdot/received_events', + repos_url: 'https://api.github.com/users/thisdot/repos', + site_admin: false, + starred_url: + 'https://api.github.com/users/thisdot/starred{/owner}{/repo}', + subscriptions_url: + 'https://api.github.com/users/thisdot/subscriptions', + type: 'Organization', + url: 'https://api.github.com/users/thisdot', + }, + }, + { + name: 'Repo-test-3', + description: 'This is a repo test 2', + language: 'Javascript', + private: false, + stargazers_count: 0, + forks_count: 0, + updated_at: '2022-06-17T09:54:38Z', + owner: { + avatar_url: 'https://avatars.githubusercontent.com/u/22839396?v=4', + events_url: 'https://api.github.com/users/thisdot/events{/privacy}', + followers_url: 'https://api.github.com/users/thisdot/followers', + following_url: + 'https://api.github.com/users/thisdot/following{/other_user}', + gists_url: 'https://api.github.com/users/thisdot/gists{/gist_id}', + gravatar_id: '', + html_url: 'https://github.com/thisdot', + id: 22839396, + login: 'thisdot', + node_id: 'MDEyOk9yZ2FuaXphdGlvbjIyODM5Mzk2', + organizations_url: 'https://api.github.com/users/thisdot/orgs', + received_events_url: + 'https://api.github.com/users/thisdot/received_events', + repos_url: 'https://api.github.com/users/thisdot/repos', + site_admin: false, + starred_url: + 'https://api.github.com/users/thisdot/starred{/owner}{/repo}', + subscriptions_url: + 'https://api.github.com/users/thisdot/subscriptions', + type: 'Organization', + url: 'https://api.github.com/users/thisdot', + }, + }, + ]; + httpClientSpy.get.and.returnValue(of(expectedHttpResponse)); + + const result: UserReposState[] = []; + + userService.getUserTopRepos().subscribe((res) => { + Object.assign(result, res); + }); + tick(1000); + + expect(result).toEqual(expectedResponse); + expect(httpClientSpy.get.calls.count()).withContext('called once').toBe(1); + })); + + it('should return the gists from the user', fakeAsync(() => { + const username = 'thisDot'; + const expectedResponse: UserGistsState[] = [ + { + url: 'github.com/gists', + fileName: 'textfile1.txt', + }, + ]; + + const expectedHttpResponse: Partial[] = [ + { + html_url: 'github.com/gists', + files: { 'textfile1.txt': { filename: 'textfile1.txt' } }, + }, + ]; + + httpClientSpy.get.and.returnValue(of(expectedHttpResponse)); + + const result: UserGistsState[] = []; + + userService.getUserGists(username).subscribe((res) => { + Object.assign(result, res); + }); + tick(1000); + + expect(result).toEqual(expectedResponse); + })); }); diff --git a/angular-ngrx-scss/src/app/user/services/user.service.ts b/angular-ngrx-scss/src/app/user/services/user.service.ts index 158c4790c..6c041a0e5 100644 --- a/angular-ngrx-scss/src/app/user/services/user.service.ts +++ b/angular-ngrx-scss/src/app/user/services/user.service.ts @@ -109,6 +109,36 @@ export class UserService { ); } + getUserTopRepos(): Observable { + const url = `${environment.githubUrl}/user/repos?sort=updated&affiliation=owner,collaborator,organization_member&per_page=20'}`; + + return this.http.get(url).pipe( + map((data) => + data.map((repo) => ({ + name: repo.name, + description: repo.description, + language: repo.language, + stargazers_count: repo.stargazers_count, + forks_count: repo.forks_count, + private: repo.private, + updated_at: repo.updated_at, + license: repo.license + ? { + key: repo.license.key, + name: repo.license.name, + spdx_id: repo.license.spdx_id, + url: repo.license.url, + node_id: repo.license.node_id, + } + : null, + owner: { + login: repo.owner.login, + }, + })), + ), + ); + } + getUserGists(username: string): Observable { const url = `${environment.githubUrl}/users/${encodeURIComponent( username, From 77234b3f0687c4806f4d06ecfd8c75985a609304 Mon Sep 17 00:00:00 2001 From: SDaian Date: Wed, 6 Jul 2022 00:29:43 +0200 Subject: [PATCH 4/8] Add missing changes --- .../top-repositories/top-repositories.component.ts | 5 ----- angular-ngrx-scss/src/app/state/user/user.actions.ts | 10 ---------- .../src/app/state/user/user.effects.spec.ts | 6 +++--- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts index 5122bb211..02e5135ed 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.ts @@ -1,7 +1,6 @@ import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { selectTopRepos, selectUserLoginName } from 'src/app/state/user'; -import languageColors from 'src/assets/language-colors.json'; @Component({ selector: 'app-top-repositories', @@ -13,8 +12,4 @@ export class TopRepositoriesComponent { repos$ = this.store.select(selectTopRepos); constructor(private store: Store) {} - - getColor(language: string): string { - return languageColors[language] ?? '#000'; - } } diff --git a/angular-ngrx-scss/src/app/state/user/user.actions.ts b/angular-ngrx-scss/src/app/state/user/user.actions.ts index 12e3d1dc5..5cfd8f809 100644 --- a/angular-ngrx-scss/src/app/state/user/user.actions.ts +++ b/angular-ngrx-scss/src/app/state/user/user.actions.ts @@ -14,16 +14,6 @@ export const fetchUserDataError = createAction( props<{ error: object }>(), ); -export const fetchUserGists = createAction( - '[User API] User gists requested', - props<{ username: string }>(), -); - -export const fetchUserTopRepos = createAction( - '[User API] User top repos requested', - props<{ username: string }>(), -); - export const fetchUserTopReposSuccess = createAction( '[User API] User top repos successfully received', props<{ topRepos: UserReposState[] }>(), diff --git a/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts b/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts index 7e38e2cb4..fad01b61d 100644 --- a/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts +++ b/angular-ngrx-scss/src/app/state/user/user.effects.spec.ts @@ -13,7 +13,7 @@ import { UserEffects } from './user.effects'; import { UserState } from './user.state'; import { UserGistsState, UserReposState } from '../profile/profile.state'; -const userStateMock: UserState = { +const USER_STATE_MOCK: UserState = { username: 'thisdot', avatar: '', bio: '', @@ -92,7 +92,7 @@ describe('UserEffects', () => { }); it('should get the user gists from the Github API', (done) => { - actions$ = of(fetchUserDataSuccess({ userData: userStateMock })); + actions$ = of(fetchUserDataSuccess({ userData: USER_STATE_MOCK })); const expectedUserData: UserGistsState[] = [ { url: 'github.com/gists', @@ -111,7 +111,7 @@ describe('UserEffects', () => { }); it('should get the top repositories from the Github API', (done) => { - actions$ = of(fetchUserDataSuccess({ userData: userStateMock })); + actions$ = of(fetchUserDataSuccess({ userData: USER_STATE_MOCK })); const expectedUserData: UserReposState[] = [ { name: 'Repo-test', From 6a5a3e5d2e67670aaecf15e2b2609caa49190b61 Mon Sep 17 00:00:00 2001 From: SDaian Date: Wed, 6 Jul 2022 12:15:53 +0200 Subject: [PATCH 5/8] Remove unnecesary params --- angular-ngrx-scss/src/app/user/services/user.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/angular-ngrx-scss/src/app/user/services/user.service.ts b/angular-ngrx-scss/src/app/user/services/user.service.ts index 6c041a0e5..4328c7c0e 100644 --- a/angular-ngrx-scss/src/app/user/services/user.service.ts +++ b/angular-ngrx-scss/src/app/user/services/user.service.ts @@ -110,7 +110,7 @@ export class UserService { } getUserTopRepos(): Observable { - const url = `${environment.githubUrl}/user/repos?sort=updated&affiliation=owner,collaborator,organization_member&per_page=20'}`; + const url = `${environment.githubUrl}/user/repos?sort=updated&per_page=20'}`; return this.http.get(url).pipe( map((data) => From bf00576b8fb5fd6e9f4c398ec3cf8f8e7db32dc9 Mon Sep 17 00:00:00 2001 From: SDaian Date: Wed, 6 Jul 2022 17:33:42 +0200 Subject: [PATCH 6/8] Update params to the topRepos call --- .../src/app/user/services/user.service.ts | 65 +++++++++++-------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/angular-ngrx-scss/src/app/user/services/user.service.ts b/angular-ngrx-scss/src/app/user/services/user.service.ts index 4328c7c0e..46bb615e1 100644 --- a/angular-ngrx-scss/src/app/user/services/user.service.ts +++ b/angular-ngrx-scss/src/app/user/services/user.service.ts @@ -1,4 +1,4 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { map, Observable } from 'rxjs'; import { @@ -110,33 +110,44 @@ export class UserService { } getUserTopRepos(): Observable { - const url = `${environment.githubUrl}/user/repos?sort=updated&per_page=20'}`; + const defaultParams = { + sort: 'updated', + per_page: 20, + }; - return this.http.get(url).pipe( - map((data) => - data.map((repo) => ({ - name: repo.name, - description: repo.description, - language: repo.language, - stargazers_count: repo.stargazers_count, - forks_count: repo.forks_count, - private: repo.private, - updated_at: repo.updated_at, - license: repo.license - ? { - key: repo.license.key, - name: repo.license.name, - spdx_id: repo.license.spdx_id, - url: repo.license.url, - node_id: repo.license.node_id, - } - : null, - owner: { - login: repo.owner.login, - }, - })), - ), - ); + const url = `${environment.githubUrl}/user/repos`; + + return this.http + .get(url, { + params: new HttpParams({ + fromObject: { ...Object.assign(defaultParams) }, + }), + }) + .pipe( + map((data) => + data.map((repo) => ({ + name: repo.name, + description: repo.description, + language: repo.language, + stargazers_count: repo.stargazers_count, + forks_count: repo.forks_count, + private: repo.private, + updated_at: repo.updated_at, + license: repo.license + ? { + key: repo.license.key, + name: repo.license.name, + spdx_id: repo.license.spdx_id, + url: repo.license.url, + node_id: repo.license.node_id, + } + : null, + owner: { + login: repo.owner.login, + }, + })), + ), + ); } getUserGists(username: string): Observable { From d16ebb64ae939288e4b6913177d2a51776ee99cb Mon Sep 17 00:00:00 2001 From: SDaian Date: Wed, 6 Jul 2022 21:43:06 +0200 Subject: [PATCH 7/8] Added disabled feature for view-all --- .../home/top-repositories/top-repositories.component.html | 4 +++- .../home/top-repositories/top-repositories.component.scss | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html index b00a56a32..b675a1b71 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html @@ -7,7 +7,9 @@

Top Repositories

diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss index ddbc3ddcd..5919b2917 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.scss @@ -12,10 +12,10 @@ background-color: variables.$white; border-radius: 0.5rem; border-width: 1px; - padding-left: 2rem; } .repo-section { padding: 2rem 0; + padding-left: 2rem; border-bottom: 1px solid variables.$gray300; } .view-all-link { @@ -26,6 +26,10 @@ a { color: inherit; font-weight: 600; + &.disabled { + color: variables.$gray300; + cursor: not-allowed; + } } } } From 608fa1573c3eea020f68440e07a6de4eafe5952f Mon Sep 17 00:00:00 2001 From: SDaian Date: Wed, 6 Jul 2022 21:45:49 +0200 Subject: [PATCH 8/8] fix format --- .../app/home/top-repositories/top-repositories.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html index b675a1b71..23015e6d4 100644 --- a/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html +++ b/angular-ngrx-scss/src/app/home/top-repositories/top-repositories.component.html @@ -8,7 +8,9 @@

Top Repositories