Commit 2a6c80f5 authored by Doompickaxe's avatar Doompickaxe

Add participant number

parent c2e9efa5
......@@ -4,7 +4,7 @@ import { RouterModule, Routes } from '@angular/router';
import { ModulesComponent } from './components/modules/modules.component';
import { RegistrationComponent } from './components/registration/registration.component';
import { SessionsComponent } from './components/sessions/sessions.component';
import { UpcomingComponent } from './components/upcoming/upcoming.component';
import { UpcomingsComponent } from './components/upcomings/upcomings.component';
const routes: Routes = [
{
......@@ -25,12 +25,12 @@ const routes: Routes = [
},
{
path: '',
component: UpcomingComponent,
component: UpcomingsComponent,
outlet: 'upcoming',
},
{
path: ':curriculum/modules',
component: UpcomingComponent,
component: UpcomingsComponent,
outlet: 'upcoming',
},
];
......
......@@ -16,6 +16,6 @@
<div class="request-more">
Couldn't find what you were looking for? Request it
<a href="mailto:klaus.unger@software-craftsmen.at" target="_blank">here</a>
<a href="mailto:klaus.unger@software-craftsmen.at?subject=Request%20for%20Training" target="_blank">here</a>
</div>
</div>
......@@ -24,6 +24,8 @@ import { SessionsComponent } from './components/sessions/sessions.component';
import { TrainerComponent } from './components/trainer/trainer.component';
import { TrainersComponent } from './components/trainers/trainers.component';
import { UpcomingComponent } from './components/upcoming/upcoming.component';
import { UpcomingsComponent } from './components/upcomings/upcomings.component';
import { ReplacePipe } from './pipes/replace.pipe';
@NgModule({
declarations: [
......@@ -37,7 +39,9 @@ import { UpcomingComponent } from './components/upcoming/upcoming.component';
SessionsComponent,
TrainerComponent,
TrainersComponent,
UpcomingsComponent,
UpcomingComponent,
ReplacePipe,
],
imports: [
AppRoutingModule,
......@@ -61,7 +65,7 @@ import { UpcomingComponent } from './components/upcoming/upcoming.component';
CurriculumComponent,
ModulesComponent,
SessionsComponent,
UpcomingComponent,
UpcomingsComponent,
],
bootstrap: [AppComponent],
})
......
......@@ -5,6 +5,10 @@
</div>
<div class="description">
{{ item.description }}
<br />
Between {{ item.minParticipants }} and {{ item.maxParticipants }} Participants.
<br />
{{ isTheoretical() }}.
</div>
</div>
</mat-list-item>
......@@ -20,4 +20,11 @@ export class ModuleComponent {
}
return false;
}
isTheoretical(): string {
if (this.item.isTheoretical) {
return 'It is theoretical';
}
return 'It is Hands-On';
}
}
......@@ -2,6 +2,7 @@
:host {
display: flex;
height: fit-content;
mat-card {
display: flex;
......
......@@ -6,6 +6,8 @@
<div class="description">
training is {{ item.location.type | lowercase }} from {{ item.endAt | date: 'HH:mm' }} until
{{ item.endAt | date: 'HH:mm' }}
<br />
Seats left: {{ item.seatsLeft }}
</div>
<div *ngIf="item.trainers.length > 0">
<div (click)="showTrainers()" class="trainer">
......
<mat-card class="upcoming">
<mat-card-title>Upcoming</mat-card-title>
<mat-card-content>
<mat-list>
<div *ngIf="(items$ | async)?.length > 0; else noitems">
<div *ngFor="let item of items$ | async" class="session">
<app-session [item]="item"></app-session>
</div>
</div>
<ng-template #noitems>
<div>No results!</div>
</ng-template>
</mat-list>
</mat-card-content>
</mat-card>
<mat-list-item>
<div class="content">
<div class="header" [routerLink]="linkToRegistration$ | async">
{{ (module$ | async)?.title }} at {{ item.startAt | date: 'dd.MM.yyyy' }}
</div>
<div class="description">
training is {{ item.location.type | lowercase | replace: '_':'-' }} from {{ item.endAt | date: 'HH:mm' }} until
{{ item.endAt | date: 'HH:mm' }}
<br />
Seats left: {{ item.seatsLeft }}
</div>
</div>
</mat-list-item>
@import 'src/themes';
:host {
margin-left: auto;
mat-list-item {
height: fit-content;
padding-bottom: 10px;
}
mat-card {
.content {
display: flex;
flex-direction: column;
margin: 10px;
}
mat-card-title {
color: mat-color($trasc-primary, default);
.header {
display: flex;
font-weight: bold;
&:hover {
text-decoration: underline;
cursor: pointer;
}
}
.description {
display: flex;
}
}
......@@ -2,30 +2,42 @@ import { of } from 'rxjs';
import { TestBed, async } from '@angular/core/testing';
import { SessionsService } from '../../../../generated-sources/openapi';
import { SessionsServiceMock } from '../../services/sessions.service.mock';
import { ModulesService, SessionResponse } from '../../../../generated-sources/openapi';
import { ModulesServiceMock } from '../../services/modules.service.mock';
import { UpcomingComponent } from './upcoming.component';
describe('UpcomingComponent', () => {
let component: UpcomingComponent;
let service: SessionsServiceMock;
let service: ModulesServiceMock;
const session: SessionResponse = {
id: 'SESSION',
moduleId: 'MODULE',
trainers: [],
startAt: '2020-01-01T00:00:00.000Z',
endAt: '2020-01-01T00:00:00.000Z',
location: {},
};
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{ provide: SessionsService, useClass: SessionsServiceMock }, UpcomingComponent],
providers: [{ provide: ModulesService, useClass: ModulesServiceMock }, UpcomingComponent],
});
component = TestBed.get(UpcomingComponent);
service = TestBed.get(SessionsService);
service.sessionsUpcomingGet.mockReturnValue(of());
service = TestBed.get(ModulesService);
service.modulesIdGet.mockReturnValue(of());
}));
it('should get all sessions on init', () => {
it('should get module on init', () => {
// given
component.item = session;
// when
component.ngOnInit();
// then
expect(service.sessionsUpcomingGet).toHaveBeenCalledWith();
expect(service.modulesIdGet).toHaveBeenCalledWith(session.moduleId);
});
});
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Component, OnInit } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { SessionResponse, SessionsService } from '../../../../generated-sources/openapi';
import { ModuleResponse, ModulesService, SessionResponse } from '../../../../generated-sources/openapi';
@Component({
selector: 'app-upcoming',
......@@ -10,11 +11,18 @@ import { SessionResponse, SessionsService } from '../../../../generated-sources/
styleUrls: ['./upcoming.component.scss'],
})
export class UpcomingComponent implements OnInit {
items$: Observable<SessionResponse[]>;
@Input()
item: SessionResponse;
constructor(private sessionsService: SessionsService) {}
module$: Observable<ModuleResponse>;
linkToRegistration$: Observable<string>;
ngOnInit() {
this.items$ = this.sessionsService.sessionsUpcomingGet();
constructor(private modulesService: ModulesService) {}
ngOnInit(): void {
this.module$ = this.modulesService.modulesIdGet(this.item.moduleId);
this.linkToRegistration$ = this.module$.pipe(
map((x) => `${x.curriculumId}/modules/${x.id}/sessions/${this.item.id}/registration`)
);
}
}
<mat-card class="upcoming">
<mat-card-title>Upcoming</mat-card-title>
<mat-card-content>
<mat-list>
<div *ngIf="(items$ | async)?.length > 0; else noitems">
<div *ngFor="let item of items$ | async" class="session">
<app-upcoming [item]="item"></app-upcoming>
</div>
</div>
<ng-template #noitems>
<div>No results!</div>
</ng-template>
</mat-list>
</mat-card-content>
</mat-card>
@import 'src/themes';
:host {
margin-left: auto;
mat-card {
display: flex;
flex-direction: column;
margin: 10px;
}
mat-card-title {
color: mat-color($trasc-primary, default);
}
}
import { of } from 'rxjs';
import { TestBed, async } from '@angular/core/testing';
import { SessionsService } from '../../../../generated-sources/openapi';
import { SessionsServiceMock } from '../../services/sessions.service.mock';
import { UpcomingsComponent } from './upcomings.component';
describe('UpcomingsComponent', () => {
let component: UpcomingsComponent;
let service: SessionsServiceMock;
beforeEach(async(() => {
TestBed.configureTestingModule({
providers: [{ provide: SessionsService, useClass: SessionsServiceMock }, UpcomingsComponent],
});
component = TestBed.get(UpcomingsComponent);
service = TestBed.get(SessionsService);
service.sessionsUpcomingGet.mockReturnValue(of());
}));
it('should get all sessions on init', () => {
// when
component.ngOnInit();
// then
expect(service.sessionsUpcomingGet).toHaveBeenCalledWith();
});
});
import { Observable } from 'rxjs';
import { Component, OnInit } from '@angular/core';
import { SessionResponse, SessionsService } from '../../../../generated-sources/openapi';
@Component({
selector: 'app-upcomings',
templateUrl: './upcomings.component.html',
styleUrls: ['./upcomings.component.scss'],
})
export class UpcomingsComponent implements OnInit {
items$: Observable<SessionResponse[]>;
constructor(private sessionsService: SessionsService) {}
ngOnInit() {
this.items$ = this.sessionsService.sessionsUpcomingGet();
}
}
import { ReplacePipe } from './replace.pipe';
describe('ReplacePipe', () => {
const pipe: ReplacePipe = new ReplacePipe();
it('should replace characters', () => {
// given
const given = 'on_site';
const expected = 'on-site';
// when
const result = pipe.transform(given, '_', '-');
// then
expect(result).toEqual(expected);
});
it('should return an error on invalid arguments', () => {
// given
const excpected = 'Two parameters needed';
// when
const result = pipe.transform('', '_');
// then
expect(result).toEqual(excpected);
});
});
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'replace',
pure: true,
})
export class ReplacePipe implements PipeTransform {
transform(value: string, ...args: string[]): string {
if (args.length !== 2) {
return 'Two parameters needed';
}
return value.replace(args[0], args[1]);
}
}
export class ModulesServiceMock {
curriculumsIdModulesGet: jest.Mock = jest.fn().mockName('curriculumsIdModulesGet');
modulesIdGet: jest.Mock = jest.fn().mockName('modulesIdGet');
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment