Changes in / [91bfcf4:dd264cb]
- Location:
- src
- Files:
-
- 11 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
r91bfcf4 rdd264cb 19 19 GetQuestionState, 20 20 GetSearchQuestions, 21 RespondToAnswer, 21 22 SetCorrectAnswer, 22 23 VoteAnswer … … 85 86 } 86 87 88 public respondToAnswer(answerUid: string, questionUid: string, text: string): void { 89 this.dispatchEffect(new RespondToAnswer(questionUid, answerUid, text)); 90 } 91 87 92 public fetchQuestion(questionUid: string): void { 88 93 this.dispatchEffect(new GetQuestionState(questionUid)); -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state-request.models.ts
r91bfcf4 rdd264cb 4 4 constructor(public voteType: VoteType) {} 5 5 } 6 7 export class RespondToAnswerRequest { 8 constructor(public text: string) {} 9 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
r91bfcf4 rdd264cb 3 3 4 4 import { 5 AnswerResponseQuestionStateViewModel, 5 6 PreviewQuestionViewModel, 6 7 QuestionStateViewModel, … … 13 14 GetQuestionState = '[Question] Get state', 14 15 GetQuestionStateSuccess = '[Question] Get state success', 16 RespondToAnswer = '[Question] RespondToAnswer', 17 RespondToAnswerSuccess = '[Question] RespondToAnswer success', 15 18 SetCorrectAnswer = '[Question] Set Correct Answer', 16 19 SetCorrectAnswerSuccess = '[Question] Set Correct Answer success', … … 100 103 } 101 104 105 export class RespondToAnswer implements Action { 106 readonly type = QuestionActionTypes.RespondToAnswer; 107 108 constructor(public questionUid: string, public answerUid: string, public text: string) {} 109 } 110 111 export class RespondToAnswerSuccess implements Action { 112 readonly type = QuestionActionTypes.RespondToAnswerSuccess; 113 114 constructor(public payload: AnswerResponseQuestionStateViewModel, public answerUid: string) {} 115 } 116 102 117 export class EffectStartedWorking implements Action { 103 118 readonly type = QuestionActionTypes.EffectStartedWorking; … … 125 140 | VoteAnswerSuccess 126 141 | SetCorrectAnswerSuccess 142 | RespondToAnswerSuccess 127 143 | EffectStartedWorking 128 144 | EffectFinishedWorking -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
r91bfcf4 rdd264cb 8 8 import { NotificationService } from '../../services/notification.service'; 9 9 import { QuestionFacadeService } from '../question-facade.service'; 10 import { VoteAnswerRequest } from './question-state-request.models'; 11 import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models'; 10 import { RespondToAnswerRequest, VoteAnswerRequest } from './question-state-request.models'; 11 import { 12 AnswerResponseQuestionStateResponse, 13 PreviewQuestionResponse, 14 QuestionStateResponse, 15 VoteAnswerResponse 16 } from './question-state-response.models'; 12 17 import { 13 18 EffectFinishedWorking, … … 22 27 GetSearchQuestionsSuccess, 23 28 QuestionActionTypes, 29 RespondToAnswer, 30 RespondToAnswerSuccess, 24 31 SetCorrectAnswer, 25 32 SetCorrectAnswerSuccess, … … 137 144 ); 138 145 }); 146 147 respondToAnswer$ = createEffect(() => { 148 return this.actions$.pipe( 149 ofType<RespondToAnswer>(QuestionActionTypes.RespondToAnswer), 150 mergeMap((action) => { 151 return this.api 152 .post<AnswerResponseQuestionStateResponse>( 153 `v1/questions/${action.questionUid}/answers/${action.answerUid}/answerresponses`, 154 new RespondToAnswerRequest(action.text) 155 ) 156 .pipe( 157 tap((state) => this.notification.successNotification('success-answer-response')), 158 switchMap((state) => [ 159 new RespondToAnswerSuccess(QuestionMapper.ToAnswerResponseQuestionStateViewModel(state), action.answerUid), 160 new EffectFinishedWorking() 161 ]), 162 catchError((err) => [new EffectFinishedWorkingError(err)]) 163 ); 164 }) 165 ); 166 }); 139 167 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
r91bfcf4 rdd264cb 14 14 } from 'src/app/shared-app/models'; 15 15 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 16 import { PreviewQuestionResponse, QuestionStateResponse, VoteAnswerResponse } from './question-state-response.models'; 16 import { 17 AnswerResponseQuestionStateResponse, 18 PreviewQuestionResponse, 19 QuestionStateResponse, 20 VoteAnswerResponse 21 } from './question-state-response.models'; 17 22 18 23 export class QuestionMapper { … … 118 123 return new VoteAnswerViewModel(response.answerUid, response.voteUid, response.voteType); 119 124 } 125 126 public static ToAnswerResponseQuestionStateViewModel( 127 response: AnswerResponseQuestionStateResponse 128 ): AnswerResponseQuestionStateViewModel { 129 const answerResponseStudent = new AnswerResponseStudentQuestionStateViewModel( 130 response.studentResponse.uid, 131 response.studentResponse.index, 132 response.studentResponse.imageUrl, 133 response.studentResponse.reputation 134 ); 135 136 return new AnswerResponseQuestionStateViewModel(response.uid, response.text, moment(response.createdOn), answerResponseStudent); 137 } 120 138 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
r91bfcf4 rdd264cb 90 90 }; 91 91 } 92 case QuestionActionTypes.RespondToAnswerSuccess: { 93 if (state.question) { 94 return { 95 ...state, 96 question: { 97 ...state.question, 98 answers: state.question.answers.map((x) => { 99 if (x.uid === action.answerUid) { 100 return { 101 ...x, 102 answerResponses: [...x.answerResponses, action.payload] 103 }; 104 } 105 106 return x; 107 }) 108 } 109 }; 110 } 111 112 return { 113 ...state 114 }; 115 } 92 116 case QuestionActionTypes.EffectStartedWorking: { 93 117 return { -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts
r91bfcf4 rdd264cb 9 9 import { PreviewQuestionFullComponent } from './question/preview-question-full/preview-question-full.component'; 10 10 import { QuestionPreviewComponent } from './question/question-preview/question-preview.component'; 11 import { RespondToAnswerDialogComponent } from './question/respond-to-answer-dialog/respond-to-answer-dialog.component'; 11 12 import { SearchQuestionComponent } from './question/search-question/search-question.component'; 12 13 import { StudentCardComponent } from './question/student-card/student-card.component'; … … 24 25 AskQuestionSharedComponent, 25 26 PreviewQuestionFullComponent, 26 TextEditorComponent 27 TextEditorComponent, 28 RespondToAnswerDialogComponent 27 29 ]; -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
r91bfcf4 rdd264cb 45 45 <div *ngFor="let answerResponse of answer.answerResponses"> 46 46 {{ answerResponse.text }} 47 <mat-chip class="cursor" selected>{{ answerResponse.student.index }}</mat-chip> -47 <mat-chip class="cursor">{{ answerResponse.student.index }}</mat-chip> - 48 48 {{ answerResponse.createdOn | momentDate: 'LL' }} 49 49 <hr /> … … 52 52 </div> 53 53 </mat-card-content> 54 <mat-card-actions> </mat-card-actions> 54 <mat-card-actions> 55 <app-button (action)="openRespondToAnswerDialog(answer.uid)" [buttonType]="ButtonType.Basic">{{ 56 'question-preview-respond-to-answer-button' | translate 57 }}</app-button> 58 </mat-card-actions> 55 59 </mat-card> 56 60 </ng-container> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.ts
r91bfcf4 rdd264cb 5 5 6 6 import { QuestionStateViewModel, VoteType } from 'src/app/shared-app/models'; 7 import { SharedDialogService } from 'src/app/shared-app/services/shared-dialog.service'; 7 8 import { ButtonType } from '../../generic/button/button.models'; 8 9 … … 17 18 working = true; 18 19 ButtonType = ButtonType; 19 constructor(private questionFacade: QuestionFacadeService, private notification: NotificationService) {} 20 constructor( 21 private questionFacade: QuestionFacadeService, 22 private notification: NotificationService, 23 private dialog: SharedDialogService 24 ) {} 20 25 21 26 ngOnInit(): void { … … 39 44 this.questionFacade.setCorrectAnswer(questionUid, answerUid); 40 45 } 46 47 openRespondToAnswerDialog(answerUid: string): void { 48 this.dialog.respondToAnswer(this.question.uid, answerUid); 49 } 41 50 } -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r91bfcf4 rdd264cb 55 55 "sucess-vote": "Successfully voted answer", 56 56 "success-correct-answer": "Successfully set correct answer", 57 "success-answer-response": "Successfully responded to answer", 57 58 "ask-question-ask-button": "Ask question", 59 "question-preview-respond-to-answer-button": "Respond to answer", 60 "respond-to-answer-title": "Respond to answer", 61 "respond-to-answer-title-text-placeholder": "Response text", 62 "close-button": "Close", 63 "submit-button": "Submit", 58 64 "AnswerAlreadyUpvoted": "You have already upvoted this answer", 59 65 "AnswerAlreadyDownvoted": "You have already downvoted this answer", -
src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs
r91bfcf4 rdd264cb 48 48 var answerResponseStudent = new AnswerResponseStudentQuestionStateResponse(y.StudentDto.Id, y.StudentDto.Uid, y.StudentDto.Index, y.StudentDto.ImageUrl, y.StudentDto.Reputation); 49 49 50 return new AnswerResponseQuestionStateResponse(y.Id, y.Uid, y.Text, y.CreatedOn, answerResponseStudent);50 return ToAnswerResponseQuestionStateResponse(y); 51 51 }); 52 52 } … … 76 76 return new QuestionStateResponse(questionState.Id, questionState.Uid, questionState.Title, questionState.Text, questionState.CreatedOn, questionState.Views, questionState.LastActiveOn, student, answers, questionCategories, team); 77 77 } 78 79 public static AnswerResponseQuestionStateResponse ToAnswerResponseQuestionStateResponse(this AnswerResponseQuestionStateDto dto) 80 { 81 var answerResponseStudent = new AnswerResponseStudentQuestionStateResponse(dto.StudentDto.Id, dto.StudentDto.Uid, dto.StudentDto.Index, dto.StudentDto.ImageUrl, dto.StudentDto.Reputation); 82 83 return new AnswerResponseQuestionStateResponse(dto.Id, dto.Uid, dto.Text, dto.CreatedOn, answerResponseStudent); 84 } 78 85 } 79 86 } -
src/FinkiChattery/FinkiChattery.Commands/Questioning/QuestioningErrorCodes.cs
r91bfcf4 rdd264cb 7 7 public const string QuestionTitleLengthInvalid = "QuestionTitleLengthInvalid"; 8 8 public const string QuestionTextLengthInvalid = "QuestionTextLengthInvalid"; 9 public const string AnswerResponseTextLengthInvalid = "AnswerResponseTextLengthInvalid"; 9 10 public const string CategoriesDontExist = "CategoriesDontExist"; 10 11 public const string TeamDontExist = "TeamDontExist"; -
src/FinkiChattery/FinkiChattery.Commands/Questioning/Validators/QuestioningFluentValidationRules.cs
r91bfcf4 rdd264cb 16 16 } 17 17 18 public static IRuleBuilderOptions<T, string> AnswerResponseTextValidate<T>(this IRuleBuilder<T, string> ruleBuilder) 19 { 20 return ruleBuilder.NotNull().WithMessage(QuestioningErrorCodes.CantBeNull).MaximumLength(4000).WithMessage(QuestioningErrorCodes.AnswerResponseTextLengthInvalid); 21 } 22 18 23 public static IRuleBuilderOptions<T, string> AnswerTextValidate<T>(this IRuleBuilder<T, string> ruleBuilder) 19 24 { -
src/FinkiChattery/FinkiChattery.Persistence/Models/AnswerResponse.cs
r91bfcf4 rdd264cb 1 1 using System; 2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Threading.Tasks;6 2 7 3 namespace FinkiChattery.Persistence.Models … … 9 5 public class AnswerResponse : BaseEntity 10 6 { 7 public AnswerResponse() : base() 8 { 9 CreatedOn = DateTime.UtcNow; 10 } 11 11 12 public string Text { get; set; } 12 13 -
src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Contracts/IUnitOfWork.cs
r91bfcf4 rdd264cb 15 15 ITeacherRepo Teachers { get; } 16 16 IModeratorRepo Moderators { get; } 17 IAnswerResponseRepo AnswerResponses { get; } 17 18 Task<int> SaveAsync(); 18 19 } -
src/FinkiChattery/FinkiChattery.Persistence/UnitOfWork/Implementations/UnitOfWork.cs
r91bfcf4 rdd264cb 16 16 private ModeratorRepo _moderators; 17 17 private TeacherRepo _teachers; 18 private AnswerResponseRepo _answerResponses; 18 19 19 20 public UnitOfWork(ApplicationDbContext dbContext) 20 21 { 21 22 DbContext = dbContext; 23 } 24 25 public IAnswerResponseRepo AnswerResponses 26 { 27 get 28 { 29 if (_answerResponses == null) 30 { 31 _answerResponses = new AnswerResponseRepo(DbContext); 32 } 33 34 return _answerResponses; 35 } 22 36 } 23 37
Note:
See TracChangeset
for help on using the changeset viewer.