File
Implements
Metadata
selector |
app-interview |
styleUrls |
./interview.component.scss |
templateUrl |
./interview.component.html |
Methods
getFacCritPosition
|
getFacCritPosition(id: number)
|
|
Parameters :
Name |
Type |
Optional |
id |
number
|
No
|
|
onFinishClick
|
onFinishClick()
|
|
|
onGoalInput
|
onGoalInput(value: string)
|
|
Parameters :
Name |
Type |
Optional |
value |
string
|
No
|
|
onNaviagteBack
|
onNaviagteBack(facCritId: number)
|
|
Parameters :
Name |
Type |
Optional |
facCritId |
number
|
No
|
|
onNavigateForward
|
onNavigateForward(facCritId: number)
|
|
Parameters :
Name |
Type |
Optional |
facCritId |
number
|
No
|
|
facCritId$
|
Type : Observable<number>
|
Decorators :
@Select(AppRouterState.facCritId)
|
|
facCritIds
|
Type : number[]
|
|
goal$
|
Default value : new Subject<string>()
|
|
interviewId$
|
Type : Observable<number>
|
Decorators :
@Select(AppRouterState.interviewId)
|
|
import { Component, OnInit } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { AppRouterState } from 'src/app/core/ngxs/app-router.state';
import { Observable, Subject, combineLatest } from 'rxjs';
import { InterviewState } from 'src/app/core/ngxs/interview.state';
import { Answer } from 'src/app/core/data/models/answer.model';
import { FacCrit } from 'src/app/core/data/models/faccrit.model';
import { Interview, InterviewStatus } from 'src/app/core/data/models/interview.model';
import { ActivatedRoute, Router } from '@angular/router';
import { FacCritService } from 'src/app/core/http/facCrit.service';
import { filter, debounceTime } from 'rxjs/operators';
import { AuditState } from 'src/app/core/ngxs/audit.state';
import { UpdateInterview } from 'src/app/core/ngxs/actions/inteview.actions';
@Component({
selector: 'app-interview',
templateUrl: './interview.component.html',
styleUrls: ['./interview.component.scss'],
})
export class InterviewComponent implements OnInit {
@Select(AppRouterState.interviewId) interviewId$: Observable<number>;
@Select(AppRouterState.facCritId) facCritId$: Observable<number>;
@Select(InterviewState.answers) answers$: Observable<Answer[]>;
facCrit$: Observable<FacCrit>;
interview$: Observable<Interview>;
goal$ = new Subject<string>();
facCritId: number;
interviewId: number;
facCritIds: number[];
constructor(
private store: Store,
private activatedRoute: ActivatedRoute,
private facCritService: FacCritService,
private router: Router,
) {}
ngOnInit() {
combineLatest(this.interviewId$, this.facCritId$)
.pipe(filter(ids => ids[0] != null && ids[1] != null))
.subscribe(ids => {
this.interviewId = ids[0];
this.facCritId = ids[1];
this.interview$ = this.store.select(InterviewState.interview(ids[0]));
this.facCrit$ = this.store.select(AuditState.facCrit(ids[1]));
this.facCritService.getFacCritsByInterviewId(ids[0]).subscribe((facCrits: FacCrit[]) => {
this.facCritIds = this.facCritIds = facCrits.map(f => f.id);
});
});
// Dispatch UpdateInterview after 1000ms of last input event
this.goal$.pipe(debounceTime(1000)).subscribe(goal => {
this.store.dispatch(new UpdateInterview(this.interviewId, { goal }));
});
}
onGoalInput(value: string) {
this.goal$.next(value);
}
onNavigateForward(facCritId: number) {
const { auditId, interviewId } = this.activatedRoute.snapshot.params;
const indexOfFacCrit = this.facCritIds.indexOf(facCritId);
const url = `audits/${auditId}/interviews/${interviewId}/${
this.facCritIds[indexOfFacCrit + 1]
}`;
if (indexOfFacCrit + 1 !== this.facCritIds.length) {
this.router.navigate([url]);
}
}
onNaviagteBack(facCritId: number) {
const { auditId, interviewId } = this.activatedRoute.snapshot.params;
const indexOfFacCrit = this.facCritIds.indexOf(facCritId);
const url = `audits/${auditId}/interviews/${interviewId}/${
this.facCritIds[indexOfFacCrit - 1]
}`;
if (indexOfFacCrit > 0) {
this.router.navigate([url]);
}
}
getFacCritPosition(id: number) {
const indexOfFacCrit = this.facCritIds.indexOf(id) + 1;
return indexOfFacCrit + '/' + this.facCritIds.length;
}
onFinishClick() {
this.store.dispatch(
new UpdateInterview(this.interviewId, { status: InterviewStatus.Finished }),
);
}
}
<ng-container *ngIf="interview$ | async; let interview">
<header class="header-main">
<div class="header-main-info">
<h4 data-cy="heading">
Interview
<span class="label">{{ interview.startDate | date: 'dd.MM.yyyy' }}</span>
</h4>
<span class="subtitle-2" *ngFor="let person of interview.contactPersons" data-cy="subheading">
{{ person.forename + ' ' + person.surname + ',' }}
</span>
</div>
<div>
<button class="mr-1" hero [routerLink]="['/audits/' + interview.auditId + '/interviews']" nbButton>
<nb-icon icon="arrow-back-outline"></nb-icon>
Interviews
</button>
<button (click)="onFinishClick()" status="primary" hero nbButton>
<nb-icon icon="checkmark-square-outline"></nb-icon>
Abschließen
</button>
</div>
</header>
<nb-form-field class="mt-2" id="input-goal">
<nb-icon nbPrefix icon="compass-outline"></nb-icon>
<input [value]="interview.goal" (input)="onGoalInput($event.target.value)" placeholder="Ziel des Interviews..." type="text" fullWidth nbInput data-cy="notes" />
</nb-form-field>
</ng-container>
<nb-card class="mt-1">
<nb-card-body>
<ng-container *ngIf="facCrit$ | async; let facCrit">
<div class="nb-card-header-navigation">
<nb-icon class="ml-1 icon-navigation" (click)="onNaviagteBack(facCrit.id)" icon="arrow-ios-back-outline"></nb-icon>
<p class="subtitle">
{{ facCrit.name }}
<span *ngIf="facCritIds" class="text-hint">{{ getFacCritPosition(facCrit.id) }}</span>
</p>
<nb-icon class="mr-1 icon-navigation" (click)="onNavigateForward(facCrit.id)" icon="arrow-ios-forward-outline"></nb-icon>
</div>
</ng-container>
</nb-card-body>
</nb-card>
<ng-container *ngIf="answers$ | async | answerByIds: interviewId:facCritId; let answers">
<app-answer-question-list [answers]="answers"></app-answer-question-list>
</ng-container>
@import '../../../sass/utils';
@import '../../../../node_modules/@nebular/theme/styles/theming';
@import '../../../../node_modules/@nebular/theme/styles/themes/default';
nb-card-body {
padding: 7px !important;
}
#input-goal {
position: sticky;
top: nb-theme(header-height) - nb-theme(header-padding) + 1.5;
z-index: 1;
}
.header-main {
display: flex;
justify-content: space-between;
}
.nb-card-header-navigation {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 0 5px;
justify-items: center;
align-items: center;
}
.icon-navigation {
cursor: pointer;
}
Legend
Html element with directive