Changeset f3c4950
- Timestamp:
- 01/19/22 16:59:58 (3 years ago)
- Branches:
- dev
- Children:
- 6738cc0
- Parents:
- fcc3080
- Location:
- src
- Files:
-
- 22 added
- 20 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/app-routing.module.ts
rfcc3080 rf3c4950 2 2 import { Routes, RouterModule } from '@angular/router'; 3 3 import { AuthCallbackComponent } from './auth-callback/auth-callback.component'; 4 import { AuthorizedModeratorGuard } from './core/guards/authorized-moderator.guard'; 4 5 import { AuthorizedGuard } from './core/guards/authorized.guard'; 5 6 … … 9 10 canActivate: [AuthorizedGuard], 10 11 loadChildren: () => import('./modules/questioning/questioning.module').then((x) => x.QuestioningModule) 12 }, 13 { 14 path: 'moderating', 15 canActivate: [AuthorizedGuard, AuthorizedModeratorGuard], 16 loadChildren: () => import('./modules/moderating/moderating.module').then((x) => x.ModeratingModule) 11 17 }, 12 18 { -
src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts
rfcc3080 rf3c4950 64 64 } 65 65 66 public isModerator(): boolean { 67 return this.user !== null && this.user.userType === ApplicationUserType.Moderator; 68 } 69 66 70 public currentUser(): ApplicationUser | null { 67 71 return this.user; -
src/Clients/Angular/finki-chattery/src/app/core/services/redirect.service.ts
rfcc3080 rf3c4950 21 21 case ApplicationUserType.Teacher: 22 22 break; 23 case ApplicationUserType.Moderator: 24 this.router.navigateByUrl(`moderating/categories`); 25 break; 23 26 } 24 27 } -
src/Clients/Angular/finki-chattery/src/app/core/state/category-facade.service.ts
rfcc3080 rf3c4950 6 6 7 7 import { CategoryStateViewModel } from 'src/app/shared-app/models'; 8 import { EffectStartedWorking, GetCategoriesState } from './category-state/category.actions';8 import { AddCategory, EffectStartedWorking, GetCategoriesState } from './category-state/category.actions'; 9 9 import { categoriesStateQuery } from './category-state/category.selectors'; 10 10 import { CategoryState } from './category-state/category.state'; … … 17 17 18 18 constructor(private store: Store<CategoryState>) { 19 this.effectWorking$ = this.store.select(categoriesStateQuery.effectWorking).pipe( 20 filter((effect) => effect !== null), 21 map((effect) => { 22 if (effect instanceof HttpErrorResponse) { 23 throw effect; 24 } else { 25 return effect; 26 } 27 }), 28 catchError((err) => { 29 return throwError(err); 30 }) 31 ); 19 this.effectWorking$ = this.store.select(categoriesStateQuery.effectWorking).pipe(filter((effect) => effect !== null)); 32 20 } 33 21 … … 38 26 public fetchCategories(): void { 39 27 this.dispatchEffect(new GetCategoriesState()); 28 } 29 30 public addNewCategory(name: string): void { 31 this.dispatchEffect(new AddCategory(name)); 40 32 } 41 33 -
src/Clients/Angular/finki-chattery/src/app/core/state/category-state/category.actions.ts
rfcc3080 rf3c4950 2 2 import { Action } from '@ngrx/store'; 3 3 import { CategoryStateViewModel } from 'src/app/shared-app/models'; 4 import { CategoryStateResponse } from './category-state.models';5 4 6 5 export enum CategoryActionTypes { 7 6 GetCategoriesState = '[Category] Get state', 8 7 GetCategoriesStateSuccess = '[Category] Get state success', 8 AddCategory = '[Category] AddCategory', 9 AddCategorySuccess = '[Category] AddCategorySuccess success', 9 10 EffectStartedWorking = '[Category] Effect Started Working', 10 11 EffectFinishedWorking = '[Category] Effect Finished Working', … … 22 23 23 24 constructor(public payload: CategoryStateViewModel[]) {} 25 } 26 27 export class AddCategory implements Action { 28 readonly type = CategoryActionTypes.AddCategory; 29 30 constructor(public name: string) {} 31 } 32 33 export class AddCategorySuccess implements Action { 34 readonly type = CategoryActionTypes.AddCategorySuccess; 35 36 constructor(public payload: CategoryStateViewModel) {} 24 37 } 25 38 … … 42 55 } 43 56 44 export type CategoryAction = GetCategoriesStateSuccess | EffectStartedWorking | EffectFinishedWorking | EffectFinishedWorkingError; 57 export type CategoryAction = 58 | GetCategoriesStateSuccess 59 | AddCategorySuccess 60 | EffectStartedWorking 61 | EffectFinishedWorking 62 | EffectFinishedWorkingError; -
src/Clients/Angular/finki-chattery/src/app/core/state/category-state/category.effects.ts
rfcc3080 rf3c4950 1 1 import { Injectable } from '@angular/core'; 2 2 import { Actions, createEffect, ofType } from '@ngrx/effects'; 3 import { catchError, switchMap } from 'rxjs/operators';3 import { catchError, mergeMap, switchMap } from 'rxjs/operators'; 4 4 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 5 5 6 6 import { BaseApiService } from 'src/app/shared-app/services/base-api.service'; 7 import { CreateCategoryRequest } from './category-state-request.models'; 7 8 import { CategoryStateResponse } from './category-state.models'; 8 9 import { 10 AddCategory, 11 AddCategorySuccess, 9 12 CategoryActionTypes, 10 13 EffectFinishedWorking, … … 35 38 ); 36 39 }); 40 41 addCategory$ = createEffect(() => { 42 return this.actions$.pipe( 43 ofType<AddCategory>(CategoryActionTypes.AddCategory), 44 mergeMap((action) => { 45 return this.api.post<string>(`v1/categories`, new CreateCategoryRequest(action.name)).pipe( 46 switchMap((state) => [ 47 new AddCategorySuccess(CategoriesMapper.ToCategoryStateViewModel(state, action.name, this.translate)), 48 new EffectFinishedWorking() 49 ]), 50 catchError((err) => [new EffectFinishedWorkingError(err)]) 51 ); 52 }) 53 ); 54 }); 37 55 } -
src/Clients/Angular/finki-chattery/src/app/core/state/category-state/category.mapper.ts
rfcc3080 rf3c4950 10 10 return categoriesResponse.map((x) => new CategoryStateViewModel(x.uid, x.name, translate.instant(x.name))); 11 11 } 12 13 public static ToCategoryStateViewModel(uid: string, name: string, translate: TranslateFromJsonService): CategoryStateViewModel { 14 return new CategoryStateViewModel(uid, name, translate.instant(name)); 15 } 12 16 } -
src/Clients/Angular/finki-chattery/src/app/core/state/category-state/category.reducers.ts
rfcc3080 rf3c4950 9 9 categories: action.payload 10 10 }; 11 case CategoryActionTypes.AddCategorySuccess: { 12 return { 13 ...state, 14 categories: [action.payload, ...state.categories] 15 }; 16 } 11 17 case CategoryActionTypes.EffectStartedWorking: { 12 18 return { -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/header/header.component.html
rfcc3080 rf3c4950 16 16 'header-ask-question' | translate 17 17 }}</app-button> 18 <app-button [matMenuTriggerFor]="menu" class="margin-y-xs" *ngIf="auth.is LoggedIn()" [buttonType]="ButtonType.Basic">{{18 <app-button [matMenuTriggerFor]="menu" class="margin-y-xs" *ngIf="auth.isStudent()" [buttonType]="ButtonType.Basic">{{ 19 19 'header-student-questions' | translate 20 20 }}</app-button> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/header/header.component.ts
rfcc3080 rf3c4950 28 28 this.router.navigateByUrl('questioning/preview'); 29 29 } 30 if (this.auth.isModerator()) { 31 this.router.navigateByUrl('moderating/categories'); 32 } 30 33 } 31 34 -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
rfcc3080 rf3c4950 81 81 "AnswerAlreadyUpvoted": "You have already upvoted this answer", 82 82 "AnswerAlreadyDownvoted": "You have already downvoted this answer", 83 "StudentHasBadReputation": "You have bad reputation and can not vote" 83 "StudentHasBadReputation": "You have bad reputation and can not vote", 84 "CategoryNameAlreadyExists": "Category with that name already exists", 85 "category-title": "Category title", 86 "create-new-category": "Create new category" 84 87 } -
src/FinkiChattery/FinkiChattery.Api/ApplicationServices/Authentication/AuthenticationPolicy.cs
rfcc3080 rf3c4950 4 4 { 5 5 public const string Student = "Student"; 6 public const string Moderator = "Moderator"; 6 7 } 7 8 } -
src/FinkiChattery/FinkiChattery.Api/Controllers/v1/CategoriesController.cs
rfcc3080 rf3c4950 1 using FinkiChattery.Api.ApplicationServices.Questioning; 1 using FinkiChattery.Api.ApplicationServices.Authentication; 2 using FinkiChattery.Api.ApplicationServices.Questioning; 3 using FinkiChattery.Commands.Moderating; 2 4 using FinkiChattery.Common.Mediator.Interfaces; 5 using FinkiChattery.Contracts.Moderating; 3 6 using FinkiChattery.Queries.Questioning; 7 using IdentityServer4.AccessTokenValidation; 4 8 using Microsoft.AspNetCore.Authorization; 5 9 using Microsoft.AspNetCore.Mvc; … … 27 31 return Ok(categoriesList.ToCategoryDtos()); 28 32 } 33 34 [HttpPost] 35 [Authorize(AuthenticationSchemes = IdentityServerAuthenticationDefaults.AuthenticationScheme, Policy = AuthenticationPolicy.Moderator)] 36 public async Task<IActionResult> CreateNewCategory([FromBody] CreateCategoryRequest request) 37 { 38 var categoryUid = await MediatorService.SendAsync(new CreateCategoryCommand(request.Name)); 39 return Ok(categoryUid); 40 } 29 41 } 30 42 } -
src/FinkiChattery/FinkiChattery.Api/Services/RegisterServices.cs
rfcc3080 rf3c4950 94 94 { 95 95 options.AddPolicy(AuthenticationPolicy.Student, policy => policy.Requirements.Add(new StudentRequirement())); 96 options.AddPolicy(AuthenticationPolicy.Moderator, policy => policy.Requirements.Add(new ModeratorRequirement())); 96 97 97 98 }); -
src/FinkiChattery/FinkiChattery.Database/FinkiChattery.Database.sqlproj
rfcc3080 rf3c4950 76 76 <Folder Include="Snapshots" /> 77 77 <Folder Include="dbo\Tables\Vote" /> 78 <Folder Include="dbo\Tables\Moderator" /> 78 79 </ItemGroup> 79 80 <ItemGroup> 80 <Build Include="dbo\Tables\Moderator.sql" />81 81 <Build Include="dbo\Tables\Teacher.sql" /> 82 82 <Build Include="dbo\Tables\StudentTeam.sql" /> … … 101 101 <None Include="dbo\Tables\QuestionCategory\QuestionCategory.Debug.Seed.sql" /> 102 102 <Build Include="dbo\Tables\Vote\Vote.sql" /> 103 <Build Include="dbo\Tables\Moderator\Moderator.sql" /> 104 <None Include="dbo\Tables\Moderator\Moderator.Debug.Seed.sql" /> 103 105 </ItemGroup> 104 106 <ItemGroup> -
src/FinkiChattery/FinkiChattery.Database/dbo/Scripts/PostDeploymentScripts/Debug.PostDeployment.sql
rfcc3080 rf3c4950 6 6 :r ./../../Tables/AnswerResponse/AnswerResponse.Debug.Seed.sql 7 7 :r ./../../Tables/QuestionCategory/QuestionCategory.Debug.Seed.sql 8 :r ./../../Tables/Moderator/Moderator.Debug.Seed.sql -
src/FinkiChattery/FinkiChattery.Database/dbo/Tables/User/Seed/Users.Debug.Seed.sql
rfcc3080 rf3c4950 7 7 FROM ( 8 8 VALUES 9 (1, N'stojkovmarko1@gmail.com', N'STOJKOVMARKO1@GMAIL.COM', 'stojkovmarko1@gmail.com', N'STOJKOVMARKO1@GMAIL.COM', 1, N'AQAAAAEAACcQAAAAELBRjOGmA/Dh8BPvcPMA1vmk1jjvyDd/9/lO/3shoBt7z9NfiKJR+Ckp/2+6BVpyLw==', N'MMDEZ3RWADCRM4PTTKSEZNQYNH5V7UVA', N'08309369-24a1-470c-9ab1-65a250cafd4e', null, 0, 0, null, 1, 0, 0) 9 (1, N'stojkovmarko1@gmail.com', N'STOJKOVMARKO1@GMAIL.COM', 'stojkovmarko1@gmail.com', N'STOJKOVMARKO1@GMAIL.COM', 1, N'AQAAAAEAACcQAAAAELBRjOGmA/Dh8BPvcPMA1vmk1jjvyDd/9/lO/3shoBt7z9NfiKJR+Ckp/2+6BVpyLw==', N'MMDEZ3RWADCRM4PTTKSEZNQYNH5V7UVA', N'08309369-24a1-470c-9ab1-65a250cafd4e', null, 0, 0, null, 1, 0, 0), 10 (2, N'stojkovmarko1234@gmail.com', N'STOJKOVMARKO1234@GMAIL.COM', 'stojkovmarko1234@gmail.com', N'STOJKOVMARKO1234@GMAIL.COM', 1, N'AQAAAAEAACcQAAAAELBRjOGmA/Dh8BPvcPMA1vmk1jjvyDd/9/lO/3shoBt7z9NfiKJR+Ckp/2+6BVpyLw==', N'MMDEZ3RWADCRM4PTTKSEZNQYNH5V7UVA', N'08309369-24a1-470c-9ab1-65a250cafd4e', null, 0, 0, null, 1, 0, 2) 10 11 ) 11 12 AS temp ([ID], [UserName], [NormalizedUserName], [Email], [NormalizedEmail], [EmailConfirmed], [PasswordHash], [SecurityStamp], [ConcurrencyStamp], [PhoneNumber], [PhoneNumberConfirmed], [TwoFactorEnabled], [LockoutEnd], [LockoutEnabled], [AccessFailedCount], [Role]) -
src/FinkiChattery/FinkiChattery.Persistence/Models/Category.cs
rfcc3080 rf3c4950 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace FinkiChattery.Persistence.Models 1 namespace FinkiChattery.Persistence.Models 8 2 { 9 3 public class Category : BaseEntity 10 4 { 5 public Category() : base() 6 { 7 } 8 11 9 public string Name { get; set; } 12 10 } -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Contracts/ICategoriesRepo.cs
rfcc3080 rf3c4950 12 12 public Task<bool> CategoriesExist(IEnumerable<Guid> categoriesUids); 13 13 14 public Task<bool> CategoryWithNameIsUnique(string name); 15 14 16 public Task<IEnumerable<Category>> GetCategories(IEnumerable<Guid> categoriesUids); 15 17 } -
src/FinkiChattery/FinkiChattery.Persistence/Repositories/Implementations/CategoriesRepo.cs
rfcc3080 rf3c4950 20 20 } 21 21 22 public async Task<bool> CategoryWithNameIsUnique(string name) 23 { 24 return !(await DbSet.AnyAsync(x => x.Name == name)); 25 } 26 22 27 public async Task<IEnumerable<Category>> GetCategories(IEnumerable<Guid> categoriesUids) 23 28 {
Note:
See TracChangeset
for help on using the changeset viewer.