Skip to content

Commit

Permalink
Initial timetable creator and frequency pattern creator for desktop c…
Browse files Browse the repository at this point in the history
…lient
  • Loading branch information
daveajlee committed Aug 29, 2023
1 parent 24b11e3 commit 4e8e308
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 1 deletion.
2 changes: 2 additions & 0 deletions desktop/src/app/app-routing.module.ts
Expand Up @@ -11,6 +11,7 @@ import {VehiclesComponent} from './vehicles/vehicles.component';
import {VehicleDetailComponent} from './vehicles/vehicle-detail/vehicle-detail.component';
import {ManagementComponent} from './management/management.component';
import {RoutecreatorComponent} from "./routecreator/routecreator.component";
import {TimetablecreatorComponent} from "./timetablecreator/timetablecreator.component";

/**
* Define the links which work in this application.
Expand All @@ -19,6 +20,7 @@ const appRoutes: Routes = [
{ path: 'management', component: ManagementComponent },
{ path: 'routes', component: RoutesComponent },
{ path: 'routecreator', component: RoutecreatorComponent },
{ path: 'timetablecreator', component: TimetablecreatorComponent},
{ path: 'scenariolist', component: ScenariolistComponent },
{ path: 'scenarioinfo', component: ScenarioinfoComponent },
{ path: 'scenariomap', component: ScenariomapComponent },
Expand Down
4 changes: 3 additions & 1 deletion desktop/src/app/app.module.ts
Expand Up @@ -25,6 +25,7 @@ import {GameService} from './shared/game.service';
import { ScenariomapComponent } from './scenariomap/scenariomap.component';
import { ScenarioinfoComponent } from './scenarioinfo/scenarioinfo.component';
import { RoutecreatorComponent } from './routecreator/routecreator.component';
import { TimetablecreatorComponent } from './timetablecreator/timetablecreator.component';

@NgModule({
declarations: [
Expand All @@ -42,7 +43,8 @@ import { RoutecreatorComponent } from './routecreator/routecreator.component';
ScenariolistComponent,
ScenariomapComponent,
ScenarioinfoComponent,
RoutecreatorComponent
RoutecreatorComponent,
TimetablecreatorComponent
],
imports: [
BrowserModule,
Expand Down
14 changes: 14 additions & 0 deletions desktop/src/app/game/game.model.ts
Expand Up @@ -42,4 +42,18 @@ export class Game {
this.routes.push(route);
}

/**
* This method returns the route object corresponding to the route number or null if none was found.
* @param routeNumber the route number to retrieve the route object for.
* @returns the route object or null if no route object matching the route number was found,
*/
getRoute( routeNumber: string ): Route {
for ( var i = 0; i < this.routes.length; i++ ) {
if ( this.routes[i].routeNumber === routeNumber ) {
return this.routes[i];
}
}
return null;
}

}
1 change: 1 addition & 0 deletions desktop/src/app/routecreator/routecreator.component.ts
Expand Up @@ -69,6 +69,7 @@ export class RoutecreatorComponent implements OnInit {
route.endStop = this.endStop;
route.stops = this.stops;
this.gameService.getGame().addRoute(route);
this.router.navigate(['timetablecreator'], { queryParams: { routeNumber: this.routeNumber } });
}

}
@@ -0,0 +1,6 @@
/* CSS options for the timetable creator component */
.center-button {
text-align: center;
padding-top: 10px;
margin-top: 25px;
}
84 changes: 84 additions & 0 deletions desktop/src/app/timetablecreator/timetablecreator.component.html
@@ -0,0 +1,84 @@
<!-- Show the header -->
<app-header></app-header>

<!-- Jumbotron with page title -->
<div class="jumbotron">
<h1 class="display-4 text-center">Create New Timetable for Route {{getRouteNumber()}}</h1>
</div>

<!-- Show an input box where the user can enter a name for this timetable. -->
<div class="form-group top-space m-5">
<label for="timetableName" style="font-weight: bold;">Timetable Name:</label>
<input class="form-control" [(ngModel)]="timetableName" type="text" id="timetableName"/>
</div>

<!-- Show an input box where the user can choose the valid from date -->
<div class="form-group top-space m-5">
<label for="validFromDate" style="font-weight: bold;">Valid From:</label>
<input class="form-control" [(ngModel)]="validFromDate" type="date" id="validFromDate"/>
</div>

<!-- Show an input box where the user can choose the valid to date -->
<div class="form-group top-space m-5">
<label for="validToDate" style="font-weight: bold;">Valid To:</label>
<input class="form-control" [(ngModel)]="validToDate" type="date" id="validToDate"/>
</div>

<!-- Button to open the frequency pattern modal -->
<div class="center-button">
<button type="button" class="btn btn-primary btn-lg" data-bs-toggle="modal" data-bs-target="#frequencyPatternModal">
Create Frequency Pattern
</button>
</div>

<!-- Modal -->
<div class="modal fade" id="frequencyPatternModal" tabindex="-1" aria-labelledby="frequencyPatternModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Frequency Pattern</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- Show an input box where the user can enter a name for this frequency pattern. -->
<div class="form-group top-space m-2">
<label for="frequencyPatternName" style="font-weight: bold;">Name:</label>
<input class="form-control" [(ngModel)]="frequencyPatternName" type="text" id="frequencyPatternName"/>
</div>

<!-- Show a set of checkboxes so that the user can choose the days of operation -->
<div class="form-group top-space m-2">
<label style="font-weight: bold;">Days of Operation:</label>
<div class="col" *ngFor="let item of this.getDaysOfWeek() let i = index" >
<input class="checkbox" type="checkbox" [id]="'checkbox-' + i"> {{item.split(':')[0]}}
</div>
</div>

<div class="form-group top-space m-2">
<div class="row">
<div class="col">
From: <select class="form-control" [(ngModel)]="frequencyPatternStartStop" id="frequencyPatternStartStop">
<option *ngFor="let item of this.getFrequencyPatternStartStops()" [ngValue]="item">{{ item }}</option>
</select>
</div>
<div class="col">
To: <select class="form-control" [(ngModel)]="frequencyPatternEndStop" id="frequencyPatternEndStop">
<option *ngFor="let item of this.getFrequencyPatternEndStops()" [ngValue]="item">{{ item }}</option>
</select>
</div>
</div>
</div>

</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>

<!-- Button to save the timetable -->
<div class="center-button">
<button type="submit" (click)="onSubmitTimetable()" class="btn btn-primary btn-lg">Save Timetable</button>
</div>
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TimetablecreatorComponent } from './timetablecreator.component';

describe('TimetablecreatorComponent', () => {
let component: TimetablecreatorComponent;
let fixture: ComponentFixture<TimetablecreatorComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TimetablecreatorComponent]
});
fixture = TestBed.createComponent(TimetablecreatorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
78 changes: 78 additions & 0 deletions desktop/src/app/timetablecreator/timetablecreator.component.ts
@@ -0,0 +1,78 @@
import { Component } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {GameService} from "../shared/game.service";
import {DatePipe} from "@angular/common";

@Component({
selector: 'app-timetablecreator',
templateUrl: './timetablecreator.component.html',
styleUrls: ['./timetablecreator.component.css']
})
export class TimetablecreatorComponent {

routeNumber: string;
timetableName: string;
validFromDate: string;
validToDate: string;
gameService: GameService;

frequencyPatternName: string;
frequencyPatternStartStop: string;
frequencyPatternEndStop: string;

constructor(private route: ActivatedRoute, private gameService2: GameService,
public router: Router, private datePipe: DatePipe) {
this.gameService = gameService2;
// Valid from date is current date.
this.validFromDate = this.datePipe.transform(new Date(), 'yyyy-MM-dd');
// Valid to date is current date + 1 year.
let oneFromYearNow = new Date(new Date().setFullYear(new Date().getFullYear() + 1));
this.validToDate = this.datePipe.transform(oneFromYearNow, 'yyyy-MM-dd');
}

/**
* Copy parameters from last request so that we do not lose the information that the user has provided.
*/
ngOnInit(): void {
this.route.queryParams
.subscribe(params => {
this.routeNumber = params.routeNumber;
}
);
}

getRouteNumber(): string {
return this.routeNumber;
}

getDaysOfWeek(): string[] {
return ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
}

getFrequencyPatternStartStops(): string[] {
let possibleStops = [];
let route = this.gameService.getGame().getRoute(this.routeNumber);
if ( !this.frequencyPatternStartStop ) {
this.frequencyPatternStartStop = route.startStop;
}
possibleStops.push(route.startStop);
possibleStops = possibleStops.concat(route.stops);
return possibleStops;
}

getFrequencyPatternEndStops(): string[] {
let possibleStops = [];
let route = this.gameService.getGame().getRoute(this.routeNumber);
if ( !this.frequencyPatternEndStop ) {
this.frequencyPatternEndStop = route.endStop;
}
possibleStops.push(route.endStop);
possibleStops = possibleStops.concat(route.stops);
return possibleStops;
}

onSubmitTimetable(): void {
console.log('Timetable submission coming soon!');
}

}

0 comments on commit 4e8e308

Please sign in to comment.