Skip to content

Commit da0d835

Browse files
committed
The threats are now grouped by city.
1 parent e8fe049 commit da0d835

File tree

8 files changed

+102
-30
lines changed

8 files changed

+102
-30
lines changed

src/app/app.component.html

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,4 @@
1+
<app-header></app-header>
12
<div class="container">
2-
<div class="row">
3-
<div class="page-header">
4-
<h1>{{title}}</h1>
5-
</div>
6-
</div>
7-
<div class="row">
8-
<div class="col-xs-10">
9-
<button [routerLink]="['/login']" routerLinkActive="active" class="btn btn-primary">Login</button>
10-
<button [routerLink]="['/threat']" routerLinkActive="active" class="btn btn-danger" *ngIf="securityService.isLoggedIn()">Threats</button>
11-
<button [routerLink]="['']" routerLinkActive="active" class="btn btn-primary">Home</button>
12-
<hr>
13-
<!-- Render the routing -->
14-
<div class="container">
15-
<router-outlet></router-outlet>
16-
</div>
17-
</div>
18-
</div>
19-
<div class="row">
20-
<hr>
21-
Footer
22-
</div>
3+
<router-outlet></router-outlet>
234
</div>

src/app/app.module.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import {ThreatComponent} from "./components/threat/threat.component";
1212
import {ThreatService} from "./services/threat.service";
1313
import {SpinnerComponent} from "./components/spinner/spinner.component";
1414
import {AgmCoreModule} from "angular2-google-maps/core";
15+
import { HeaderComponent } from './components/header/header.component';
16+
import { DropdownDirective } from './directives/dropdown.directive';
1517

1618
@NgModule({
1719
declarations: [
@@ -20,7 +22,9 @@ import {AgmCoreModule} from "angular2-google-maps/core";
2022
HomeComponent,
2123
GreetingComponent,
2224
ThreatComponent,
23-
SpinnerComponent
25+
SpinnerComponent,
26+
HeaderComponent,
27+
DropdownDirective
2428
],
2529
imports: [
2630
BrowserModule,

src/app/components/header/header.component.css

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<nav class="navbar navbar-default">
2+
<div class="container-fluid">
3+
<!-- Brand and toggle get grouped for better mobile display -->
4+
<div class="navbar-header">
5+
<a class="navbar-brand" [routerLink]="['/']">Threat Monitor</a>
6+
</div>
7+
8+
<!-- Collect the nav links, forms, and other content for toggling -->
9+
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
10+
<ul class="nav navbar-nav">
11+
<li routerLinkActive="active"><a [routerLink]="['/threat']">Threats</a></li>
12+
</ul>
13+
<ul class="nav navbar-nav navbar-right">
14+
<li class="dropdown" rbDropdown>
15+
<a class="dropdown-toggle"
16+
role="button"
17+
aria-haspopup="true"
18+
aria-expanded="false">User<span class="caret"></span></a>
19+
<ul class="dropdown-menu">
20+
<li><a [routerLink]="['/login']" style="cursor: pointer;">Login</a></li>
21+
<li><a style="cursor: pointer;">Logout</a></li>
22+
</ul>
23+
</li>
24+
</ul>
25+
</div><!-- /.navbar-collapse -->
26+
</div><!-- /.container-fluid -->
27+
</nav>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {Component, OnInit} from "@angular/core";
2+
3+
@Component({
4+
selector: 'app-header',
5+
templateUrl: './header.component.html',
6+
styleUrls: ['./header.component.css']
7+
})
8+
export class HeaderComponent implements OnInit {
9+
10+
constructor() {
11+
}
12+
13+
ngOnInit() {
14+
}
15+
16+
}

src/app/components/threat/threat.component.html

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@
66
<!-- Loading icon -->
77
<spinner [visible]="isLoading"></spinner>
88

9-
<!-- TODO: Organize threats by location...-->
10-
<!--<ul class="nav nav-pills nav-justified">-->
11-
<!--<li *ngFor="let location of locationThreats" role="presentation" class="active">{{ location.city}}</li>-->
12-
<!--</ul>-->
13-
149
<!-- Number of threats -->
1510
<div class="alert alert-danger" role="alert" *ngIf="!isLoading">
1611
{{ (threats) ? threats.length : 0 }} threats in {{ (locationThreats) ? locationThreats.length : 0 }} locations
1712
</div>
1813

19-
<ul class="list-group posts" *ngIf="!isLoading">
20-
<li class="list-group-item" [class.active]="isActive(i)" *ngFor="let threat of threats; let i=index"
14+
<!-- Group threats by city -->
15+
<ul class="nav nav-pills" *ngIf="!isLoading">
16+
<li *ngFor="let location of locationThreats; let i=index" role="presentation" [class.active]="location === selectedLocation">
17+
<a (click)="onSelectLocation(location)">{{ location.city + ' (' + location.threats.length + ')'}} </a>
18+
</li>
19+
</ul>
20+
21+
<ul class="list-group posts" *ngIf="!isLoading && selectedLocation">
22+
<li class="list-group-item" [class.active]="isActive(i)" *ngFor="let threat of selectedLocation.threats; let i=index"
2123
(click)="onClick(threat)">
2224
<span class="badge">{{ threat.temperatureAlert }}</span>
2325
{{i+1}} - {{ threat.organization}}, {{ threat.assetType }}, {{ threat.threatType }}, {{ threat.threatSeverity }}, {{ threat.threatDateBegin}}

src/app/components/threat/threat.component.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class ThreatComponent implements OnInit {
1313
isLoading: Boolean = true;
1414
threats: Threat[] = []
1515
locationThreats: LocationThreat[] = []
16+
selectedLocation: LocationThreat = null
1617
selectedThreat: Threat = null
1718

1819
constructor(private threatService: ThreatService) {
@@ -28,6 +29,11 @@ export class ThreatComponent implements OnInit {
2829
console.log(result);
2930
this.threats = result.threats;
3031
this.locationThreats = result.locations
32+
this.selectedLocation = this.locationThreats.length > 0 ? this.locationThreats[0] : null;
33+
console.log('Selected location: ' + this.selectedLocation.city)
34+
if (this.selectedLocation) {
35+
this.selectedThreat = (this.selectedLocation.threats.length > 0) ? this.selectedLocation.threats[0] : null;
36+
}
3137
},
3238
error => {
3339
console.log(error);
@@ -41,6 +47,16 @@ export class ThreatComponent implements OnInit {
4147
)
4248
}
4349

50+
/**
51+
* Location selection
52+
* @param location
53+
*/
54+
onSelectLocation(location: LocationThreat) {
55+
this.selectedLocation = location;
56+
this.selectedThreat = (this.selectedLocation.threats.length > 0) ? this.selectedLocation.threats[0] : null;
57+
console.log('Selected location: ' + this.selectedLocation.city)
58+
}
59+
4460
/**
4561
* Threat selection.
4662
*/
@@ -53,7 +69,8 @@ export class ThreatComponent implements OnInit {
5369
* Is a post currently selected/active?
5470
*/
5571
isActive(threatIndex: number) {
56-
return this.selectedThreat != null && this.threats[threatIndex] == this.selectedThreat;
72+
// return this.selectedThreat != null && this.threats[threatIndex] == this.selectedThreat;
73+
return this.selectedThreat != null && this.selectedLocation.threats[threatIndex] == this.selectedThreat;
5774
}
5875

5976
clickedMarker() {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Directive, HostBinding, HostListener} from "@angular/core";
2+
3+
@Directive({
4+
selector: '[rbDropdown]'
5+
})
6+
export class DropdownDirective {
7+
8+
// The CSS class 'open' (From Bootstrap) is appended to the element with this directive
9+
// if opened() returns true.
10+
@HostBinding('class.open') get opened() {
11+
return this.isOpen;
12+
}
13+
14+
// Handle click events on the element
15+
@HostListener('click') openDropdown() {
16+
this.isOpen = true;
17+
}
18+
19+
// Handle mouse leave events
20+
@HostListener('mouseleave') closeDropdown() {
21+
this.isOpen = false;
22+
}
23+
24+
private isOpen = false;
25+
}

0 commit comments

Comments
 (0)