Commit de59ffef8b72e48bd09fedbb9245a1693fd2cbcc
1 parent
b02c6cc825
Exists in
master
add model + search
Showing 16 changed files with 189 additions and 45 deletions Side-by-side Diff
- package-lock.json
- package.json
- src/app/component/app.component.html
- src/app/component/app.component.scss
- src/app/component/app.component.ts
- src/app/component/app.module.ts
- src/app/component/import-vessels/import-vessels.component.ts
- src/app/component/list-vessel/list-vessel.component.html
- src/app/component/list-vessel/list-vessel.component.scss
- src/app/component/list-vessel/list-vessel.component.ts
- src/app/model/message.spec.ts
- src/app/model/vessel.spec.ts
- src/app/model/vessel.ts
- src/app/model/vessels.spec.ts
- src/app/model/vessels.ts
- src/app/service/vessels.service.ts
package-lock.json
View file @
de59ffe
... | ... | @@ -1746,6 +1746,14 @@ |
1746 | 1746 | "@types/jasmine": "*" |
1747 | 1747 | } |
1748 | 1748 | }, |
1749 | + "@types/jquery": { | |
1750 | + "version": "3.5.3", | |
1751 | + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.3.tgz", | |
1752 | + "integrity": "sha512-IENpHTjGksr2wQS6ZO8eMIE0tIB22Ywg+n3/yAWCa56VSZ26phcwAbFdh9+VNUWk7e83qB27QLax3Rf4G92Y9A==", | |
1753 | + "requires": { | |
1754 | + "@types/sizzle": "*" | |
1755 | + } | |
1756 | + }, | |
1749 | 1757 | "@types/json-schema": { |
1750 | 1758 | "version": "7.0.6", |
1751 | 1759 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", |
... | ... | @@ -1759,9 +1767,9 @@ |
1759 | 1767 | "dev": true |
1760 | 1768 | }, |
1761 | 1769 | "@types/node": { |
1762 | - "version": "12.19.1", | |
1763 | - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.1.tgz", | |
1764 | - "integrity": "sha512-/xaVmBBjOGh55WCqumLAHXU9VhjGtmyTGqJzFBXRWZzByOXI5JAJNx9xPVGEsNizrNwcec92fQMj458MWfjN1A==", | |
1770 | + "version": "12.19.2", | |
1771 | + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.2.tgz", | |
1772 | + "integrity": "sha512-SRH6QM0IMOBBFmDiJ75vlhcbUEYEquvSuhsVW9ijG20JvdFTfOrB1p6ddZxz5y/JNnbf+9HoHhjhOVSX2hsJyA==", | |
1765 | 1773 | "dev": true |
1766 | 1774 | }, |
1767 | 1775 | "@types/q": { |
... | ... | @@ -1776,6 +1784,11 @@ |
1776 | 1784 | "integrity": "sha512-tGomyEuzSC1H28y2zlW6XPCaDaXFaD6soTdb4GNdmte2qfHtrKqhy0ZFs4r/1hpazCfEZqeTSRLvSasmEx89uw==", |
1777 | 1785 | "dev": true |
1778 | 1786 | }, |
1787 | + "@types/sizzle": { | |
1788 | + "version": "2.3.2", | |
1789 | + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", | |
1790 | + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==" | |
1791 | + }, | |
1779 | 1792 | "@types/source-list-map": { |
1780 | 1793 | "version": "0.1.2", |
1781 | 1794 | "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", |
... | ... | @@ -2106,6 +2119,21 @@ |
2106 | 2119 | "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", |
2107 | 2120 | "dev": true |
2108 | 2121 | }, |
2122 | + "angular-split": { | |
2123 | + "version": "4.0.0", | |
2124 | + "resolved": "https://registry.npmjs.org/angular-split/-/angular-split-4.0.0.tgz", | |
2125 | + "integrity": "sha512-HiTEazVlnpovjeIL0gEgOWdfjTcm8/hdhtOx8rkLJTN//uc9ImExVXnVRBGZwAPeAHMJ8O+8IJWizpzIhRwk/g==", | |
2126 | + "requires": { | |
2127 | + "tslib": "^1.9.0" | |
2128 | + }, | |
2129 | + "dependencies": { | |
2130 | + "tslib": { | |
2131 | + "version": "1.14.1", | |
2132 | + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | |
2133 | + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | |
2134 | + } | |
2135 | + } | |
2136 | + }, | |
2109 | 2137 | "ansi-colors": { |
2110 | 2138 | "version": "3.2.4", |
2111 | 2139 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", |
... | ... | @@ -7864,6 +7892,14 @@ |
7864 | 7892 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", |
7865 | 7893 | "dev": true |
7866 | 7894 | }, |
7895 | + "ninja-splitter": { | |
7896 | + "version": "1.1.3", | |
7897 | + "resolved": "https://registry.npmjs.org/ninja-splitter/-/ninja-splitter-1.1.3.tgz", | |
7898 | + "integrity": "sha512-qpDVIVD0ZWjVAu0tLiEOUgwWhx7jBOSW9aiES2fqFO+EGKgl+zFjj6uVBIMcz+b7rN8TUVuH21pCG4vCB2AkCA==", | |
7899 | + "requires": { | |
7900 | + "tslib": "^2.0.0" | |
7901 | + } | |
7902 | + }, | |
7867 | 7903 | "node-fetch-npm": { |
7868 | 7904 | "version": "2.0.4", |
7869 | 7905 | "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", |
... | ... | @@ -11578,6 +11614,11 @@ |
11578 | 11614 | "extend-shallow": "^3.0.0" |
11579 | 11615 | } |
11580 | 11616 | }, |
11617 | + "split.js": { | |
11618 | + "version": "1.6.2", | |
11619 | + "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.6.2.tgz", | |
11620 | + "integrity": "sha512-72C7zcQePzlmWqPOKkB2Ro0sUmnWSx+qEWXjLJKk6Qp4jAkFRz1hJgJb+ay6ZQyz/Aw9r8N/PZiCEKbPVpFoDQ==" | |
11621 | + }, | |
11581 | 11622 | "sprintf-js": { |
11582 | 11623 | "version": "1.0.3", |
11583 | 11624 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", |
... | ... | @@ -12281,9 +12322,9 @@ |
12281 | 12322 | "dev": true |
12282 | 12323 | }, |
12283 | 12324 | "typescript": { |
12284 | - "version": "4.0.3", | |
12285 | - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.3.tgz", | |
12286 | - "integrity": "sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg==", | |
12325 | + "version": "4.0.5", | |
12326 | + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.5.tgz", | |
12327 | + "integrity": "sha512-ywmr/VrTVCmNTJ6iV2LwIrfG1P+lv6luD8sUJs+2eI9NLGigaN+nUQc13iHqisq7bra9lnmUSYqbJvegraBOPQ==", | |
12287 | 12328 | "dev": true |
12288 | 12329 | }, |
12289 | 12330 | "ua-parser-js": { |
package.json
View file @
de59ffe
... | ... | @@ -19,12 +19,16 @@ |
19 | 19 | "@angular/platform-browser": "~10.2.0", |
20 | 20 | "@angular/platform-browser-dynamic": "~10.2.0", |
21 | 21 | "@angular/router": "~10.2.0", |
22 | + "@types/jquery": "^3.5.3", | |
23 | + "angular-split": "^4.0.0", | |
22 | 24 | "bootstrap": "^4.5.3", |
23 | 25 | "jquery": "^3.5.1", |
24 | 26 | "ngx-bootstrap-icons": "^1.2.0", |
25 | 27 | "ngx-dropzone": "^2.2.2", |
28 | + "ninja-splitter": "^1.1.3", | |
26 | 29 | "popper.js": "^1.16.1", |
27 | 30 | "rxjs": "^6.6.3", |
31 | + "split.js": "^1.6.2", | |
28 | 32 | "tslib": "^2.0.0", |
29 | 33 | "zone.js": "~0.10.2" |
30 | 34 | }, |
31 | 35 | |
... | ... | @@ -32,9 +36,9 @@ |
32 | 36 | "@angular-devkit/build-angular": "~0.1002.0", |
33 | 37 | "@angular/cli": "~10.2.0", |
34 | 38 | "@angular/compiler-cli": "~10.2.0", |
35 | - "@types/node": "^12.11.1", | |
36 | 39 | "@types/jasmine": "~3.5.0", |
37 | 40 | "@types/jasminewd2": "~2.0.3", |
41 | + "@types/node": "^12.19.2", | |
38 | 42 | "codelyzer": "^6.0.0", |
39 | 43 | "jasmine-core": "~3.6.0", |
40 | 44 | "jasmine-spec-reporter": "~5.0.0", |
... | ... | @@ -46,7 +50,7 @@ |
46 | 50 | "protractor": "~7.0.0", |
47 | 51 | "ts-node": "~8.3.0", |
48 | 52 | "tslint": "~6.1.0", |
49 | - "typescript": "~4.0.2" | |
53 | + "typescript": "^4.0.5" | |
50 | 54 | } |
51 | 55 | } |
src/app/component/app.component.html
View file @
de59ffe
1 | 1 | <app-nav-bar></app-nav-bar> |
2 | -<app-list-vessel></app-list-vessel> | |
2 | + | |
3 | +<div style="width: auto; height: 94.7vh;"> | |
4 | + <as-split direction="horizontal" > | |
5 | + <as-split-area size="20"> | |
6 | + <app-list-vessel></app-list-vessel> | |
7 | + </as-split-area> | |
8 | + <as-split-area size="80"> | |
9 | + <as-split direction="vertical"> | |
10 | + <as-split-area size="100"> | |
11 | + map | |
12 | + </as-split-area> | |
13 | + <as-split-area size="100"> | |
14 | + Graph | |
15 | + </as-split-area> | |
16 | + </as-split> | |
17 | + </as-split-area> | |
18 | + </as-split> | |
19 | +</div> | |
3 | 20 | <router-outlet></router-outlet> |
src/app/component/app.component.scss
View file @
de59ffe
src/app/component/app.component.ts
View file @
de59ffe
1 | -import { Component } from '@angular/core'; | |
1 | +import {Component, OnInit} from '@angular/core'; | |
2 | +import * as Split from 'split.js'; | |
2 | 3 | |
4 | + | |
3 | 5 | @Component({ |
4 | 6 | selector: 'app-root', |
5 | 7 | templateUrl: './app.component.html', |
... | ... | @@ -7,5 +9,6 @@ |
7 | 9 | }) |
8 | 10 | export class AppComponent { |
9 | 11 | title = 'fdit-visualisation'; |
12 | + | |
10 | 13 | } |
src/app/component/app.module.ts
View file @
de59ffe
1 | -import { BrowserModule } from '@angular/platform-browser'; | |
2 | -import { NgModule } from '@angular/core'; | |
3 | -import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'; | |
1 | +import {BrowserModule} from '@angular/platform-browser'; | |
2 | +import {NgModule} from '@angular/core'; | |
3 | +import {allIcons, NgxBootstrapIconsModule} from 'ngx-bootstrap-icons'; | |
4 | 4 | |
5 | -import { AppRoutingModule } from './app-routing.module'; | |
6 | -import { AppComponent } from './app.component'; | |
7 | -import { NavBarComponent } from './nav-bar/nav-bar.component'; | |
8 | -import { MapComponent } from './map/map.component'; | |
9 | -import { GraphComponent } from './graph/graph.component'; | |
10 | -import { ProgressComponent } from './import-vessels/progress/progress.component'; | |
11 | -import { ImportVesselsComponent } from './import-vessels/import-vessels.component'; | |
12 | -import { ImportVesselsDirective } from './import-vessels/import-vessels.directive'; | |
13 | -import { ListVesselComponent } from './list-vessel/list-vessel.component'; | |
5 | +import {AppRoutingModule} from './app-routing.module'; | |
6 | +import {AppComponent} from './app.component'; | |
7 | +import {NavBarComponent} from './nav-bar/nav-bar.component'; | |
8 | +import {MapComponent} from './map/map.component'; | |
9 | +import {GraphComponent} from './graph/graph.component'; | |
10 | +import {ProgressComponent} from './import-vessels/progress/progress.component'; | |
11 | +import {ImportVesselsComponent} from './import-vessels/import-vessels.component'; | |
12 | +import {ImportVesselsDirective} from './import-vessels/import-vessels.directive'; | |
13 | +import {ListVesselComponent} from './list-vessel/list-vessel.component'; | |
14 | +import {AngularSplitModule} from 'angular-split'; | |
14 | 15 | |
15 | 16 | @NgModule({ |
16 | 17 | declarations: [ |
17 | 18 | |
... | ... | @@ -26,10 +27,12 @@ |
26 | 27 | imports: [ |
27 | 28 | BrowserModule, |
28 | 29 | AppRoutingModule, |
29 | - NgxBootstrapIconsModule.pick(allIcons) | |
30 | + NgxBootstrapIconsModule.pick(allIcons), | |
31 | + AngularSplitModule, | |
30 | 32 | ], |
31 | 33 | providers: [], |
32 | 34 | bootstrap: [AppComponent] |
33 | 35 | }) |
34 | -export class AppModule { } | |
36 | +export class AppModule { | |
37 | +} |
src/app/component/import-vessels/import-vessels.component.ts
View file @
de59ffe
1 | 1 | import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; |
2 | 2 | import {VesselsService} from '../../service/vessels.service'; |
3 | 3 | import {Message} from '../../model/message'; |
4 | +import {Vessel} from '../../model/vessel'; | |
5 | +import {Vessels} from '../../model/vessels'; | |
4 | 6 | |
5 | 7 | @Component({ |
6 | 8 | selector: 'app-import-vessels', |
7 | 9 | |
... | ... | @@ -8,9 +10,8 @@ |
8 | 10 | styleUrls: ['./import-vessels.component.scss'] |
9 | 11 | }) |
10 | 12 | export class ImportVesselsComponent implements OnInit { |
11 | - vessels: Map<number, Message>; | |
13 | + vessels: Vessels; | |
12 | 14 | |
13 | - | |
14 | 15 | constructor(private vesselsService: VesselsService) { |
15 | 16 | } |
16 | 17 | |
17 | 18 | |
18 | 19 | |
19 | 20 | |
... | ... | @@ -50,14 +51,18 @@ |
50 | 51 | uploadFilesSimulator(index: number): void { |
51 | 52 | const fileReader = new FileReader(); |
52 | 53 | let nbLine: number; |
53 | - | |
54 | 54 | fileReader.onload = (e) => { |
55 | + this.vessels = new Vessels(); | |
55 | 56 | const lines: string[] = (fileReader.result as string).split('\n'); |
56 | 57 | nbLine = lines.length; |
57 | - for (const line of lines) { | |
58 | + for (let line of lines) { | |
59 | + line = line.replace(/[^\x20-\x7F]/g, ''); | |
58 | 60 | const splitLine = line.split(','); |
59 | - const newVessel = new Message(splitLine); | |
60 | - this.vessels.set(Number(newVessel.mmsi), newVessel); | |
61 | + if (isNaN(Number(splitLine[0])) || line === '') { | |
62 | + continue; | |
63 | + } | |
64 | + const newMessage = new Message(splitLine); | |
65 | + this.vessels.addMessage(newMessage); | |
61 | 66 | } |
62 | 67 | this.vesselsService.changeVesselsSet(this.vessels); |
63 | 68 | }; |
src/app/component/list-vessel/list-vessel.component.html
View file @
de59ffe
1 | - | |
2 | 1 | <div class="list-group border" id="list-tab" role="tablist"> |
3 | 2 | <h2 class="side-title">Vessel</h2> |
4 | - <a *ngFor="let vessel of vessels | keyvalue" class=" list-group-item list-group-item-action" id="{{vessel.value.mmsi}}" | |
3 | + <label for="myInput"></label><input class="form-control" id="myInput" type="text" placeholder="Search.."> | |
4 | + <a *ngFor="let vessel of vessels.vessels.values()" class=" list-group-item list-group-item-action" | |
5 | + id="{{vessel.getMMSI()}}" | |
5 | 6 | data-toggle="list" role="tab"> |
6 | - {{vessel.value.mmsi}} - {{vessel.value.vesselName}} | |
7 | + {{vessel.getMMSI()}} - {{vessel.getName()}} | |
7 | 8 | </a> |
8 | 9 | </div> |
src/app/component/list-vessel/list-vessel.component.scss
View file @
de59ffe
src/app/component/list-vessel/list-vessel.component.ts
View file @
de59ffe
1 | 1 | import {Component, OnInit} from '@angular/core'; |
2 | -import {Message} from '../../model/message'; | |
3 | 2 | import {VesselsService} from '../../service/vessels.service'; |
3 | +import {Vessels} from '../../model/vessels'; | |
4 | +declare var $: any; | |
4 | 5 | |
5 | 6 | @Component({ |
6 | 7 | selector: 'app-list-vessel', |
... | ... | @@ -8,7 +9,7 @@ |
8 | 9 | styleUrls: ['./list-vessel.component.scss'] |
9 | 10 | }) |
10 | 11 | export class ListVesselComponent implements OnInit { |
11 | - vessels: Map<number, Message>; | |
12 | + vessels: Vessels; | |
12 | 13 | |
13 | 14 | |
14 | 15 | constructor(private vesselsService: VesselsService) { |
... | ... | @@ -17,7 +18,15 @@ |
17 | 18 | ngOnInit(): void { |
18 | 19 | this.vesselsService.currentVessels.subscribe(vessels => { |
19 | 20 | this.vessels = vessels; |
20 | - console.log(this.vessels); | |
21 | + }); | |
22 | + | |
23 | + $(document).ready(() => { | |
24 | + $('#myInput').on('keyup', function(): void { | |
25 | + const value = $(this).val().toLowerCase(); | |
26 | + $('#list-tab a').filter(function(): void { | |
27 | + $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1); | |
28 | + }); | |
29 | + }); | |
21 | 30 | }); |
22 | 31 | } |
23 | 32 | } |
src/app/model/message.spec.ts
View file @
de59ffe
src/app/model/vessel.spec.ts
View file @
de59ffe
1 | -import { Message } from './message'; | |
1 | +import { Vessel } from './vessel'; | |
2 | 2 | |
3 | 3 | describe('Vessel', () => { |
4 | - // it('should create an instance', () => { | |
5 | - // expect(new Vessel()).toBeTruthy(); | |
6 | - // }); | |
4 | + it('should create an instance', () => { | |
5 | + // expect(new Vessel()).toBeTruthy(); | |
6 | + }); | |
7 | 7 | }); |
src/app/model/vessel.ts
View file @
de59ffe
1 | +import {Message} from './message'; | |
2 | + | |
3 | +export class Vessel { | |
4 | + messages: Array<Message>; | |
5 | + | |
6 | + constructor(messages: Array<Message>) { | |
7 | + this.messages = messages; | |
8 | + } | |
9 | + | |
10 | + addMessage(message: Message): void { | |
11 | + this.messages.push(message); | |
12 | + } | |
13 | + | |
14 | + getMMSI(): string { | |
15 | + return this.messages[0].mmsi; | |
16 | + } | |
17 | + | |
18 | + getName(): string { | |
19 | + return this.messages[0].vesselName; | |
20 | + } | |
21 | + | |
22 | +} |
src/app/model/vessels.spec.ts
View file @
de59ffe
src/app/model/vessels.ts
View file @
de59ffe
1 | +import {Vessel} from './vessel'; | |
2 | +import {Message} from './message'; | |
3 | + | |
4 | +export class Vessels { | |
5 | + vessels: Map<number, Vessel>; | |
6 | + | |
7 | + constructor() { | |
8 | + this.vessels = new Map<number, Vessel>(); | |
9 | + } | |
10 | + | |
11 | + addMessage(message: Message): void { | |
12 | + if (!this.vessels.get(Number(message.mmsi))) { | |
13 | + this.vessels.set(Number(message.mmsi), new Vessel(new Array<Message>())); | |
14 | + } | |
15 | + | |
16 | + this.vessels.get(Number(message.mmsi)).addMessage(message); | |
17 | + } | |
18 | + | |
19 | +} |
src/app/service/vessels.service.ts
View file @
de59ffe
1 | 1 | import {Injectable} from '@angular/core'; |
2 | -import {BehaviorSubject, Observable} from 'rxjs'; | |
3 | -import {Message} from '../model/message'; | |
2 | +import {BehaviorSubject} from 'rxjs'; | |
3 | +import {Vessels} from '../model/vessels'; | |
4 | 4 | |
5 | 5 | @Injectable({ |
6 | 6 | providedIn: 'root' |
7 | 7 | }) |
8 | 8 | export class VesselsService { |
9 | - private vessels = new BehaviorSubject(new Map()); | |
9 | + private vessels = new BehaviorSubject(new Vessels()); | |
10 | 10 | currentVessels = this.vessels.asObservable(); |
11 | 11 | |
12 | 12 | constructor() { |
13 | 13 | } |
14 | 14 | |
15 | - changeVesselsSet(newVessels: Map<number, Message>): void { | |
15 | + changeVesselsSet(newVessels: Vessels): void { | |
16 | 16 | this.vessels.next(newVessels); |
17 | 17 | } |
18 | 18 | } |