Changes in / [6b0fbbe:2025810]
- Location:
- src/Clients/Angular/finki-chattery/src
- Files:
-
- 8 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Clients/Angular/finki-chattery/src/app/core/services/auth.service.ts
r6b0fbbe r2025810 1 1 import { Injectable } from '@angular/core'; 2 import { User, UserManager , WebStorageStateStore} from 'oidc-client';2 import { User, UserManager } from 'oidc-client'; 3 3 import { Observable, of } from 'rxjs'; 4 4 … … 19 19 post_logout_redirect_uri: window.location.origin, 20 20 filterProtocolClaims: true, 21 loadUserInfo: true, 22 userStore: new WebStorageStateStore({ store: window.localStorage }) 21 loadUserInfo: true 23 22 }); 24 23 … … 55 54 56 55 public isStudent(): boolean { 57 return this.user ?.userType === ApplicationUserType.Student;56 return this.user !== null && this.user.userType === ApplicationUserType.Student; 58 57 } 59 58 -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.effects.ts
r6b0fbbe r2025810 39 39 switchMap((action) => { 40 40 return this.api.get<QuestionStateResponse>(`v1/questions/${action.questionUid}`).pipe( 41 switchMap((state) => [new GetQuestionStateSuccess(QuestionMapper.ToQuestionStateViewModel(state)), new EffectFinishedWorking()]), 41 switchMap((state) => [ 42 new GetQuestionStateSuccess(QuestionMapper.ToQuestionStateViewModel(state, this.translate)), 43 new EffectFinishedWorking() 44 ]), 42 45 catchError((err) => [new EffectFinishedWorkingError(err)]) 43 46 ); -
src/Clients/Angular/finki-chattery/src/app/core/state/question-state/question.mapper.ts
r6b0fbbe r2025810 13 13 } from 'src/app/shared-app/models'; 14 14 import { TranslateFromJsonService } from 'src/app/shared-app/services'; 15 import { PreviewQuestion CategoryResponse, PreviewQuestionResponse, QuestionStateResponse } from './question-state.models';15 import { PreviewQuestionResponse, QuestionStateResponse } from './question-state.models'; 16 16 17 17 export class QuestionMapper { 18 public static ToQuestionStateViewModel(questionStateResponse: QuestionStateResponse): QuestionStateViewModel { 18 public static ToQuestionStateViewModel( 19 questionStateResponse: QuestionStateResponse, 20 translate: TranslateFromJsonService 21 ): QuestionStateViewModel { 19 22 let answers: AnswerQuestionStateViewModel[] = []; 20 23 … … 58 61 59 62 if (questionStateResponse.categoriesResponse.length > 0) { 60 categories = questionStateResponse.categoriesResponse.map((x) => new QuestionCategoryQuestionStateViewModel(x.uid, x.name)); 63 categories = questionStateResponse.categoriesResponse.map( 64 (x) => new QuestionCategoryQuestionStateViewModel(x.uid, x.name, translate.instant(x.name)) 65 ); 61 66 } 62 67 -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/components.ts
r6b0fbbe r2025810 3 3 import { FormErrorComponent } from './generic/form-error/form-error.component'; 4 4 import { HeaderComponent } from './generic/header/header.component'; 5 import { TextEditorComponent } from './generic/text-editor/text-editor.component'; 5 6 import { VoteComponent } from './generic/vote/vote.component'; 6 7 import { AskQuestionSharedComponent } from './question/ask-question-shared/ask-question-shared.component'; 7 8 import { PreviewQuestionDisplayComponent } from './question/preview-question-display/preview-question-display.component'; 9 import { PreviewQuestionFullComponent } from './question/preview-question-full/preview-question-full.component'; 8 10 import { QuestionPreviewComponent } from './question/question-preview/question-preview.component'; 9 11 import { SearchQuestionComponent } from './question/search-question/search-question.component'; … … 20 22 SearchQuestionComponent, 21 23 PreviewQuestionDisplayComponent, 22 AskQuestionSharedComponent 24 AskQuestionSharedComponent, 25 PreviewQuestionFullComponent, 26 TextEditorComponent 23 27 ]; -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/ask-question-shared/ask-question-shared.component.html
r6b0fbbe r2025810 1 <form [formGroup]="questionFormGroup"> 2 <mat-form-field class="full-width margin-bottom-sm" appearance="fill" appHandleInputFormErrors> 3 <mat-label>{{ 'ask-question-question-title' | translate }}</mat-label> 4 <input matInput [formControl]="titleForm" /> 5 </mat-form-field> 1 <mat-horizontal-stepper linear #stepper> 2 <mat-step [stepControl]="questionFormGroup"> 3 <ng-template matStepLabel>{{ 'ask-question-stepper-ask' | translate }}</ng-template> 4 <form [formGroup]="questionFormGroup"> 5 <mat-form-field class="full-width margin-bottom-sm" appearance="fill" appHandleInputFormErrors> 6 <mat-label>{{ 'ask-question-question-title' | translate }}</mat-label> 7 <input matInput [formControl]="titleForm" /> 8 </mat-form-field> 6 9 7 <editor 8 matInput 9 class="margin-bottom-sm" 10 [formControl]="textForm" 11 [init]="{ 12 apiKey: 'fx28x0d64jeufa35u7mcd80fgveayg5c4ap9gnr6posehzny', 13 menubar: false, 14 plugins: [ 15 'advlist autolink lists link image charmap print preview anchor', 16 'searchreplace visualblocks code fullscreen', 17 'insertdatetime media table paste code help wordcount' 18 ], 19 toolbar: 20 'undo redo | formatselect | bold italic backcolor | code | \ 21 alignleft aligncenter alignright alignjustify | \ 22 bullist numlist outdent indent | removeformat | help' 23 }" 24 ></editor> 25 <mat-error *ngIf="textForm?.touched && textForm?.errors?.required">{{ 'not-found' | translate }}</mat-error> 26 <mat-error *ngIf="textForm?.touched && textForm?.errors?.maxlength">{{ 27 'error-message-max-length' | translate: { maxlength: textForm?.errors?.maxlength?.requiredLength } 28 }}</mat-error> 10 <app-text-editor [textForm]="textForm"></app-text-editor> 29 11 30 <mat-form-field class="full-width margin-bottom-sm" appearance="fill" appHandleInputFormErrors>31 <mat-label>{{ 'ask-question-categories' | translate }}</mat-label>32 <mat-select [formControl]="categoriesForm" multiple>33 <mat-option *ngFor="let category of categoriesList$ | async" [value]="category.uid">{{ category.translatedName }}</mat-option>34 </mat-select>35 </mat-form-field>12 <mat-form-field class="full-width margin-bottom-sm" appearance="fill" appHandleInputFormErrors> 13 <mat-label>{{ 'ask-question-categories' | translate }}</mat-label> 14 <mat-select [formControl]="categoriesForm" multiple> 15 <mat-option *ngFor="let category of categoriesList$ | async" [value]="category">{{ category.translatedName }}</mat-option> 16 </mat-select> 17 </mat-form-field> 36 18 37 <app-button [disabled]="questionFormGroup.invalid" [buttonType]="ButtonType.CallToAction" (action)="askQuestionEmit()"> 38 {{ 'ask-question-ask-button' | translate }} 39 </app-button> 40 </form> 19 <button mat-button [disabled]="questionFormGroup.invalid" matStepperNext> 20 {{ 'ask-question-ask-button-preview' | translate }} 21 </button> 22 </form> 23 </mat-step> 24 <mat-step> 25 <ng-template matStepLabel>{{ 'ask-question-stepper-preview' | translate }}</ng-template> 26 <app-preview-question-full [question]="previewQuestion"></app-preview-question-full> 27 <div> 28 <button class="margin-y-xs" mat-button [disabled]="questionFormGroup.invalid" matStepperPrevious> 29 {{ 'ask-question-ask-button-back' | translate }} 30 </button> 31 <app-button 32 class="margin-y-xs" 33 [disabled]="questionFormGroup.invalid" 34 [buttonType]="ButtonType.CallToAction" 35 (action)="askQuestionEmit()" 36 > 37 {{ 'ask-question-ask-button' | translate }} 38 </app-button> 39 </div> 40 </mat-step> 41 </mat-horizontal-stepper> -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/ask-question-shared/ask-question-shared.component.scss
r6b0fbbe r2025810 1 ::ng-deep .mat-horizontal-content-container { 2 padding: 0 !important; 3 } 4 5 ::ng-deep mat-card { 6 margin: 5px !important; 7 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/ask-question-shared/ask-question-shared.component.ts
r6b0fbbe r2025810 1 1 import { Component, EventEmitter, OnInit, Output } from '@angular/core'; 2 2 import { FormControl, FormGroup, Validators } from '@angular/forms'; 3 import * as moment from 'moment'; 3 4 4 5 import { CategoryFacadeService } from 'src/app/core/state/category-facade.service'; 5 6 import { ButtonType } from 'src/app/shared-app/components/generic/button/button.models'; 6 import { AskQuestionRequest } from 'src/app/shared-app/models'; 7 import { 8 AskQuestionRequest, 9 QuestionCategoryQuestionStateViewModel, 10 QuestionStateViewModel, 11 StudentQuestionStateViewModel 12 } from 'src/app/shared-app/models'; 7 13 8 14 @Component({ … … 13 19 export class AskQuestionSharedComponent implements OnInit { 14 20 @Output() askQuestion = new EventEmitter<AskQuestionRequest>(); 21 22 public previewQuestion?: QuestionStateViewModel; 15 23 16 24 public titleForm = new FormControl('', [Validators.required, Validators.maxLength(500)]); … … 29 37 } 30 38 31 ngOnInit(): void {} 39 ngOnInit(): void { 40 this.questionFormGroup.valueChanges.subscribe((x) => { 41 const student = new StudentQuestionStateViewModel('', '', '', 0); 42 const categories = this.categoriesForm.value.map( 43 (category: any) => new QuestionCategoryQuestionStateViewModel('', category.name, category.translatedName) 44 ); 45 46 this.previewQuestion = new QuestionStateViewModel( 47 '', 48 this.titleForm.value, 49 this.textForm.value, 50 moment(), 51 0, 52 moment(), 53 student, 54 [], 55 categories, 56 null 57 ); 58 }); 59 } 32 60 33 61 public askQuestionEmit(): void { 34 this.askQuestion.emit(new AskQuestionRequest(this.titleForm.value, this.textForm.value, this.categoriesForm.value)); 62 this.askQuestion.emit( 63 new AskQuestionRequest( 64 this.titleForm.value, 65 this.textForm.value, 66 this.categoriesForm.value.map((x: any) => x.uid) 67 ) 68 ); 35 69 } 36 70 } -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/question-preview/question-preview.component.html
r6b0fbbe r2025810 1 1 <div *ngIf="!working"> 2 <mat-card appHoverElevation class="margin-bottom-xl"> 3 <mat-card-title>{{ question.title }}</mat-card-title> 4 <mat-card-subtitle 5 [innerHTML]=" 6 'question-preview-subtitle' 7 | translate 8 : { 9 createdOn: question.createdOn | momentDate: 'LLLL', 10 lastActive: question.lastActiveOn | momentDate: 'LLLL', 11 views: question.views 12 } 13 " 14 ></mat-card-subtitle> 15 <mat-card-content> 16 <mat-chip-list> 17 <mat-chip *ngFor="let category of question.categories"> 18 {{ category.name }} 19 </mat-chip> 20 </mat-chip-list> 21 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> 33 <div class="align-right"> 34 <app-student-card 35 [indexNumber]="question.student.index" 36 [imageUrl]="question.student.imageUrl" 37 [uid]="question.student.uid" 38 [reputation]="question.student.reputation" 39 [subtitle]="'question-asked-by-subtitle' | translate: { date: question.createdOn | momentDate: 'LL' }" 40 ></app-student-card> 41 </div> 42 </mat-card-content> 43 <mat-card-actions> 44 <app-button appShareLink [buttonType]="ButtonType.Basic">{{ 'share-link' | translate }}</app-button> 45 </mat-card-actions> 46 </mat-card> 2 <div class="margin-bottom-xl"> 3 <app-preview-question-full [question]="question"></app-preview-question-full> 4 </div> 47 5 48 6 <h1 class="mat-headline">{{ 'question-answers' | translate: { answerCount: question.answers.length } }}</h1> … … 58 16 <app-vote [voteCount]="answer.upvotesCount" [correct]="answer.correctAnswer" fxFlex="6%"></app-vote> 59 17 <div fxFlex="92%"> 60 <editor 61 class="margin-x-sm" 62 [init]="{ 63 apiKey: 'fx28x0d64jeufa35u7mcd80fgveayg5c4ap9gnr6posehzny', 18 <app-text-editor 19 [text]="answer.text" 20 [configuration]="{ 64 21 menubar: false, 65 22 plugins: ['autoresize'], 66 23 toolbar: '' 67 24 }" 68 [disabled]="true" 69 [initialValue]="answer.text" 70 ></editor> 25 [readonly]="true" 26 ></app-text-editor> 71 27 <div class="align-right"> 72 28 <app-student-card -
src/Clients/Angular/finki-chattery/src/app/shared-app/components/question/student-card/student-card.component.ts
r6b0fbbe r2025810 9 9 @Input() imageUrl: string | undefined; 10 10 @Input() indexNumber: string | undefined; 11 @Input() uid !: string;11 @Input() uid?: string; 12 12 @Input() reputation: number | undefined; 13 13 @Input() subtitle: string | undefined; -
src/Clients/Angular/finki-chattery/src/app/shared-app/models/question-state-view-models.models.ts
r6b0fbbe r2025810 23 23 24 24 export class QuestionCategoryQuestionStateViewModel { 25 constructor(public uid: string, public name: string ) {}25 constructor(public uid: string, public name: string, public translatedName: string) {} 26 26 } 27 27 -
src/Clients/Angular/finki-chattery/src/app/shared-material/shared-material.module.ts
r6b0fbbe r2025810 24 24 import { MatButtonToggleModule } from '@angular/material/button-toggle'; 25 25 import { MatBadgeModule } from '@angular/material/badge'; 26 import { MatStepperModule } from '@angular/material/stepper'; 26 27 27 28 @NgModule({ … … 49 50 MatTooltipModule, 50 51 MatButtonToggleModule, 51 MatBadgeModule 52 MatBadgeModule, 53 MatStepperModule 52 54 ], 53 55 exports: [ … … 73 75 MatTooltipModule, 74 76 MatButtonToggleModule, 75 MatBadgeModule 77 MatBadgeModule, 78 MatStepperModule 76 79 ] 77 80 }) -
src/Clients/Angular/finki-chattery/src/assets/translations/en.json
r6b0fbbe r2025810 47 47 "ask-question-question-title": "Question title", 48 48 "ask-question-categories": "Add categories to question", 49 "ask-question-ask-button ": "Askquestion",49 "ask-question-ask-button-preview": "Preview question", 50 50 "header-logout": "Logout", 51 "header-ask-question": "Ask question" 51 "header-ask-question": "Ask question", 52 "ask-question-stepper-preview": "Preview question", 53 "ask-question-stepper-ask": "Ask question", 54 "ask-question-ask-button-back": "Edit question", 55 "ask-question-ask-button": "Ask question" 52 56 }
Note:
See TracChangeset
for help on using the changeset viewer.