Changes in / [7899209:6b0fbbe]
- Location:
- src
- Files:
-
- 11 added
- 2 deleted
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/package-lock.json
r7899209 r6b0fbbe 1746 1746 } 1747 1747 }, 1748 "@tinymce/tinymce-angular": { 1749 "version": "4.0.0", 1750 "resolved": "https://registry.npmjs.org/@tinymce/tinymce-angular/-/tinymce-angular-4.0.0.tgz", 1751 "integrity": "sha512-CmsKournkWWK5O7d8qgZQPvRC76z36GjeD3ZAHZEY/kUXKWAIXfbrHxxgQq9m7+wlfZq9QNgRx5ufN9y9N46DQ==", 1752 "requires": { 1753 "tslib": "^1.10.0" 1754 }, 1755 "dependencies": { 1756 "tslib": { 1757 "version": "1.14.1", 1758 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", 1759 "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" 1760 } 1761 } 1762 }, 1748 1763 "@types/glob": { 1749 1764 "version": "7.1.3", -
src/Clients/Angular/finki-chattery/package.json
r7899209 r6b0fbbe 29 29 "@ngrx/store-devtools": "^11.0.1", 30 30 "@ngx-translate/core": "^13.0.0", 31 "@tinymce/tinymce-angular": "^4.0.0", 31 32 "moment": "^2.29.1", 32 33 "ng2-file-upload": "^1.4.0", -
src/Clients/Angular/finki-chattery/src/app/app-routing.module.ts
r7899209 r6b0fbbe 6 6 const routes: Routes = [ 7 7 { 8 path: 'questioning', 9 canActivate: [AuthorizedGuard], 10 loadChildren: () => import('./modules/questioning/questioning.module').then((x) => x.QuestioningModule) 11 }, 12 { 8 13 path: 'auth-callback', 14 pathMatch: 'full', 9 15 component: AuthCallbackComponent 10 16 }, 11 17 { 12 path: ' questioning',13 canActivate: [AuthorizedGuard],14 loadChildren: () => import('./modules/questioning/questioning.module').then((x) => x.QuestioningModule)18 path: '', 19 pathMatch: 'full', 20 redirectTo: 'questioning/preview' 15 21 }, 16 22 { -
src/Clients/Angular/finki-chattery/src/app/core/core.module.ts
r7899209 r6b0fbbe 9 9 import { SharedMaterialModule } from '../shared-material/shared-material.module'; 10 10 import { COMPONENTS } from './components/components'; 11 import { GUARDS } from './guards/guards';12 11 import { LoaderInterceptor } from './interceptors/loader.interceptor'; 13 12 import { reducers } from './state'; … … 20 19 declarations: [COMPONENTS], 21 20 providers: [ 22 GUARDS,23 21 { provide: HTTP_INTERCEPTORS, useClass: LoaderInterceptor, multi: true }, 24 22 { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true } -
src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts
r7899209 r6b0fbbe 1 1 import { Injectable } from '@angular/core'; 2 import { User, UserManager } from 'oidc-client';2 import { User, UserManager, WebStorageStateStore } from 'oidc-client'; 3 3 import { Observable, of } from 'rxjs'; 4 4 5 5 import { environment } from '@env/environment'; 6 import { ApplicationUser, SelfUserResponse } from 'src/app/shared-app/models';6 import { ApplicationUser, ApplicationUserType, SelfUserResponse } from 'src/app/shared-app/models'; 7 7 import { BaseApiService } from 'src/app/shared-app/services/base-api.service'; 8 8 … … 17 17 response_type: 'id_token token', 18 18 scope: 'openid app.api.finki-chattery profile', 19 post_logout_redirect_uri: window.location.origin 19 post_logout_redirect_uri: window.location.origin, 20 filterProtocolClaims: true, 21 loadUserInfo: true, 22 userStore: new WebStorageStateStore({ store: window.localStorage }) 20 23 }); 21 24 … … 23 26 public oidcUser: User | null = null; 24 27 25 constructor(private baseApi: BaseApiService) {} 28 constructor(private baseApi: BaseApiService) { 29 this.userManager.getUser().then((user) => { 30 this.oidcUser = user; 31 this.user = new ApplicationUser( 32 user?.profile.id, 33 user?.profile.userType, 34 user?.profile.emailAddress, 35 user?.profile.username, 36 user?.profile.isVerified 37 ); 38 }); 39 } 26 40 27 41 public login(): void { … … 38 52 } 39 53 return false; 54 } 55 56 public isStudent(): boolean { 57 return this.user?.userType === ApplicationUserType.Student; 40 58 } 41 59 -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questioning-components.ts
r7899209 r6b0fbbe 3 3 import { QuestionsPreviewGeneralComponent } from './questions-preview-general/questions-preview-general.component'; 4 4 import { QuestionsSearchComponent } from './questions-search/questions-search.component'; 5 import { AskQuestionComponent } from './ask-question/ask-question.component'; 5 6 6 7 export const QUESTIONING_COMPONENTS: any[] = [ … … 8 9 QuestionsPreviewGeneralComponent, 9 10 QuestioningGeneralComponent, 10 QuestionsSearchComponent 11 QuestionsSearchComponent, 12 AskQuestionComponent 11 13 ]; -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questioning-general/questioning-general.component.ts
r7899209 r6b0fbbe 1 1 import { Component, OnInit } from '@angular/core'; 2 import { CategoryFacadeService } from 'src/app/core/state/category-facade.service'; 2 3 3 4 @Component({ … … 7 8 }) 8 9 export class QuestioningGeneralComponent implements OnInit { 9 constructor( ) {}10 constructor(private categoriesFacade: CategoryFacadeService) {} 10 11 11 ngOnInit(): void {} 12 ngOnInit(): void { 13 this.categoriesFacade.fetchCategories(); 14 } 12 15 } -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/components/questions-preview-general/questions-preview-general.component.ts
r7899209 r6b0fbbe 17 17 questionsSortByForm = new FormControl(PreviewQuestionsOrderEnum.Latest); 18 18 19 constructor(private categoriesFacade: CategoryFacadeService, privatequestionFacade: QuestionFacadeService, private router: Router) {}19 constructor(private questionFacade: QuestionFacadeService, private router: Router) {} 20 20 21 21 ngOnInit(): void { 22 this.categoriesFacade.fetchCategories();23 22 this.questionFacade.fetchPreviewQuestions(PreviewQuestionsOrderEnum.Latest); 24 23 this.questionsSortByForm.valueChanges.subscribe((value: PreviewQuestionsOrderEnum) => { -
src/Clients/Angular/finki-chattery/src/app/modules/questioning/questioning.routes.ts
r7899209 r6b0fbbe 5 5 import { QuestionsPreviewGeneralComponent } from './components/questions-preview-general/questions-preview-general.component'; 6 6 import { QuestionsSearchComponent } from './components/questions-search/questions-search.component'; 7 import { AuthorizedStudentGuard } from 'src/app/core/guards/authorized-student.guard'; 8 import { AskQuestionComponent } from './components/ask-question/ask-question.component'; 7 9 8 10 const routes: Routes = [ … … 22 24 }, 23 25 { 26 path: 'ask', 27 pathMatch: 'full', 28 component: AskQuestionComponent, 29 canActivate: [AuthorizedStudentGuard] 30 }, 31 { 24 32 path: ':questionUid', 25 33 component: QuestionPreviewGeneralComponent -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts
r7899209 r6b0fbbe 4 4 import { HeaderComponent } from './generic/header/header.component'; 5 5 import { VoteComponent } from './generic/vote/vote.component'; 6 import { AskQuestionSharedComponent } from './question/ask-question-shared/ask-question-shared.component'; 6 7 import { PreviewQuestionDisplayComponent } from './question/preview-question-display/preview-question-display.component'; 7 8 import { QuestionPreviewComponent } from './question/question-preview/question-preview.component'; … … 18 19 HeaderComponent, 19 20 SearchQuestionComponent, 20 PreviewQuestionDisplayComponent 21 PreviewQuestionDisplayComponent, 22 AskQuestionSharedComponent 21 23 ]; -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/header/header.component.html
r7899209 r6b0fbbe 2 2 <span>FinkiChattery</span> 3 3 <span class="right"></span> 4 <app-button *ngIf="auth.isLoggedIn()" (action)="logout()" [buttonType]="ButtonType.CallToAction">Logout</app-button> 4 <app-button class="margin-y-xs" *ngIf="auth.isStudent()" (action)="askQuestion()" [buttonType]="ButtonType.CallToAction">{{ 5 'header-ask-question' | translate 6 }}</app-button> 7 <app-button class="margin-y-xs" *ngIf="auth.isLoggedIn()" (action)="logout()" [buttonType]="ButtonType.Basic">{{ 8 'header-logout' | translate 9 }}</app-button> 5 10 </mat-toolbar> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/generic/header/header.component.ts
r7899209 r6b0fbbe 1 1 import { Component, OnInit } from '@angular/core'; 2 import { Router } from '@angular/router'; 2 3 import { AuthService } from 'src/app/core/services'; 3 4 import { ButtonType } from '../button/button.models'; … … 11 12 ButtonType = ButtonType; 12 13 13 constructor(public auth: AuthService ) {}14 constructor(public auth: AuthService, private router: Router) {} 14 15 15 16 ngOnInit(): void {} … … 18 19 this.auth.logout(); 19 20 } 21 22 askQuestion(): void { 23 this.router.navigateByUrl('questioning/ask'); 24 } 20 25 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
r7899209 r6b0fbbe 20 20 </mat-chip-list> 21 21 22 <div class="margin-top-lg" [innerHTML]="question.text"></div> 22 <editor 23 class="margin-x-sm" 24 [init]="{ 25 apiKey: 'fx28x0d64jeufa35u7mcd80fgveayg5c4ap9gnr6posehzny', 26 menubar: false, 27 plugins: ['autoresize'], 28 toolbar: '' 29 }" 30 [disabled]="true" 31 [initialValue]="question.text" 32 ></editor> 23 33 <div class="align-right"> 24 34 <app-student-card … … 48 58 <app-vote [voteCount]="answer.upvotesCount" [correct]="answer.correctAnswer" fxFlex="6%"></app-vote> 49 59 <div fxFlex="92%"> 50 <div [innerHTML]="answer.text"></div> 60 <editor 61 class="margin-x-sm" 62 [init]="{ 63 apiKey: 'fx28x0d64jeufa35u7mcd80fgveayg5c4ap9gnr6posehzny', 64 menubar: false, 65 plugins: ['autoresize'], 66 toolbar: '' 67 }" 68 [disabled]="true" 69 [initialValue]="answer.text" 70 ></editor> 51 71 <div class="align-right"> 52 72 <app-student-card -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/index.ts
r7899209 r6b0fbbe 4 4 export * from './category-state-view-models.models'; 5 5 export * from './question-state-enums.models'; 6 export * from './questioning-request.models'; -
src/Clients/Angular/finki-chattery/src/app/shared-app/shared-app.module.ts
r7899209 r6b0fbbe 7 7 import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker'; 8 8 import { FileUploadModule } from 'ng2-file-upload'; 9 import { EditorModule } from '@tinymce/tinymce-angular'; 9 10 10 11 import { COMPONENTS } from './components/components'; … … 25 26 FlexLayoutModule, 26 27 FileUploadModule, 27 NgxMaterialTimepickerModule 28 NgxMaterialTimepickerModule, 29 EditorModule 28 30 ], 29 31 exports: [ … … 38 40 DIRECTIVES, 39 41 PIPES, 40 SharedMaterialModule 42 SharedMaterialModule, 43 EditorModule 41 44 ] 42 45 }) -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r7899209 r6b0fbbe 44 44 "questions-preview-question-answers": "Answers", 45 45 "questions-preview-question-views": "Views", 46 "questions-search-title": "Search results for: {{searchQuery}}" 46 "questions-search-title": "Search results for: {{searchQuery}}", 47 "ask-question-question-title": "Question title", 48 "ask-question-categories": "Add categories to question", 49 "ask-question-ask-button": "Ask question", 50 "header-logout": "Logout", 51 "header-ask-question": "Ask question" 47 52 } -
src/FinkiChattery/FinkiChattery.Api/Controllers/v1/QuestionsController.cs
r7899209 r6b0fbbe 29 29 public async Task<IActionResult> AskQuestion([FromBody] AskQuestionRequest request) 30 30 { 31 await MediatorService.SendAsync(new AskQuestionCommand(request.Title, request.Text, request.Categories));32 return Ok( );31 var questionUid = await MediatorService.SendAsync(new AskQuestionCommand(request.Title, request.Text, request.Categories)); 32 return Ok(questionUid); 33 33 } 34 34 -
src/FinkiChattery/FinkiChattery.Persistence/Configurations/QuestionConfig.cs
r7899209 r6b0fbbe 24 24 builder.Property(x => x.Views).HasColumnName(@"Views").HasColumnType("bigint").IsRequired().HasDefaultValue(0); 25 25 builder.Property(x => x.LastActiveOn).HasColumnName(@"LastActiveOn").HasColumnType("smalldatetime").IsRequired(); 26 builder.Property(x => x.Search).HasCo lumnType(@"Search").HasColumnType("nvarchar").HasMaxLength(4000).IsRequired();26 builder.Property(x => x.Search).HasComputedColumnSql(@"Search").HasColumnType("nvarchar").ValueGeneratedOnAddOrUpdate().HasMaxLength(4000).IsRequired(); 27 27 builder.Property(x => x.AnswersCount).HasColumnType(@"AnswersCount").HasColumnType("bigint").IsRequired().HasDefaultValue(0); 28 28 -
src/FinkiChattery/FinkiChattery.Persistence/Models/Question.cs
r7899209 r6b0fbbe 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.ComponentModel.DataAnnotations.Schema; 3 4 4 5 namespace FinkiChattery.Persistence.Models … … 32 33 public DateTime LastActiveOn { get; set; } 33 34 35 [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 34 36 public string Search { get; set; } 35 37
Note:
See TracChangeset
for help on using the changeset viewer.