Changeset b9d7ae5 for src/Clients/Angular/finki-chattery
- Timestamp:
- 11/03/21 16:43:08 (3 years ago)
- Branches:
- dev
- Children:
- 6901f8b, 91bfcf4
- Parents:
- 80e2fe0 (diff), 2a9d9d1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/Clients/Angular/finki-chattery/src
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts
r80e2fe0 rb9d7ae5 24 24 public user: ApplicationUser | null = null; 25 25 public oidcUser: User | null = null; 26 public selfUser: SelfUserResponse | null = null; 26 27 27 28 constructor(private baseApi: BaseApiService) { … … 35 36 user?.profile.isVerified 36 37 ); 38 39 this.selfUserDto().subscribe((selfUser) => { 40 if (selfUser) { 41 this.selfUser = selfUser; 42 } 43 }); 37 44 }); 38 45 } … … 86 93 user.profile.isVerified 87 94 ); 95 96 if (!this.selfUser) { 97 this.selfUserDto().subscribe((selfUser) => { 98 if (selfUser) { 99 this.selfUser = selfUser; 100 } 101 }); 102 } 88 103 }); 89 104 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
r80e2fe0 rb9d7ae5 3 3 import { Action, Store } from '@ngrx/store'; 4 4 import { Observable, Subject } from 'rxjs'; 5 import { filter } from 'rxjs/operators';5 import { filter, map } from 'rxjs/operators'; 6 6 7 7 import { … … 12 12 VoteType 13 13 } from 'src/app/shared-app/models'; 14 import { AuthService } from '../services'; 14 15 import { 15 16 EffectStartedWorking, … … 18 19 GetQuestionState, 19 20 GetSearchQuestions, 21 SetCorrectAnswer, 20 22 VoteAnswer 21 23 } from './question-state/question.actions'; … … 31 33 effectWorking$: Observable<boolean | HttpErrorResponse>; 32 34 33 constructor(private store: Store<QuestionState> ) {35 constructor(private store: Store<QuestionState>, private auth: AuthService) { 34 36 this.effectWorking$ = this.store.select(questionStateQuery.effectWorking).pipe(filter((effect) => effect !== null)); 37 } 38 39 public currentQuestionOwnedByCurrentUser(): Observable<boolean> { 40 return this.getQuestion().pipe(map((question) => this.auth.selfUser?.student?.uid === question.student.uid)); 35 41 } 36 42 … … 71 77 } 72 78 79 public setCorrectAnswer(questionUid: string, answerUid: string): void { 80 this.dispatchEffect(new SetCorrectAnswer(questionUid, answerUid)); 81 } 82 73 83 public voteAnswer(answerUid: string, questionUid: string, voteType: VoteType): void { 74 84 this.dispatchEffect(new VoteAnswer(questionUid, answerUid, voteType)); -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
r80e2fe0 rb9d7ae5 13 13 GetQuestionState = '[Question] Get state', 14 14 GetQuestionStateSuccess = '[Question] Get state success', 15 SetCorrectAnswer = '[Question] Set Correct Answer', 16 SetCorrectAnswerSuccess = '[Question] Set Correct Answer success', 15 17 GetPreviewQuestionsLatest = '[Question] Get preview questions Latest', 16 18 GetPreviewQuestionsLatestSuccess = '[Question] Get preview questions Latest Success', … … 36 38 37 39 constructor(public payload: QuestionStateViewModel) {} 40 } 41 42 export class SetCorrectAnswer implements Action { 43 readonly type = QuestionActionTypes.SetCorrectAnswer; 44 45 constructor(public questionUid: string, public answerUid: string) {} 46 } 47 48 export class SetCorrectAnswerSuccess implements Action { 49 readonly type = QuestionActionTypes.SetCorrectAnswerSuccess; 50 51 constructor(public payload: string) {} 38 52 } 39 53 … … 110 124 | GetSearchQuestionsSuccess 111 125 | VoteAnswerSuccess 126 | SetCorrectAnswerSuccess 112 127 | EffectStartedWorking 113 128 | EffectFinishedWorking -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
r80e2fe0 rb9d7ae5 1 1 import { Injectable } from '@angular/core'; 2 2 import { act, Actions, createEffect, ofType } from '@ngrx/effects'; 3 import { catchError, filter, mergeMap, switchMap, withLatestFrom } from 'rxjs/operators';3 import { catchError, filter, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators'; 4 4 import { PreviewQuestionsOrderEnum, SearchQuestionsQueryViewModel } from 'src/app/shared-app/models'; 5 5 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 6 6 7 7 import { BaseApiService } from 'src/app/shared-app/services/base-api.service'; 8 import { NotificationService } from '../../services/notification.service'; 8 9 import { QuestionFacadeService } from '../question-facade.service'; 9 10 import { VoteAnswerRequest } from './question-state-request.models'; … … 21 22 GetSearchQuestionsSuccess, 22 23 QuestionActionTypes, 24 SetCorrectAnswer, 25 SetCorrectAnswerSuccess, 23 26 VoteAnswer, 24 27 VoteAnswerSuccess … … 34 37 private api: BaseApiService, 35 38 private translate: TranslateFromJsonService, 36 private facade: QuestionFacadeService 39 private facade: QuestionFacadeService, 40 private notification: NotificationService 37 41 ) {} 38 42 … … 113 117 const body = new VoteAnswerRequest(action.voteType); 114 118 return this.api.post<VoteAnswerResponse>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/votes`, body).pipe( 119 tap((state) => this.notification.successNotification('sucess-vote')), 115 120 switchMap((state) => [new VoteAnswerSuccess(QuestionMapper.ToVoteAnswerViewModel(state)), new EffectFinishedWorking()]), 116 121 catchError((err) => [new EffectFinishedWorkingError(err)]) … … 119 124 ); 120 125 }); 126 127 setCorrectAnswer$ = createEffect(() => { 128 return this.actions$.pipe( 129 ofType<SetCorrectAnswer>(QuestionActionTypes.SetCorrectAnswer), 130 mergeMap((action) => { 131 return this.api.put<string>(`v1/questions/${action.questionUid}/answers/${action.answerUid}/correct`).pipe( 132 tap((state) => this.notification.successNotification('success-correct-answer')), 133 switchMap((state) => [new SetCorrectAnswerSuccess(state), new EffectFinishedWorking()]), 134 catchError((err) => [new EffectFinishedWorkingError(err)]) 135 ); 136 }) 137 ); 138 }); 121 139 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
r80e2fe0 rb9d7ae5 1 import { VoteType } from 'src/app/shared-app/models';1 import { AnswerQuestionStateViewModel, VoteType } from 'src/app/shared-app/models'; 2 2 import { QuestionAction, QuestionActionTypes } from './question.actions'; 3 3 import { initialState, QuestionState } from './question.state'; … … 61 61 }; 62 62 } 63 case QuestionActionTypes.SetCorrectAnswerSuccess: { 64 if (state.question) { 65 return { 66 ...state, 67 question: { 68 ...state.question, 69 answers: state.question.answers.map((x) => { 70 if (x.correctAnswer) { 71 return { 72 ...x, 73 correctAnswer: false 74 }; 75 } 76 if (x.uid === action.payload) { 77 return { 78 ...x, 79 correctAnswer: true 80 }; 81 } 82 return x; 83 }) 84 } 85 }; 86 } 87 88 return { 89 ...state 90 }; 91 } 63 92 case QuestionActionTypes.EffectStartedWorking: { 64 93 return { -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.html
r80e2fe0 rb9d7ae5 1 <div >1 <div class="main-div"> 2 2 <div class="vote-icons" fxLayout="column" fxLayoutAlign="center center"> 3 3 <mat-icon class="vote-icon" (click)="voted(VoteType.Upvote)" [inline]="true">arrow_drop_up</mat-icon> … … 7 7 >check</mat-icon 8 8 > 9 <mat-icon 10 *ngIf="canSetCorrectAnswer && !correct" 11 [inline]="true" 12 class="text-center text-bold green set-correct-answer" 13 (click)="setCorrectAnswer.emit()" 14 >check</mat-icon 15 > 9 16 </div> 10 17 </div> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.scss
r80e2fe0 rb9d7ae5 14 14 cursor: pointer; 15 15 } 16 17 .show-on-hover { 18 display: none; 19 } 20 21 .set-correct-answer { 22 opacity: 0.3; 23 visibility: hidden; 24 } 25 26 .main-div:hover > .vote-icons > .set-correct-answer { 27 visibility: visible; 28 } 29 30 .main-div { 31 height: 100%; 32 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/vote/vote.component.ts
r80e2fe0 rb9d7ae5 10 10 export class VoteComponent implements OnInit { 11 11 @Input() voteCount: number | undefined; 12 @Input() canSetCorrectAnswer: boolean | null = false; 12 13 @Input() correct = false; 13 14 @Output() voteClicked = new EventEmitter<VoteType>(); 15 @Output() setCorrectAnswer = new EventEmitter<void>(); 14 16 15 17 VoteType = VoteType; -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
r80e2fe0 rb9d7ae5 15 15 <div fxLayout="row wrap" fxLayoutAlign="space-around none"> 16 16 <app-vote 17 [canSetCorrectAnswer]="canSetCorrectAnswer | async" 17 18 [voteCount]="answer.votesCount" 18 19 [correct]="answer.correctAnswer" 19 20 (voteClicked)="answerVoted($event, answer.uid, question.uid)" 21 (setCorrectAnswer)="setCorrectAnswer(question.uid, answer.uid)" 20 22 fxFlex="6%" 21 23 ></app-vote> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts
r80e2fe0 rb9d7ae5 13 13 }) 14 14 export class QuestionPreviewComponent implements OnInit { 15 canSetCorrectAnswer = this.questionFacade.currentQuestionOwnedByCurrentUser(); 15 16 question!: QuestionStateViewModel; 16 17 working = true; … … 34 35 this.questionFacade.voteAnswer(answerUid, questionUid, voteType); 35 36 } 37 38 setCorrectAnswer(questionUid: string, answerUid: string): void { 39 this.questionFacade.setCorrectAnswer(questionUid, answerUid); 40 } 36 41 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/user.models.ts
r80e2fe0 rb9d7ae5 9 9 } 10 10 11 export class SelfUserResponse {12 uid!: string;13 }14 15 11 export enum ApplicationUserType { 16 12 Student = 'Student', … … 19 15 Guest = 'Guest' 20 16 } 17 18 export class SelfUserResponse { 19 public student?: StudentSelfResponse | null; 20 public teacher?: TeacherSelfResponse | null; 21 public moderator?: ModeratorSelfResponse | null; 22 } 23 24 export class StudentSelfResponse { 25 public uid!: string; 26 public applicationUserId!: number; 27 public index!: string; 28 public reputation!: number; 29 public imageUrl!: string; 30 public questions!: StudentQuestionResponse[]; 31 public teams!: StudentTeamResponse[]; 32 } 33 34 export class StudentQuestionResponse { 35 public questionUid!: string; 36 public title!: string; 37 } 38 39 export class StudentTeamResponse { 40 public teamUid!: string; 41 public name!: string; 42 } 43 44 export class ModeratorSelfResponse { 45 public uid!: string; 46 public applicationUserId!: number; 47 } 48 49 export class TeacherSelfResponse { 50 public uid!: string; 51 public applicationUserId!: number; 52 public teams!: TeacherTeamResponse[]; 53 } 54 55 export class TeacherTeamResponse { 56 public teamUid!: string; 57 public name!: string; 58 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/services/base-api.service.ts
r80e2fe0 rb9d7ae5 19 19 20 20 public getSelfUser(): Observable<SelfUserResponse> { 21 return this.get<SelfUserResponse>(' self');21 return this.get<SelfUserResponse>('v1/self'); 22 22 } 23 23 -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r80e2fe0 rb9d7ae5 53 53 "ask-question-stepper-ask": "Ask question", 54 54 "ask-question-ask-button-back": "Edit question", 55 "sucess-vote": "Successfully voted answer", 56 "success-correct-answer": "Successfully set correct answer", 55 57 "ask-question-ask-button": "Ask question", 56 58 "AnswerAlreadyUpvoted": "You have already upvoted this answer",
Note:
See TracChangeset
for help on using the changeset viewer.