Commit 632c4ac2ffc20e2b051533b741377e5cc2b35dca
1 parent
c666d6db69
Exists in
master
import vessels
Showing 53 changed files with 842 additions and 251 deletions Side-by-side Diff
- angular.json
- package-lock.json
- package.json
- src/app/app-routing.module.ts
- src/app/app.component.html
- src/app/app.component.spec.ts
- src/app/app.component.ts
- src/app/app.module.ts
- src/app/boat-list/boat-list.component.html
- src/app/boat-list/boat-list.component.spec.ts
- src/app/boat-list/boat-list.component.ts
- src/app/component/app-routing.module.ts
- src/app/component/app.component.html
- src/app/component/app.component.spec.ts
- src/app/component/app.component.ts
- src/app/component/app.module.ts
- src/app/component/graph/graph.component.spec.ts
- src/app/component/graph/graph.component.ts
- src/app/component/import-vessels/import-vessels.component.html
- src/app/component/import-vessels/import-vessels.component.scss
- src/app/component/import-vessels/import-vessels.component.spec.ts
- src/app/component/import-vessels/import-vessels.component.ts
- src/app/component/import-vessels/import-vessels.directive.spec.ts
- src/app/component/import-vessels/import-vessels.directive.ts
- src/app/component/import-vessels/progress/progress.component.html
- src/app/component/import-vessels/progress/progress.component.scss
- src/app/component/import-vessels/progress/progress.component.spec.ts
- src/app/component/import-vessels/progress/progress.component.ts
- src/app/component/list-vessel/list-vessel.component.spec.ts
- src/app/component/list-vessel/list-vessel.component.ts
- src/app/component/map/map.component.html
- src/app/component/map/map.component.spec.ts
- src/app/component/map/map.component.ts
- src/app/component/nav-bar/nav-bar.component.html
- src/app/component/nav-bar/nav-bar.component.spec.ts
- src/app/component/nav-bar/nav-bar.component.ts
- src/app/graph/graph.component.html
- src/app/graph/graph.component.spec.ts
- src/app/graph/graph.component.ts
- src/app/map/map.component.html
- src/app/map/map.component.spec.ts
- src/app/map/map.component.ts
- src/app/model/vessel.spec.ts
- src/app/model/vessel.ts
- src/app/nav-bar/nav-bar.component.html
- src/app/nav-bar/nav-bar.component.spec.ts
- src/app/nav-bar/nav-bar.component.ts
- src/app/service/vessels.service.spec.ts
- src/app/service/vessels.service.ts
- src/assets/ic-delete-file.svg
- src/assets/ic-file.svg
- src/assets/ic-upload-file.svg
- src/main.ts
angular.json
View file @
632c4ac
... | ... | @@ -31,7 +31,10 @@ |
31 | 31 | "node_modules/bootstrap/dist/css/bootstrap.css", |
32 | 32 | "src/styles.scss" |
33 | 33 | ], |
34 | - "scripts": [] | |
34 | + "scripts": [ | |
35 | + "node_modules/jquery/dist/jquery.min.js", | |
36 | + "node_modules/bootstrap/dist/js/bootstrap.min.js" | |
37 | + ] | |
35 | 38 | }, |
36 | 39 | "configurations": { |
37 | 40 | "production": { |
package-lock.json
View file @
632c4ac
... | ... | @@ -6674,6 +6674,11 @@ |
6674 | 6674 | } |
6675 | 6675 | } |
6676 | 6676 | }, |
6677 | + "jquery": { | |
6678 | + "version": "3.5.1", | |
6679 | + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", | |
6680 | + "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" | |
6681 | + }, | |
6677 | 6682 | "js-tokens": { |
6678 | 6683 | "version": "4.0.0", |
6679 | 6684 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", |
... | ... | @@ -7830,6 +7835,29 @@ |
7830 | 7835 | "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", |
7831 | 7836 | "dev": true |
7832 | 7837 | }, |
7838 | + "ngx-bootstrap-icons": { | |
7839 | + "version": "1.2.0", | |
7840 | + "resolved": "https://registry.npmjs.org/ngx-bootstrap-icons/-/ngx-bootstrap-icons-1.2.0.tgz", | |
7841 | + "integrity": "sha512-e6AT33wrhZfUEahZoZoVji2Nk2twj0GlPeusf6sW2Ebds9eeN3tBoSCE4kqLEZHS1B/6eOw8jDdOhKYhRPSgLw==", | |
7842 | + "requires": { | |
7843 | + "tslib": "^2.0.0" | |
7844 | + } | |
7845 | + }, | |
7846 | + "ngx-dropzone": { | |
7847 | + "version": "2.2.2", | |
7848 | + "resolved": "https://registry.npmjs.org/ngx-dropzone/-/ngx-dropzone-2.2.2.tgz", | |
7849 | + "integrity": "sha512-REuBcPNTY33OtcZD6dw8Fq/jFqwviiYydYaCn74yig8TvDDYhtJ/BPjtvbw7uEgF4BJr/UEHbKMvkdZIyCgsww==", | |
7850 | + "requires": { | |
7851 | + "tslib": "^1.9.0" | |
7852 | + }, | |
7853 | + "dependencies": { | |
7854 | + "tslib": { | |
7855 | + "version": "1.14.1", | |
7856 | + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | |
7857 | + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | |
7858 | + } | |
7859 | + } | |
7860 | + }, | |
7833 | 7861 | "nice-try": { |
7834 | 7862 | "version": "1.0.5", |
7835 | 7863 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", |
... | ... | @@ -8865,6 +8893,11 @@ |
8865 | 8893 | "requires": { |
8866 | 8894 | "ts-pnp": "^1.1.6" |
8867 | 8895 | } |
8896 | + }, | |
8897 | + "popper.js": { | |
8898 | + "version": "1.16.1", | |
8899 | + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", | |
8900 | + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" | |
8868 | 8901 | }, |
8869 | 8902 | "portfinder": { |
8870 | 8903 | "version": "1.0.28", |
package.json
View file @
632c4ac
... | ... | @@ -20,6 +20,10 @@ |
20 | 20 | "@angular/platform-browser-dynamic": "~10.2.0", |
21 | 21 | "@angular/router": "~10.2.0", |
22 | 22 | "bootstrap": "^4.5.3", |
23 | + "jquery": "^3.5.1", | |
24 | + "ngx-bootstrap-icons": "^1.2.0", | |
25 | + "ngx-dropzone": "^2.2.2", | |
26 | + "popper.js": "^1.16.1", | |
23 | 27 | "rxjs": "^6.6.3", |
24 | 28 | "tslib": "^2.0.0", |
25 | 29 | "zone.js": "~0.10.2" |
src/app/app-routing.module.ts
View file @
632c4ac
src/app/app.component.html
View file @
632c4ac
src/app/app.component.spec.ts
View file @
632c4ac
1 | -import { TestBed } from '@angular/core/testing'; | |
2 | -import { RouterTestingModule } from '@angular/router/testing'; | |
3 | -import { AppComponent } from './app.component'; | |
4 | - | |
5 | -describe('AppComponent', () => { | |
6 | - beforeEach(async () => { | |
7 | - await TestBed.configureTestingModule({ | |
8 | - imports: [ | |
9 | - RouterTestingModule | |
10 | - ], | |
11 | - declarations: [ | |
12 | - AppComponent | |
13 | - ], | |
14 | - }).compileComponents(); | |
15 | - }); | |
16 | - | |
17 | - it('should create the app', () => { | |
18 | - const fixture = TestBed.createComponent(AppComponent); | |
19 | - const app = fixture.componentInstance; | |
20 | - expect(app).toBeTruthy(); | |
21 | - }); | |
22 | - | |
23 | - it(`should have as title 'fdit-visualisation'`, () => { | |
24 | - const fixture = TestBed.createComponent(AppComponent); | |
25 | - const app = fixture.componentInstance; | |
26 | - expect(app.title).toEqual('fdit-visualisation'); | |
27 | - }); | |
28 | - | |
29 | - it('should render title', () => { | |
30 | - const fixture = TestBed.createComponent(AppComponent); | |
31 | - fixture.detectChanges(); | |
32 | - const compiled = fixture.nativeElement; | |
33 | - expect(compiled.querySelector('.content span').textContent).toContain('fdit-visualisation app is running!'); | |
34 | - }); | |
35 | -}); |
src/app/app.component.ts
View file @
632c4ac
src/app/app.module.ts
View file @
632c4ac
1 | -import { BrowserModule } from '@angular/platform-browser'; | |
2 | -import { NgModule } from '@angular/core'; | |
3 | - | |
4 | -import { AppRoutingModule } from './app-routing.module'; | |
5 | -import { AppComponent } from './app.component'; | |
6 | -import { NavBarComponent } from './nav-bar/nav-bar.component'; | |
7 | -import { BoatListComponent } from './boat-list/boat-list.component'; | |
8 | -import { MapComponent } from './map/map.component'; | |
9 | -import { GraphComponent } from './graph/graph.component'; | |
10 | - | |
11 | -@NgModule({ | |
12 | - declarations: [ | |
13 | - AppComponent, | |
14 | - NavBarComponent, | |
15 | - BoatListComponent, | |
16 | - MapComponent, | |
17 | - GraphComponent | |
18 | - ], | |
19 | - imports: [ | |
20 | - BrowserModule, | |
21 | - AppRoutingModule | |
22 | - ], | |
23 | - providers: [], | |
24 | - bootstrap: [AppComponent] | |
25 | -}) | |
26 | -export class AppModule { } |
src/app/boat-list/boat-list.component.html
View file @
632c4ac
1 | -<p>boat-list works!</p> |
src/app/boat-list/boat-list.component.spec.ts
View file @
632c4ac
1 | -import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | - | |
3 | -import { BoatListComponent } from './boat-list.component'; | |
4 | - | |
5 | -describe('BoatListComponent', () => { | |
6 | - let component: BoatListComponent; | |
7 | - let fixture: ComponentFixture<BoatListComponent>; | |
8 | - | |
9 | - beforeEach(async () => { | |
10 | - await TestBed.configureTestingModule({ | |
11 | - declarations: [ BoatListComponent ] | |
12 | - }) | |
13 | - .compileComponents(); | |
14 | - }); | |
15 | - | |
16 | - beforeEach(() => { | |
17 | - fixture = TestBed.createComponent(BoatListComponent); | |
18 | - component = fixture.componentInstance; | |
19 | - fixture.detectChanges(); | |
20 | - }); | |
21 | - | |
22 | - it('should create', () => { | |
23 | - expect(component).toBeTruthy(); | |
24 | - }); | |
25 | -}); |
src/app/boat-list/boat-list.component.ts
View file @
632c4ac
1 | -import { Component, OnInit } from '@angular/core'; | |
2 | - | |
3 | -@Component({ | |
4 | - selector: 'app-boat-list', | |
5 | - templateUrl: './boat-list.component.html', | |
6 | - styleUrls: ['./boat-list.component.scss'] | |
7 | -}) | |
8 | -export class BoatListComponent implements OnInit { | |
9 | - | |
10 | - constructor() { } | |
11 | - | |
12 | - ngOnInit(): void { | |
13 | - } | |
14 | - | |
15 | -} |
src/app/component/app-routing.module.ts
View file @
632c4ac
src/app/component/app.component.html
View file @
632c4ac
src/app/component/app.component.spec.ts
View file @
632c4ac
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | +import { RouterTestingModule } from '@angular/router/testing'; | |
3 | +import { AppComponent } from './app.component'; | |
4 | + | |
5 | +describe('AppComponent', () => { | |
6 | + beforeEach(async () => { | |
7 | + await TestBed.configureTestingModule({ | |
8 | + imports: [ | |
9 | + RouterTestingModule | |
10 | + ], | |
11 | + declarations: [ | |
12 | + AppComponent | |
13 | + ], | |
14 | + }).compileComponents(); | |
15 | + }); | |
16 | + | |
17 | + it('should create the app', () => { | |
18 | + const fixture = TestBed.createComponent(AppComponent); | |
19 | + const app = fixture.componentInstance; | |
20 | + expect(app).toBeTruthy(); | |
21 | + }); | |
22 | + | |
23 | + it(`should have as title 'fdit-visualisation'`, () => { | |
24 | + const fixture = TestBed.createComponent(AppComponent); | |
25 | + const app = fixture.componentInstance; | |
26 | + expect(app.title).toEqual('fdit-visualisation'); | |
27 | + }); | |
28 | + | |
29 | + it('should render title', () => { | |
30 | + const fixture = TestBed.createComponent(AppComponent); | |
31 | + fixture.detectChanges(); | |
32 | + const compiled = fixture.nativeElement; | |
33 | + expect(compiled.querySelector('.content span').textContent).toContain('fdit-visualisation app is running!'); | |
34 | + }); | |
35 | +}); |
src/app/component/app.component.ts
View file @
632c4ac
src/app/component/app.module.ts
View file @
632c4ac
1 | +import { BrowserModule } from '@angular/platform-browser'; | |
2 | +import { NgModule } from '@angular/core'; | |
3 | +import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'; | |
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'; | |
14 | + | |
15 | +@NgModule({ | |
16 | + declarations: [ | |
17 | + AppComponent, | |
18 | + NavBarComponent, | |
19 | + MapComponent, | |
20 | + GraphComponent, | |
21 | + ProgressComponent, | |
22 | + ImportVesselsComponent, | |
23 | + ImportVesselsDirective, | |
24 | + ListVesselComponent | |
25 | + ], | |
26 | + imports: [ | |
27 | + BrowserModule, | |
28 | + AppRoutingModule, | |
29 | + NgxBootstrapIconsModule.pick(allIcons) | |
30 | + ], | |
31 | + providers: [], | |
32 | + bootstrap: [AppComponent] | |
33 | +}) | |
34 | +export class AppModule { } |
src/app/component/graph/graph.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { GraphComponent } from './graph.component'; | |
4 | + | |
5 | +describe('GraphComponent', () => { | |
6 | + let component: GraphComponent; | |
7 | + let fixture: ComponentFixture<GraphComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ GraphComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(GraphComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/graph/graph.component.ts
View file @
632c4ac
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | + | |
3 | +@Component({ | |
4 | + selector: 'app-graph', | |
5 | + templateUrl: './graph.component.html', | |
6 | + styleUrls: ['./graph.component.scss'] | |
7 | +}) | |
8 | +export class GraphComponent implements OnInit { | |
9 | + | |
10 | + constructor() { } | |
11 | + | |
12 | + ngOnInit(): void { | |
13 | + } | |
14 | + | |
15 | +} |
src/app/component/import-vessels/import-vessels.component.html
View file @
632c4ac
1 | +<div class="container" appImportVessels (fileDropped)="onFileDropped($event)"> | |
2 | + <input type="file" #fileDropRef id="fileDropRef" multiple (change)="fileBrowseHandler($event.target.files)" /> | |
3 | + <img src="../../../assets/ic-upload-file.svg" alt=""> | |
4 | + <h3>Drag and drop file here</h3> | |
5 | + <h3>or</h3> | |
6 | + <label for="fileDropRef">Browse for file</label> | |
7 | +</div> | |
8 | +<div class="files-list"> | |
9 | + <div class="single-file" *ngFor="let file of files; let i = index"> | |
10 | + <img src="../../../assets/ic-file.svg" width="45px" alt="file"> | |
11 | + <div class="info"> | |
12 | + <h4 class="name"> | |
13 | + {{ file?.name }} | |
14 | + </h4> | |
15 | + <p class="size"> | |
16 | + {{ formatBytes(file?.size) }} | |
17 | + </p> | |
18 | + <app-progress [progress]="file?.progress"></app-progress> | |
19 | + </div> | |
20 | + <img src="../../../assets/ic-delete-file.svg" class="delete" width="20px" alt="file" (click)="deleteFile(i)"> | |
21 | + </div> | |
22 | +</div> |
src/app/component/import-vessels/import-vessels.component.scss
View file @
632c4ac
1 | + | |
2 | +.container { | |
3 | + width: 450px; | |
4 | + height: 200px; | |
5 | + padding: 2rem; | |
6 | + text-align: center; | |
7 | + //border: dashed 1px #979797; | |
8 | + position: relative; | |
9 | + margin: 0 auto; | |
10 | + | |
11 | + input { | |
12 | + opacity: 0; | |
13 | + position: absolute; | |
14 | + z-index: 2; | |
15 | + width: 100%; | |
16 | + height: 100%; | |
17 | + top: 0; | |
18 | + left: 0; | |
19 | + } | |
20 | + | |
21 | + label { | |
22 | + color: white; | |
23 | + width: 183px; | |
24 | + height: 44px; | |
25 | + border-radius: 21.5px; | |
26 | + background-color: #db202f; | |
27 | + padding: 8px 16px; | |
28 | + } | |
29 | + | |
30 | + h3 { | |
31 | + font-size: 20px; | |
32 | + font-weight: 600; | |
33 | + color: #38424c; | |
34 | + } | |
35 | +} | |
36 | + | |
37 | +.fileover { | |
38 | + animation: shake 1s; | |
39 | + animation-iteration-count: infinite; | |
40 | +} | |
41 | + | |
42 | +.files-list { | |
43 | + margin-top: 1.5rem; | |
44 | + | |
45 | + .single-file { | |
46 | + display: flex; | |
47 | + padding: 0.5rem; | |
48 | + justify-content: space-between; | |
49 | + align-items: center; | |
50 | + border: dashed 1px #979797; | |
51 | + margin-bottom: 1rem; | |
52 | + | |
53 | + img.delete { | |
54 | + margin-left: 0.5rem; | |
55 | + cursor: pointer; | |
56 | + align-self: flex-end; | |
57 | + } | |
58 | + | |
59 | + flex-grow: 1; | |
60 | + | |
61 | + .name { | |
62 | + font-size: 14px; | |
63 | + font-weight: 500; | |
64 | + color: #353f4a; | |
65 | + margin: 0; | |
66 | + } | |
67 | + | |
68 | + .size { | |
69 | + font-size: 12px; | |
70 | + font-weight: 500; | |
71 | + color: #a4a4a4; | |
72 | + margin: 0 0 0.25rem; | |
73 | + } | |
74 | + | |
75 | + .info { | |
76 | + width: 100% | |
77 | + } | |
78 | + } | |
79 | +} | |
80 | + | |
81 | +/* Shake animation */ | |
82 | +@keyframes shake { | |
83 | + 0% { | |
84 | + transform: translate(1px, 1px) rotate(0deg); | |
85 | + } | |
86 | + | |
87 | + 10% { | |
88 | + transform: translate(-1px, -2px) rotate(-1deg); | |
89 | + } | |
90 | + | |
91 | + 20% { | |
92 | + transform: translate(-3px, 0px) rotate(1deg); | |
93 | + } | |
94 | + | |
95 | + 30% { | |
96 | + transform: translate(3px, 2px) rotate(0deg); | |
97 | + } | |
98 | + | |
99 | + 40% { | |
100 | + transform: translate(1px, -1px) rotate(1deg); | |
101 | + } | |
102 | + | |
103 | + 50% { | |
104 | + transform: translate(-1px, 2px) rotate(-1deg); | |
105 | + } | |
106 | + | |
107 | + 60% { | |
108 | + transform: translate(-3px, 1px) rotate(0deg); | |
109 | + } | |
110 | + | |
111 | + 70% { | |
112 | + transform: translate(3px, 1px) rotate(-1deg); | |
113 | + } | |
114 | + | |
115 | + 80% { | |
116 | + transform: translate(-1px, -1px) rotate(1deg); | |
117 | + } | |
118 | + | |
119 | + 90% { | |
120 | + transform: translate(1px, 2px) rotate(0deg); | |
121 | + } | |
122 | + | |
123 | + 100% { | |
124 | + transform: translate(1px, -2px) rotate(-1deg); | |
125 | + } | |
126 | +} |
src/app/component/import-vessels/import-vessels.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ImportVesselsComponent } from './import-vessels.component'; | |
4 | + | |
5 | +describe('ImportVesselsComponent', () => { | |
6 | + let component: ImportVesselsComponent; | |
7 | + let fixture: ComponentFixture<ImportVesselsComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ ImportVesselsComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(ImportVesselsComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/import-vessels/import-vessels.component.ts
View file @
632c4ac
1 | +import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; | |
2 | +import {VesselsService} from '../../service/vessels.service'; | |
3 | +import {Vessel} from '../../model/vessel'; | |
4 | + | |
5 | +@Component({ | |
6 | + selector: 'app-import-vessels', | |
7 | + templateUrl: './import-vessels.component.html', | |
8 | + styleUrls: ['./import-vessels.component.scss'] | |
9 | +}) | |
10 | +export class ImportVesselsComponent implements OnInit { | |
11 | + vessels: Map<number, Vessel>; | |
12 | + | |
13 | + | |
14 | + constructor(private vesselsService: VesselsService) { | |
15 | + } | |
16 | + | |
17 | + @ViewChild('fileDropRef', {static: false}) fileDropEl: ElementRef; | |
18 | + files: any[] = []; | |
19 | + | |
20 | + ngOnInit(): void { | |
21 | + this.vesselsService.currentVessels.subscribe(vessels => this.vessels = vessels); | |
22 | + } | |
23 | + | |
24 | + /** | |
25 | + * on file drop handler | |
26 | + */ | |
27 | + onFileDropped($event): void { | |
28 | + this.prepareFilesList($event); | |
29 | + } | |
30 | + | |
31 | + /** | |
32 | + * handle file from browsing | |
33 | + */ | |
34 | + fileBrowseHandler(files): void { | |
35 | + this.prepareFilesList(files); | |
36 | + } | |
37 | + | |
38 | + /** | |
39 | + * Delete file from files list | |
40 | + * @param index (File index) | |
41 | + */ | |
42 | + deleteFile(index: number): void { | |
43 | + if (this.files[index].progress < 100) { | |
44 | + return; | |
45 | + } | |
46 | + this.files.splice(index, 1); | |
47 | + } | |
48 | + | |
49 | + | |
50 | + uploadFilesSimulator(index: number): void { | |
51 | + const fileReader = new FileReader(); | |
52 | + let nbLine: number; | |
53 | + | |
54 | + fileReader.onload = (e) => { | |
55 | + const lines: string[] = (fileReader.result as string).split('\n'); | |
56 | + nbLine = lines.length; | |
57 | + for (const line of lines) { | |
58 | + const splitLine = line.split(','); | |
59 | + const newVessel = new Vessel(splitLine); | |
60 | + this.vessels.set(Number(newVessel.mmsi), newVessel); | |
61 | + } | |
62 | + }; | |
63 | + | |
64 | + fileReader.onprogress = (e ) => { | |
65 | + if (e.lengthComputable) { | |
66 | + this.files[index].progress = Math.round(((e.loaded / e.total) * 100)); | |
67 | + } | |
68 | + }; | |
69 | + | |
70 | + fileReader.readAsText(this.files[index]); | |
71 | + } | |
72 | + | |
73 | + prepareFilesList(files: Array<any>): void { | |
74 | + for (const item of files) { | |
75 | + item.progress = 0; | |
76 | + this.files.push(item); | |
77 | + } | |
78 | + this.fileDropEl.nativeElement.value = ''; | |
79 | + this.uploadFilesSimulator(0); | |
80 | + } | |
81 | + | |
82 | + formatBytes(bytes, decimals = 2): string { | |
83 | + if (bytes === 0) { | |
84 | + return '0 Bytes'; | |
85 | + } | |
86 | + const k = 1024; | |
87 | + const dm = decimals <= 0 ? 0 : decimals; | |
88 | + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; | |
89 | + const i = Math.floor(Math.log(bytes) / Math.log(k)); | |
90 | + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; | |
91 | + } | |
92 | +} |
src/app/component/import-vessels/import-vessels.directive.spec.ts
View file @
632c4ac
src/app/component/import-vessels/import-vessels.directive.ts
View file @
632c4ac
1 | +import {Directive, EventEmitter, HostBinding, HostListener, Output} from '@angular/core'; | |
2 | + | |
3 | +@Directive({ | |
4 | + selector: '[appImportVessels]' | |
5 | +}) | |
6 | +export class ImportVesselsDirective { | |
7 | + | |
8 | + @HostBinding('class.fileover') fileOver: boolean; | |
9 | + @Output() fileDropped = new EventEmitter<any>(); | |
10 | + | |
11 | + @HostListener('dragover', ['$event']) | |
12 | + onDragOver(evt): void { | |
13 | + evt.preventDefault(); | |
14 | + evt.stopPropagation(); | |
15 | + this.fileOver = true; | |
16 | + } | |
17 | + | |
18 | + @HostListener('dragleave', ['$event']) | |
19 | + public onDragLeave(evt): void { | |
20 | + evt.preventDefault(); | |
21 | + evt.stopPropagation(); | |
22 | + this.fileOver = false; | |
23 | + } | |
24 | + | |
25 | + @HostListener('drop', ['$event']) | |
26 | + public ondrop(evt): void { | |
27 | + evt.preventDefault(); | |
28 | + evt.stopPropagation(); | |
29 | + this.fileOver = false; | |
30 | + const files = evt.dataTransfer.files; | |
31 | + if (files.length > 0) { | |
32 | + this.fileDropped.emit(files); | |
33 | + } | |
34 | + } | |
35 | +} |
src/app/component/import-vessels/progress/progress.component.html
View file @
632c4ac
src/app/component/import-vessels/progress/progress.component.scss
View file @
632c4ac
1 | +.progress-cont { | |
2 | + height: 7px; | |
3 | + width: 100%; | |
4 | + border-radius: 4px; | |
5 | + background-color: #d0d0d0; | |
6 | + position: relative; | |
7 | + | |
8 | + .progress { | |
9 | + width: 0; | |
10 | + height: 100%; | |
11 | + position: absolute; | |
12 | + z-index: 1; | |
13 | + top: 0; | |
14 | + left: 0; | |
15 | + border-radius: 4px; | |
16 | + background-color: #4c97cb; | |
17 | + transition: 0.5s all; | |
18 | + } | |
19 | +} |
src/app/component/import-vessels/progress/progress.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ProgressComponent } from './progress.component'; | |
4 | + | |
5 | +describe('ProgressComponent', () => { | |
6 | + let component: ProgressComponent; | |
7 | + let fixture: ComponentFixture<ProgressComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ ProgressComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(ProgressComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/import-vessels/progress/progress.component.ts
View file @
632c4ac
1 | +import {Component, Input, OnInit} from '@angular/core'; | |
2 | + | |
3 | +@Component({ | |
4 | + selector: 'app-progress', | |
5 | + templateUrl: './progress.component.html', | |
6 | + styleUrls: ['./progress.component.scss'] | |
7 | +}) | |
8 | +export class ProgressComponent implements OnInit { | |
9 | + @Input() progress = 0; | |
10 | + constructor() { } | |
11 | + | |
12 | + ngOnInit(): void { | |
13 | + } | |
14 | + | |
15 | +} |
src/app/component/list-vessel/list-vessel.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { ListVesselComponent } from './list-vessel.component'; | |
4 | + | |
5 | +describe('ListVesselComponent', () => { | |
6 | + let component: ListVesselComponent; | |
7 | + let fixture: ComponentFixture<ListVesselComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ ListVesselComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(ListVesselComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/list-vessel/list-vessel.component.ts
View file @
632c4ac
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | + | |
3 | +@Component({ | |
4 | + selector: 'app-list-vessel', | |
5 | + templateUrl: './list-vessel.component.html', | |
6 | + styleUrls: ['./list-vessel.component.scss'] | |
7 | +}) | |
8 | +export class ListVesselComponent implements OnInit { | |
9 | + | |
10 | + constructor() { } | |
11 | + | |
12 | + ngOnInit(): void { | |
13 | + } | |
14 | + | |
15 | +} |
src/app/component/map/map.component.html
View file @
632c4ac
1 | +<p>map works!</p> |
src/app/component/map/map.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { MapComponent } from './map.component'; | |
4 | + | |
5 | +describe('MapComponent', () => { | |
6 | + let component: MapComponent; | |
7 | + let fixture: ComponentFixture<MapComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ MapComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(MapComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/map/map.component.ts
View file @
632c4ac
1 | +import { Component, OnInit } from '@angular/core'; | |
2 | + | |
3 | +@Component({ | |
4 | + selector: 'app-map', | |
5 | + templateUrl: './map.component.html', | |
6 | + styleUrls: ['./map.component.scss'] | |
7 | +}) | |
8 | +export class MapComponent implements OnInit { | |
9 | + | |
10 | + constructor() { } | |
11 | + | |
12 | + ngOnInit(): void { | |
13 | + } | |
14 | + | |
15 | +} |
src/app/component/nav-bar/nav-bar.component.html
View file @
632c4ac
1 | +<nav class="navbar navbar-expand-lg navbar-light bg-light"> | |
2 | + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation"> | |
3 | + <span class="navbar-toggler-icon"></span> | |
4 | + </button> | |
5 | + <div class="collapse navbar-collapse" id="navbarNavDropdown"> | |
6 | + <ul class="navbar-nav"> | |
7 | + | |
8 | + <li class="nav-item"> | |
9 | + <a class="nav-link" data-toggle="modal" data-target="#exampleModal" >Import</a> | |
10 | + </li> | |
11 | + | |
12 | + <li class="nav-item dropdown"> | |
13 | + <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
14 | + Dropdown menu | |
15 | + </a> | |
16 | + <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink"> | |
17 | + <a class="dropdown-item" href="#">Action</a> | |
18 | + <a class="dropdown-item" href="#">Another action</a> | |
19 | + <a class="dropdown-item" href="#">Something else here</a> | |
20 | + </div> | |
21 | + </li> | |
22 | + </ul> | |
23 | + </div> | |
24 | +</nav> | |
25 | + | |
26 | +<!-- Modal --> | |
27 | +<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> | |
28 | + <div class="modal-dialog" role="document"> | |
29 | + <div class="modal-content"> | |
30 | + <div class="modal-header"> | |
31 | + <h5 class="modal-title" id="exampleModalLabel">Import Vessels</h5> | |
32 | + <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | |
33 | + <span aria-hidden="true">×</span> | |
34 | + </button> | |
35 | + </div> | |
36 | + <div class="modal-body"> | |
37 | + <app-import-vessels></app-import-vessels> | |
38 | + </div> | |
39 | + <div class="modal-footer"> | |
40 | + <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> | |
41 | + </div> | |
42 | + </div> | |
43 | + </div> | |
44 | +</div> |
src/app/component/nav-bar/nav-bar.component.spec.ts
View file @
632c4ac
1 | +import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { NavBarComponent } from './nav-bar.component'; | |
4 | + | |
5 | +describe('NavBarComponent', () => { | |
6 | + let component: NavBarComponent; | |
7 | + let fixture: ComponentFixture<NavBarComponent>; | |
8 | + | |
9 | + beforeEach(async () => { | |
10 | + await TestBed.configureTestingModule({ | |
11 | + declarations: [ NavBarComponent ] | |
12 | + }) | |
13 | + .compileComponents(); | |
14 | + }); | |
15 | + | |
16 | + beforeEach(() => { | |
17 | + fixture = TestBed.createComponent(NavBarComponent); | |
18 | + component = fixture.componentInstance; | |
19 | + fixture.detectChanges(); | |
20 | + }); | |
21 | + | |
22 | + it('should create', () => { | |
23 | + expect(component).toBeTruthy(); | |
24 | + }); | |
25 | +}); |
src/app/component/nav-bar/nav-bar.component.ts
View file @
632c4ac
1 | +import {Component, OnInit} from '@angular/core'; | |
2 | + | |
3 | +@Component({ | |
4 | + selector: 'app-nav-bar', | |
5 | + templateUrl: './nav-bar.component.html', | |
6 | + styleUrls: ['./nav-bar.component.scss'] | |
7 | +}) | |
8 | +export class NavBarComponent implements OnInit { | |
9 | + | |
10 | + constructor() { } | |
11 | + | |
12 | + ngOnInit(): void { | |
13 | + } | |
14 | + | |
15 | +} |
src/app/graph/graph.component.html
View file @
632c4ac
1 | -<p>graph works!</p> |
src/app/graph/graph.component.spec.ts
View file @
632c4ac
1 | -import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | - | |
3 | -import { GraphComponent } from './graph.component'; | |
4 | - | |
5 | -describe('GraphComponent', () => { | |
6 | - let component: GraphComponent; | |
7 | - let fixture: ComponentFixture<GraphComponent>; | |
8 | - | |
9 | - beforeEach(async () => { | |
10 | - await TestBed.configureTestingModule({ | |
11 | - declarations: [ GraphComponent ] | |
12 | - }) | |
13 | - .compileComponents(); | |
14 | - }); | |
15 | - | |
16 | - beforeEach(() => { | |
17 | - fixture = TestBed.createComponent(GraphComponent); | |
18 | - component = fixture.componentInstance; | |
19 | - fixture.detectChanges(); | |
20 | - }); | |
21 | - | |
22 | - it('should create', () => { | |
23 | - expect(component).toBeTruthy(); | |
24 | - }); | |
25 | -}); |
src/app/graph/graph.component.ts
View file @
632c4ac
1 | -import { Component, OnInit } from '@angular/core'; | |
2 | - | |
3 | -@Component({ | |
4 | - selector: 'app-graph', | |
5 | - templateUrl: './graph.component.html', | |
6 | - styleUrls: ['./graph.component.scss'] | |
7 | -}) | |
8 | -export class GraphComponent implements OnInit { | |
9 | - | |
10 | - constructor() { } | |
11 | - | |
12 | - ngOnInit(): void { | |
13 | - } | |
14 | - | |
15 | -} |
src/app/map/map.component.html
View file @
632c4ac
1 | -<p>map works!</p> |
src/app/map/map.component.spec.ts
View file @
632c4ac
1 | -import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | - | |
3 | -import { MapComponent } from './map.component'; | |
4 | - | |
5 | -describe('MapComponent', () => { | |
6 | - let component: MapComponent; | |
7 | - let fixture: ComponentFixture<MapComponent>; | |
8 | - | |
9 | - beforeEach(async () => { | |
10 | - await TestBed.configureTestingModule({ | |
11 | - declarations: [ MapComponent ] | |
12 | - }) | |
13 | - .compileComponents(); | |
14 | - }); | |
15 | - | |
16 | - beforeEach(() => { | |
17 | - fixture = TestBed.createComponent(MapComponent); | |
18 | - component = fixture.componentInstance; | |
19 | - fixture.detectChanges(); | |
20 | - }); | |
21 | - | |
22 | - it('should create', () => { | |
23 | - expect(component).toBeTruthy(); | |
24 | - }); | |
25 | -}); |
src/app/map/map.component.ts
View file @
632c4ac
1 | -import { Component, OnInit } from '@angular/core'; | |
2 | - | |
3 | -@Component({ | |
4 | - selector: 'app-map', | |
5 | - templateUrl: './map.component.html', | |
6 | - styleUrls: ['./map.component.scss'] | |
7 | -}) | |
8 | -export class MapComponent implements OnInit { | |
9 | - | |
10 | - constructor() { } | |
11 | - | |
12 | - ngOnInit(): void { | |
13 | - } | |
14 | - | |
15 | -} |
src/app/model/vessel.spec.ts
View file @
632c4ac
src/app/model/vessel.ts
View file @
632c4ac
1 | +export class Vessel { | |
2 | + mmsi: string; | |
3 | + time: string; | |
4 | + latitude: string; | |
5 | + longitude: string; | |
6 | + speedOverGround: string; | |
7 | + courseOverGround: string; | |
8 | + heading: string; | |
9 | + vesselName: string; | |
10 | + imo: string; | |
11 | + callSign: string; | |
12 | + vesselType: string; | |
13 | + status: string; | |
14 | + length: string; | |
15 | + width: string; | |
16 | + draft: string; | |
17 | + cargo: string; | |
18 | + | |
19 | + | |
20 | + constructor(splitLine: string[]) { | |
21 | + this.mmsi = splitLine[0]; | |
22 | + this.time = splitLine[1]; | |
23 | + this.latitude = splitLine[2]; | |
24 | + this.longitude = splitLine[3]; | |
25 | + this.speedOverGround = splitLine[4]; | |
26 | + this.courseOverGround = splitLine[5]; | |
27 | + this.heading = splitLine[6]; | |
28 | + this.vesselName = splitLine[7]; | |
29 | + this.imo = splitLine[8]; | |
30 | + this.callSign = splitLine[9]; | |
31 | + this.vesselType = splitLine[10]; | |
32 | + this.status = splitLine[11]; | |
33 | + this.length = splitLine[12]; | |
34 | + this.width = splitLine[13]; | |
35 | + this.draft = splitLine[14]; | |
36 | + this.cargo = splitLine[15]; | |
37 | + } | |
38 | +} |
src/app/nav-bar/nav-bar.component.html
View file @
632c4ac
1 | -<p>nav-bar works!</p> |
src/app/nav-bar/nav-bar.component.spec.ts
View file @
632c4ac
1 | -import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
2 | - | |
3 | -import { NavBarComponent } from './nav-bar.component'; | |
4 | - | |
5 | -describe('NavBarComponent', () => { | |
6 | - let component: NavBarComponent; | |
7 | - let fixture: ComponentFixture<NavBarComponent>; | |
8 | - | |
9 | - beforeEach(async () => { | |
10 | - await TestBed.configureTestingModule({ | |
11 | - declarations: [ NavBarComponent ] | |
12 | - }) | |
13 | - .compileComponents(); | |
14 | - }); | |
15 | - | |
16 | - beforeEach(() => { | |
17 | - fixture = TestBed.createComponent(NavBarComponent); | |
18 | - component = fixture.componentInstance; | |
19 | - fixture.detectChanges(); | |
20 | - }); | |
21 | - | |
22 | - it('should create', () => { | |
23 | - expect(component).toBeTruthy(); | |
24 | - }); | |
25 | -}); |
src/app/nav-bar/nav-bar.component.ts
View file @
632c4ac
1 | -import { Component, OnInit } from '@angular/core'; | |
2 | - | |
3 | -@Component({ | |
4 | - selector: 'app-nav-bar', | |
5 | - templateUrl: './nav-bar.component.html', | |
6 | - styleUrls: ['./nav-bar.component.scss'] | |
7 | -}) | |
8 | -export class NavBarComponent implements OnInit { | |
9 | - | |
10 | - constructor() { } | |
11 | - | |
12 | - ngOnInit(): void { | |
13 | - } | |
14 | - | |
15 | -} |
src/app/service/vessels.service.spec.ts
View file @
632c4ac
1 | +import { TestBed } from '@angular/core/testing'; | |
2 | + | |
3 | +import { VesselsService } from './vessels.service'; | |
4 | + | |
5 | +describe('VesselsService', () => { | |
6 | + let service: VesselsService; | |
7 | + | |
8 | + beforeEach(() => { | |
9 | + TestBed.configureTestingModule({}); | |
10 | + service = TestBed.inject(VesselsService); | |
11 | + }); | |
12 | + | |
13 | + it('should be created', () => { | |
14 | + expect(service).toBeTruthy(); | |
15 | + }); | |
16 | +}); |
src/app/service/vessels.service.ts
View file @
632c4ac
1 | +import {Injectable} from '@angular/core'; | |
2 | +import {BehaviorSubject, Observable} from 'rxjs'; | |
3 | +import {Vessel} from '../model/vessel'; | |
4 | + | |
5 | +@Injectable({ | |
6 | + providedIn: 'root' | |
7 | +}) | |
8 | +export class VesselsService { | |
9 | + private vessels = new BehaviorSubject(new Map()); | |
10 | + currentVessels = this.vessels.asObservable(); | |
11 | + | |
12 | + constructor() { | |
13 | + } | |
14 | + | |
15 | + changeVesselsSet(newVessels: Map<number, Vessel>): void { | |
16 | + this.vessels.next(newVessels); | |
17 | + } | |
18 | +} |
src/assets/ic-delete-file.svg
View file @
632c4ac
1 | +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="18" viewBox="0 0 14 18"> | |
2 | + <path fill="#B1B1B1" fill-rule="nonzero" d="M1 16c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2H3c-1.1 0-2 .9-2 2v10zm3.17-7.83a.996.996 0 0 1 1.41 0L7 9.59l1.42-1.42a.996.996 0 1 1 1.41 1.41L8.41 11l1.42 1.42a.996.996 0 1 1-1.41 1.41L7 12.41l-1.42 1.42a.996.996 0 1 1-1.41-1.41L5.59 11 4.17 9.58a.996.996 0 0 1 0-1.41zM10.5 1L9.79.29C9.61.11 9.35 0 9.09 0H4.91c-.26 0-.52.11-.7.29L3.5 1H1c-.55 0-1 .45-1 1s.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1h-2.5z"/> | |
3 | +</svg> |
src/assets/ic-file.svg
View file @
632c4ac
1 | +<?xml version="1.0" encoding="windows-1252"?> | |
2 | +<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> | |
3 | +<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve"> | |
4 | +<polygon style="fill:#EDEADA;" points="51.5,14 37.5,0 6.5,0 6.5,58 51.5,58 "/> | |
5 | +<g> | |
6 | + <path style="fill:#CEC9AE;" d="M16.5,23h25c0.552,0,1-0.447,1-1s-0.448-1-1-1h-25c-0.552,0-1,0.447-1,1S15.948,23,16.5,23z"/> | |
7 | + <path style="fill:#CEC9AE;" d="M16.5,15h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S15.948,15,16.5,15z"/> | |
8 | + <path style="fill:#CEC9AE;" d="M41.5,29h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S42.052,29,41.5,29z"/> | |
9 | + <path style="fill:#CEC9AE;" d="M41.5,37h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S42.052,37,41.5,37z"/> | |
10 | + <path style="fill:#CEC9AE;" d="M41.5,45h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S42.052,45,41.5,45z"/> | |
11 | +</g> | |
12 | +<polygon style="fill:#CEC9AE;" points="37.5,0 37.5,14 51.5,14 "/> | |
13 | +<g> | |
14 | +</g> | |
15 | +<g> | |
16 | +</g> | |
17 | +<g> | |
18 | +</g> | |
19 | +<g> | |
20 | +</g> | |
21 | +<g> | |
22 | +</g> | |
23 | +<g> | |
24 | +</g> | |
25 | +<g> | |
26 | +</g> | |
27 | +<g> | |
28 | +</g> | |
29 | +<g> | |
30 | +</g> | |
31 | +<g> | |
32 | +</g> | |
33 | +<g> | |
34 | +</g> | |
35 | +<g> | |
36 | +</g> | |
37 | +<g> | |
38 | +</g> | |
39 | +<g> | |
40 | +</g> | |
41 | +<g> | |
42 | +</g> | |
43 | +</svg> |
src/assets/ic-upload-file.svg
View file @
632c4ac
1 | +<svg xmlns="http://www.w3.org/2000/svg" width="63" height="64" viewBox="0 0 63 64"> | |
2 | + <g fill="#3B454F" fill-rule="nonzero"> | |
3 | + <path d="M42.656 15.135a1.953 1.953 0 0 1-1.391-.578L31.5 4.795l-9.765 9.762a1.97 1.97 0 1 1-2.785-2.785L30.106.616a1.97 1.97 0 0 1 2.785 0l11.157 11.156a1.97 1.97 0 0 1-1.392 3.363z"/> | |
4 | + <path d="M31.5 36.791a1.97 1.97 0 0 1-1.969-1.969V2.01a1.97 1.97 0 0 1 3.938 0v32.812a1.97 1.97 0 0 1-1.969 1.969z"/> | |
5 | + <path d="M55.781 63.041H7.22A7.225 7.225 0 0 1 0 55.822V41.385a4.599 4.599 0 0 1 4.594-4.594h7.234a4.567 4.567 0 0 1 4.402 3.276l2.814 9.382a.658.658 0 0 0 .628.467h23.656a.658.658 0 0 0 .628-.467l2.814-9.385a4.572 4.572 0 0 1 4.402-3.273h7.234A4.599 4.599 0 0 1 63 41.385v14.437a7.225 7.225 0 0 1-7.219 7.219zM4.594 40.729a.656.656 0 0 0-.657.656v14.437a3.286 3.286 0 0 0 3.282 3.282H55.78a3.286 3.286 0 0 0 3.282-3.282V41.385a.656.656 0 0 0-.657-.656h-7.234a.65.65 0 0 0-.628.467L47.73 50.58a4.628 4.628 0 0 1-4.402 3.274H19.672a4.567 4.567 0 0 1-4.402-3.276l-2.814-9.382a.65.65 0 0 0-.628-.467H4.594z"/> | |
6 | + </g> | |
7 | +</svg> |
src/main.ts
View file @
632c4ac
1 | 1 | import { enableProdMode } from '@angular/core'; |
2 | 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; |
3 | 3 | |
4 | -import { AppModule } from './app/app.module'; | |
4 | +import { AppModule } from './app/component/app.module'; | |
5 | 5 | import { environment } from './environments/environment'; |
6 | 6 | |
7 | 7 | if (environment.production) { |