Changes in / [8b6791f:81c2e6f]
- Location:
- src
- Files:
-
- 1 added
- 19 deleted
- 29 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/core/state/question-facade.service.ts
r8b6791f r81c2e6f 5 5 import { catchError, filter, map } from 'rxjs/operators'; 6 6 7 import { PreviewQuestionsOrderEnum, PreviewQuestionViewModel, QuestionStateViewModel } from 'src/app/shared-app/models'; 8 import { 9 EffectStartedWorking, 10 GetPreviewQuestionsLatest, 11 GetPreviewQuestionsPopular, 12 GetQuestionState 13 } from './question-state/question.actions'; 7 import { QuestionStateViewModel } from 'src/app/shared-app/models'; 8 import { EffectStartedWorking, GetQuestionState } from './question-state/question.actions'; 14 9 import { questionStateQuery } from './question-state/question.selectors'; 15 10 import { QuestionState } from './question-state/question.state'; … … 43 38 } 44 39 45 public getPreviewQuestionsLatest(): Observable<PreviewQuestionViewModel[]> {46 return this.store.select(questionStateQuery.getPreviewQuestionsLatest);47 }48 49 public getPreviewQuestionsPopular(): Observable<PreviewQuestionViewModel[]> {50 return this.store.select(questionStateQuery.getPreviewQuestionsPopular);51 }52 53 public fetchPreviewQuestions(orderBy: PreviewQuestionsOrderEnum): void {54 if (orderBy === PreviewQuestionsOrderEnum.Latest) {55 this.fetchPreviewQuestionsLatest();56 } else if (orderBy === PreviewQuestionsOrderEnum.Popular) {57 this.fetchPreviewQuestionsPopular();58 }59 }60 61 40 public fetchQuestion(questionUid: string): void { 62 41 this.dispatchEffect(new GetQuestionState(questionUid)); 63 }64 65 private fetchPreviewQuestionsLatest(): void {66 this.dispatchEffect(new GetPreviewQuestionsLatest());67 }68 69 private fetchPreviewQuestionsPopular(): void {70 this.dispatchEffect(new GetPreviewQuestionsPopular());71 42 } 72 43 -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question-state.models.ts
r8b6791f r81c2e6f 59 59 public reputation!: number; 60 60 } 61 62 export class PreviewQuestionResponse {63 public uid!: string;64 public title!: string;65 public createdOn!: moment.Moment;66 public views!: number;67 public answersCount!: number;68 public categories!: PreviewQuestionCategoryResponse[];69 }70 71 export class PreviewQuestionCategoryResponse {72 public uid!: string;73 public text!: string;74 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.actions.ts
r8b6791f r81c2e6f 2 2 import { Action } from '@ngrx/store'; 3 3 4 import { PreviewQuestionViewModel, QuestionStateViewModel } from 'src/app/shared-app/models'; 5 import { PreviewQuestionResponse } from './question-state.models'; 4 import { QuestionStateViewModel } from 'src/app/shared-app/models'; 6 5 7 6 export enum QuestionActionTypes { 8 7 GetQuestionState = '[Question] Get state', 9 8 GetQuestionStateSuccess = '[Question] Get state success', 10 GetPreviewQuestionsLatest = '[Question] Get preview questions Latest',11 GetPreviewQuestionsLatestSuccess = '[Question] Get preview questions Latest Success',12 GetPreviewQuestionsPopular = '[Question] Get preview questions Popular',13 GetPreviewQuestionsPopularSuccess = '[Question] Get preview questions Popular Success',14 9 EffectStartedWorking = '[Question] Effect Started Working', 15 10 EffectFinishedWorking = '[Question] Effect Finished Working', … … 27 22 28 23 constructor(public payload: QuestionStateViewModel) {} 29 }30 31 export class GetPreviewQuestionsLatest implements Action {32 readonly type = QuestionActionTypes.GetPreviewQuestionsLatest;33 34 constructor() {}35 }36 37 export class GetPreviewQuestionsLatestSuccess implements Action {38 readonly type = QuestionActionTypes.GetPreviewQuestionsLatestSuccess;39 40 constructor(public payload: PreviewQuestionViewModel[]) {}41 }42 43 export class GetPreviewQuestionsPopular implements Action {44 readonly type = QuestionActionTypes.GetPreviewQuestionsPopular;45 46 constructor() {}47 }48 49 export class GetPreviewQuestionsPopularSuccess implements Action {50 readonly type = QuestionActionTypes.GetPreviewQuestionsPopularSuccess;51 52 constructor(public payload: PreviewQuestionViewModel[]) {}53 24 } 54 25 … … 71 42 } 72 43 73 export type QuestionAction = 74 | GetQuestionStateSuccess 75 | GetPreviewQuestionsLatestSuccess 76 | GetPreviewQuestionsPopularSuccess 77 | EffectStartedWorking 78 | EffectFinishedWorking 79 | EffectFinishedWorkingError; 44 export type QuestionAction = GetQuestionStateSuccess | EffectStartedWorking | EffectFinishedWorking | EffectFinishedWorkingError; -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
r8b6791f r81c2e6f 1 1 import { Injectable } from '@angular/core'; 2 2 import { Actions, createEffect, ofType } from '@ngrx/effects'; 3 import { catchError, filter, switchMap, withLatestFrom } from 'rxjs/operators'; 4 import { PreviewQuestionsOrderEnum } from 'src/app/shared-app/models'; 5 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 3 import { catchError, switchMap } from 'rxjs/operators'; 6 4 7 5 import { BaseApiService } from 'src/app/shared-app/services/base-api.service'; 8 import { QuestionFacadeService } from '../question-facade.service'; 9 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models'; 6 import { QuestionStateResponse } from './question-state.models'; 10 7 import { 11 8 EffectFinishedWorking, 12 9 EffectFinishedWorkingError, 13 GetPreviewQuestionsLatestSuccess,14 GetPreviewQuestionsPopularSuccess,15 10 GetQuestionState, 16 11 GetQuestionStateSuccess, … … 23 18 }) 24 19 export class QuestionEffects { 25 constructor( 26 private actions$: Actions, 27 private api: BaseApiService, 28 private translate: TranslateFromJsonService, 29 private facade: QuestionFacadeService 30 ) {} 20 constructor(private actions$: Actions, private api: BaseApiService) {} 31 21 32 22 getQuestionState$ = createEffect(() => { … … 41 31 ); 42 32 }); 43 44 getPreviewQuestionsLatest$ = createEffect(() => {45 return this.actions$.pipe(46 ofType<GetQuestionState>(QuestionActionTypes.GetPreviewQuestionsLatest),47 withLatestFrom(this.facade.getPreviewQuestionsLatest()),48 filter(([action, questions]) => questions.length === 0),49 switchMap((action) => {50 return this.api.get<PreviewQuestionResponse[]>(`v1/questions/preview?order=${PreviewQuestionsOrderEnum.Latest}`).pipe(51 switchMap((state) => [52 new GetPreviewQuestionsLatestSuccess(QuestionMapper.ToPreviwQuestionsViewModel(state, this.translate)),53 new EffectFinishedWorking()54 ]),55 catchError((err) => [new EffectFinishedWorkingError(err)])56 );57 })58 );59 });60 61 getPreviewQuestionsPopular$ = createEffect(() => {62 return this.actions$.pipe(63 ofType<GetQuestionState>(QuestionActionTypes.GetPreviewQuestionsPopular),64 withLatestFrom(this.facade.getPreviewQuestionsPopular()),65 filter(([action, questions]) => questions.length === 0),66 switchMap((action) => {67 return this.api.get<PreviewQuestionResponse[]>(`v1/questions/preview?order=${PreviewQuestionsOrderEnum.Popular}`).pipe(68 switchMap((state) => [69 new GetPreviewQuestionsPopularSuccess(QuestionMapper.ToPreviwQuestionsViewModel(state, this.translate)),70 new EffectFinishedWorking()71 ]),72 catchError((err) => [new EffectFinishedWorkingError(err)])73 );74 })75 );76 });77 33 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
r8b6791f r81c2e6f 5 5 AnswerResponseStudentQuestionStateViewModel, 6 6 AnswerStudentQuestionStateViewModel, 7 PreviewQuestionCategoryViewModel,8 PreviewQuestionViewModel,9 7 QuestionCategoryQuestionStateViewModel, 10 8 QuestionStateViewModel, … … 12 10 TeamQuestionStateViewModel 13 11 } from 'src/app/shared-app/models'; 14 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 15 import { PreviewQuestionCategoryResponse, PreviewQuestionResponse, QuestionStateResponse } from './question-state.models'; 12 import { QuestionStateResponse } from './question-state.models'; 16 13 17 14 export class QuestionMapper { … … 87 84 ); 88 85 } 89 90 public static ToPreviwQuestionsViewModel(91 previewQuestionsResponse: PreviewQuestionResponse[],92 translate: TranslateFromJsonService93 ): PreviewQuestionViewModel[] {94 let questions = new Array<PreviewQuestionViewModel>();95 96 if (previewQuestionsResponse.length > 0) {97 questions = previewQuestionsResponse.map((x) => {98 let categories = new Array<PreviewQuestionCategoryViewModel>();99 100 if (x.categories.length > 0) {101 categories = x.categories.map((y) => new PreviewQuestionCategoryViewModel(y.uid, y.text, translate.instant(y.text)));102 }103 104 return new PreviewQuestionViewModel(x.uid, x.title, moment(x.createdOn), x.views, x.answersCount, categories);105 });106 }107 108 return questions;109 }110 86 } -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.reducers.ts
r8b6791f r81c2e6f 8 8 ...state, 9 9 question: action.payload 10 };11 case QuestionActionTypes.GetPreviewQuestionsLatestSuccess:12 return {13 ...state,14 previewQuestionsLatest: action.payload15 };16 case QuestionActionTypes.GetPreviewQuestionsPopularSuccess:17 return {18 ...state,19 previewQuestionsPopular: action.payload20 10 }; 21 11 case QuestionActionTypes.EffectStartedWorking: { -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.selectors.ts
r8b6791f r81c2e6f 5 5 6 6 const getQuestion = createSelector(getQuestionState, (state) => state.question); 7 const getPreviewQuestionsLatest = createSelector(getQuestionState, (state) => state.previewQuestionsLatest);8 const getPreviewQuestionsPopular = createSelector(getQuestionState, (state) => state.previewQuestionsPopular);9 7 const effectWorking = createSelector(getQuestionState, (state) => state.effectWorking); 10 8 11 9 export const questionStateQuery = { 12 10 effectWorking, 13 getQuestion, 14 getPreviewQuestionsLatest, 15 getPreviewQuestionsPopular 11 getQuestion 16 12 }; -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.state.ts
r8b6791f r81c2e6f 1 1 import { HttpErrorResponse } from '@angular/common/http'; 2 import { PreviewQuestionViewModel,QuestionStateViewModel } from 'src/app/shared-app/models';2 import { QuestionStateViewModel } from 'src/app/shared-app/models'; 3 3 4 4 export const questionStateKey = 'question'; … … 6 6 export interface QuestionState { 7 7 question: QuestionStateViewModel | null; 8 previewQuestionsLatest: PreviewQuestionViewModel[];9 previewQuestionsPopular: PreviewQuestionViewModel[];10 8 effectWorking: boolean | HttpErrorResponse; 11 9 } … … 13 11 export const initialState: QuestionState = { 14 12 question: null, 15 previewQuestionsLatest: [],16 previewQuestionsPopular: [],17 13 effectWorking: false 18 14 }; -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questioning-components.ts
r8b6791f r81c2e6f 1 1 import { QuestionPreviewGeneralComponent } from './question-preview-general/question-preview-general.component'; 2 import { QuestioningGeneralComponent } from './questioning-general/questioning-general.component';3 2 import { QuestionsPreviewGeneralComponent } from './questions-preview-general/questions-preview-general.component'; 4 3 5 export const QUESTIONING_COMPONENTS: any[] = [ 6 QuestionPreviewGeneralComponent, 7 QuestionsPreviewGeneralComponent, 8 QuestioningGeneralComponent 9 ]; 4 export const QUESTIONING_COMPONENTS: any[] = [QuestionPreviewGeneralComponent, QuestionsPreviewGeneralComponent]; -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questions-preview-general/questions-preview-general.component.html
r8b6791f r81c2e6f 1 <app-search-question></app-search-question> 2 <div class="margin-x-lg"> 3 <h1 class="mat-headline">{{ 'questions-preview' | translate }}</h1> 4 <mat-button-toggle-group [formControl]="questionsSortByForm"> 5 <mat-button-toggle [value]="QuestionsSortBy.Latest">{{ 'question-sort-newest' | translate }}</mat-button-toggle> 6 <mat-button-toggle [value]="QuestionsSortBy.Popular">{{ 'question-sort-popular' | translate }}</mat-button-toggle> 7 </mat-button-toggle-group> 8 </div> 9 <app-preview-question-display 10 *ngFor="let question of previewQuestions$ | async" 11 [question]="question" 12 (questionClicked)="goToQuestion(question.uid)" 13 ></app-preview-question-display> 1 <p>questions-preview-general works!</p> -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questions-preview-general/questions-preview-general.component.ts
r8b6791f r81c2e6f 1 1 import { Component, OnInit } from '@angular/core'; 2 import { FormControl } from '@angular/forms';3 import { Router } from '@angular/router';4 2 import { CategoryFacadeService } from 'src/app/core/state/category-facade.service'; 5 import { QuestionFacadeService } from 'src/app/core/state/question-facade.service';6 import { CategoryStateViewModel, PreviewQuestionsOrderEnum } from 'src/app/shared-app/models';7 3 8 4 @Component({ … … 12 8 }) 13 9 export class QuestionsPreviewGeneralComponent implements OnInit { 14 categories?: CategoryStateViewModel[]; 15 previewQuestions$ = this.questionFacade.getPreviewQuestionsLatest(); 16 QuestionsSortBy = PreviewQuestionsOrderEnum; 17 questionsSortByForm = new FormControl(PreviewQuestionsOrderEnum.Latest); 18 19 constructor(private categoriesFacade: CategoryFacadeService, private questionFacade: QuestionFacadeService, private router: Router) {} 10 constructor(private categoriesFacade: CategoryFacadeService) {} 20 11 21 12 ngOnInit(): void { 22 13 this.categoriesFacade.fetchCategories(); 23 this.questionFacade.fetchPreviewQuestions(PreviewQuestionsOrderEnum.Latest);24 this.questionsSortByForm.valueChanges.subscribe((value: PreviewQuestionsOrderEnum) => {25 this.questionFacade.fetchPreviewQuestions(value);26 27 if (value === PreviewQuestionsOrderEnum.Latest) {28 this.previewQuestions$ = this.questionFacade.getPreviewQuestionsLatest();29 } else if (value === PreviewQuestionsOrderEnum.Popular) {30 this.previewQuestions$ = this.questionFacade.getPreviewQuestionsPopular();31 }32 });33 }34 35 goToQuestion(uid: string): void {36 this.router.navigateByUrl(`questioning/${uid}`);37 14 } 38 15 } -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/questioning.routes.ts
r8b6791f r81c2e6f 2 2 import { Routes, RouterModule } from '@angular/router'; 3 3 import { QuestionPreviewGeneralComponent } from './components/question-preview-general/question-preview-general.component'; 4 import { QuestioningGeneralComponent } from './components/questioning-general/questioning-general.component';5 4 import { QuestionsPreviewGeneralComponent } from './components/questions-preview-general/questions-preview-general.component'; 6 5 7 6 const routes: Routes = [ 8 7 { 9 component: QuestioningGeneralComponent, 10 path: '', 11 children: [ 12 { 13 path: 'preview', 14 pathMatch: 'full', 15 component: QuestionsPreviewGeneralComponent 16 }, 17 { 18 path: ':questionUid', 19 component: QuestionPreviewGeneralComponent 20 } 21 ] 8 path: 'preview', 9 pathMatch: 'full', 10 component: QuestionsPreviewGeneralComponent 11 }, 12 { 13 path: ':questionUid', 14 component: QuestionPreviewGeneralComponent 22 15 } 23 16 ]; -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts
r8b6791f r81c2e6f 4 4 import { HeaderComponent } from './generic/header/header.component'; 5 5 import { VoteComponent } from './generic/vote/vote.component'; 6 import { PreviewQuestionDisplayComponent } from './question/preview-question-display/preview-question-display.component';7 6 import { QuestionPreviewComponent } from './question/question-preview/question-preview.component'; 8 import { SearchQuestionComponent } from './question/search-question/search-question.component';9 7 import { StudentCardComponent } from './question/student-card/student-card.component'; 10 8 … … 16 14 VoteComponent, 17 15 StudentCardComponent, 18 HeaderComponent, 19 SearchQuestionComponent, 20 PreviewQuestionDisplayComponent 16 HeaderComponent 21 17 ]; -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/index.ts
r8b6791f r81c2e6f 3 3 export * from './question-state-view-models.models'; 4 4 export * from './category-state-view-models.models'; 5 export * from './question-state-enums.models'; -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts
r8b6791f r81c2e6f 54 54 constructor(public uid: string, public index: string, public imageUrl: string, public reputation: number) {} 55 55 } 56 57 export class PreviewQuestionViewModel {58 constructor(59 public uid: string,60 public title: string,61 public createdOn: moment.Moment,62 public views: number,63 public answersCount: number,64 public categories: PreviewQuestionCategoryViewModel[]65 ) {}66 }67 68 export class PreviewQuestionCategoryViewModel {69 constructor(public uid: string, public text: string, public nameTranslated: string) {}70 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/pipes/moment-date.pipe.ts
r8b6791f r81c2e6f 6 6 }) 7 7 export class MomentDatePipe implements PipeTransform { 8 transform(value: moment.Moment | undefined | null, dateFormat: string): any {8 transform(value: moment.Moment, dateFormat: string): any { 9 9 return moment(value).format(dateFormat); 10 10 } -
src/Clients/Angular/finki-chattery/src/app/shared-material/shared-material.module.ts
r8b6791f r81c2e6f 23 23 import { MatTooltipModule } from '@angular/material/tooltip'; 24 24 import { MatButtonToggleModule } from '@angular/material/button-toggle'; 25 import { MatBadgeModule } from '@angular/material/badge';26 25 27 26 @NgModule({ … … 48 47 MatChipsModule, 49 48 MatTooltipModule, 50 MatButtonToggleModule, 51 MatBadgeModule 49 MatButtonToggleModule 52 50 ], 53 51 exports: [ … … 72 70 MatChipsModule, 73 71 MatTooltipModule, 74 MatButtonToggleModule, 75 MatBadgeModule 72 MatButtonToggleModule 76 73 ] 77 74 }) -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r8b6791f r81c2e6f 28 28 "software-engineering": "Software engineering", 29 29 "visual-programming": "Visual programming", 30 "operating-systems": "Operating systems", 31 "internet-programming": "Internet programming", 32 "object-oriented-programming": "Object oriented programming", 33 "calculus": "Calculus", 34 "discrete-mathematics": "Discrete mathematics", 35 "web-programming": "Web programming", 36 "advanced-programming": "Advanced programming", 37 "questions-preview-find-question": "Search for a question", 38 "questions-preview-find-question-categories": "Search in categories", 39 "questions-search": "Search", 40 "questions-preview": "Preview questions", 41 "question-sort-newest": "Newest", 42 "question-sort-popular": "Most popular", 43 "questions-preview-question-subtitle": "Asked on: {{date}}", 44 "questions-preview-question-answers": "Answers", 45 "questions-preview-question-views": "Views" 30 "operating-systems": "Operating systems" 46 31 } -
src/Clients/Angular/finki-chattery/src/styles.scss
r8b6791f r81c2e6f 285 285 z-index: 1100 !important; 286 286 } 287 288 .full-width {289 width: 100%;290 } -
src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/CategoryMapper.cs
r8b6791f r81c2e6f 1 using FinkiChattery.Contracts.Questioning ;1 using FinkiChattery.Contracts.Questioning.GetCategories; 2 2 using FinkiChattery.Persistence.Models; 3 3 using System.Collections.Generic; … … 8 8 public static class CategoryMapper 9 9 { 10 public static List<Category Response> ToCategoryDtos(this IEnumerable<Category> categories)10 public static List<CategoryDto> ToCategoryDtos(this IEnumerable<Category> categories) 11 11 { 12 var categoryDtos = new List<Category Response>();12 var categoryDtos = new List<CategoryDto>(); 13 13 14 14 if (categories.Any()) 15 15 { 16 categoryDtos = categories.Select(x => new Category Response(x.Uid, x.Name)).ToList();16 categoryDtos = categories.Select(x => new CategoryDto(x.Uid, x.Name)).ToList(); 17 17 } 18 18 -
src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Questioning/Mapper/QuestionMapper.cs
r8b6791f r81c2e6f 1 1 #nullable enable 2 2 3 using FinkiChattery.Contracts.Questioning ;3 using FinkiChattery.Contracts.Questioning.GetQuestionState; 4 4 using FinkiChattery.Persistence.Repositories.Contracts; 5 5 using System.Collections.Generic; … … 10 10 public static class QuestionMapper 11 11 { 12 public static List<PreviewQuestionResponse> ToPreviewQuestionsResponse(this IEnumerable<QuestionPreviewDto> questions)13 {14 var questionsResponse = new List<PreviewQuestionResponse>();15 16 if (questions.Any())17 {18 questionsResponse = questions.Select(x =>19 {20 var questionCategoriesResponse = new List<PreviewQuestionCategoryResponse>();21 22 if (x.Categories.Any())23 {24 questionCategoriesResponse = x.Categories.Select(y => new PreviewQuestionCategoryResponse(y.Id, y.Uid, y.Text)).ToList();25 }26 27 return new PreviewQuestionResponse(x.Id, x.Uid, x.Title, x.Views, x.AnswersCount, x.CreatedOn, questionCategoriesResponse);28 }).ToList();29 }30 31 return questionsResponse;32 }33 34 12 public static QuestionStateResponse ToQuestionStateResponse(this QuestionStateDto questionState) 35 13 { -
src/FinkiChattery/FinkiChattery.Api/Controllers/v1/QuestionsController.cs
r8b6791f r81c2e6f 40 40 return Ok(questionDto.ToQuestionStateResponse()); 41 41 } 42 43 [HttpGet("preview")]44 [Authorize]45 public async Task<IActionResult> PreviewQuestions([FromQuery] GetPreviewQuestionsOrderEnum order)46 {47 var questions = await MediatorService.SendQueryAsync(new GetPreviewQuestionsQuery(order));48 return Ok(questions.ToPreviewQuestionsResponse());49 }50 42 } 51 43 } -
src/FinkiChattery/FinkiChattery.Contracts/Questioning/GetQuestionState/QuestionStateResponse.cs
r8b6791f r81c2e6f 5 5 using System.Text.Json.Serialization; 6 6 7 namespace FinkiChattery.Contracts.Questioning 7 namespace FinkiChattery.Contracts.Questioning.GetQuestionState 8 8 { 9 9 public class QuestionStateResponse -
src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Question/Question.Debug.Seed.sql
r8b6791f r81c2e6f 9 9 VALUES 10 10 (1, N'aee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Question 1', 'Question 1 text', 1, GETUTCDATE(), NULL, 0, 11 GETUTCDATE() , 211 GETUTCDATE() 12 12 ), 13 13 (2, N'bee193c3-9d36-4ed8-81b2-15eb4ff305f1', N'Question 2', 'Question 2 text', 1, GETUTCDATE(), NULL, 0, 14 GETUTCDATE() , 214 GETUTCDATE() 15 15 ) 16 ) AS temp ([ID], [Uid], [Title], [Text], [StudentFk], [CreatedOn], [TeamFk], [Views], [LastActiveOn] , [AnswersCount])16 ) AS temp ([ID], [Uid], [Title], [Text], [StudentFk], [CreatedOn], [TeamFk], [Views], [LastActiveOn]) 17 17 ) AS S 18 18 ON T.[ID] = S.[ID] … … 25 25 T.[TeamFk] = S.[TeamFk], 26 26 T.[Views] = S.[Views], 27 T.[LastActiveOn] = S.[LastActiveOn], 28 T.[AnswersCount] = S.[AnswersCount] 27 T.[LastActiveOn] = S.[LastActiveOn] 29 28 WHEN NOT MATCHED THEN 30 29 INSERT … … 38 37 [TeamFk], 39 38 [Views], 40 [LastActiveOn], 41 [AnswersCount] 39 [LastActiveOn] 42 40 ) 43 41 VALUES 44 (S.[ID], S.[Uid], S.[Title], S.[Text], S.[StudentFk], S.[CreatedOn], S.[TeamFk], S.[Views], S.[LastActiveOn] , S.[AnswersCount]);42 (S.[ID], S.[Uid], S.[Title], S.[Text], S.[StudentFk], S.[CreatedOn], S.[TeamFk], S.[Views], S.[LastActiveOn]); 45 43 SET IDENTITY_INSERT [dbo].[Question] OFF 46 44 END -
src/FinkiChattery/FinkiChattery.Database/dbo/Tables/Question/Question.sql
r8b6791f r81c2e6f 10 10 [LastActiveOn] SMALLDATETIME NOT NULL, 11 11 [Search] AS ([Title] + ' ' + [Text]), 12 [AnswersCount] BIGINT NOT NULL DEFAULT 0,13 12 CONSTRAINT [PK_Question] PRIMARY KEY CLUSTERED ([Id] ASC), 14 13 CONSTRAINT [FK_Question_Student_StudentFk] FOREIGN KEY ([StudentFk]) REFERENCES [dbo].[Student] ([Id]), -
src/FinkiChattery/FinkiChattery.Persistence/Configurations/QuestionConfig.cs
r8b6791f r81c2e6f 25 25 builder.Property(x => x.LastActiveOn).HasColumnName(@"LastActiveOn").HasColumnType("smalldatetime").IsRequired(); 26 26 builder.Property(x => x.Search).HasColumnType(@"Search").HasColumnType("nvarchar").HasMaxLength(4000).IsRequired(); 27 builder.Property(x => x.AnswersCount).HasColumnType(@"AnswersCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0);28 27 29 28 builder.HasOne(x => x.Student).WithMany(x => x.Questions).HasForeignKey(x => x.StudentFk).OnDelete(DeleteBehavior.NoAction); -
src/FinkiChattery/FinkiChattery.Persistence/Models/Question.cs
r8b6791f r81c2e6f 34 34 public string Search { get; set; } 35 35 36 public long AnswersCount { get; set; }37 38 36 public virtual ICollection<Answer> Answers { get; set; } 39 37 -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/IQuestionRepo.cs
r8b6791f r81c2e6f 2 2 using FinkiChattery.Persistence.Repositories.Contracts; 3 3 using System; 4 using System.Collections.Generic;5 4 using System.Threading.Tasks; 6 5 … … 10 9 { 11 10 Task<QuestionStateDto> GetQuestionState(Guid questionUid); 12 13 Task<List<QuestionPreviewDto>> GetPreviewQuestionsLatest();14 15 Task<List<QuestionPreviewDto>> GetPreviewQuestionsPopular();16 11 } 17 12 } -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/QuestionRepo.cs
r8b6791f r81c2e6f 4 4 using Microsoft.EntityFrameworkCore; 5 5 using System; 6 using System.Collections.Generic;7 6 using System.Linq; 8 using System.Linq.Expressions;9 7 using System.Threading.Tasks; 10 8 … … 15 13 public QuestionRepo(ApplicationDbContext dbContext) : base(dbContext) 16 14 { 17 }18 19 public async Task<List<QuestionPreviewDto>> GetPreviewQuestionsLatest()20 {21 Expression<Func<Question, DateTime>> orderBy = x => x.CreatedOn;22 return await GetPreviewQuestions(orderBy);23 }24 25 public async Task<List<QuestionPreviewDto>> GetPreviewQuestionsPopular()26 {27 Expression<Func<Question, long>> orderBy = x => x.Views;28 return await GetPreviewQuestions(orderBy);29 }30 31 private async Task<List<QuestionPreviewDto>> GetPreviewQuestions<T>(Expression<Func<Question, T>> orderBy)32 {33 return await DbSet34 .AsNoTracking()35 .Include(x => x.QuestionCategories).ThenInclude(x => x.Category)36 .OrderByDescending(orderBy)37 .Select(x => new QuestionPreviewDto(x.Id,38 x.Uid,39 x.Title,40 x.Views,41 x.AnswersCount,42 x.CreatedOn,43 x.QuestionCategories.Select(y => new QuestionPreviewCategoryDto(y.Id, y.Uid, y.Category.Name))))44 .Skip(0).Take(30)45 .ToListAsync();46 15 } 47 16
Note:
See TracChangeset
for help on using the changeset viewer.