diff --git a/README.md b/README.md index b098ff9..28d58b3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # DeFinMa - UI -This is the Angular front end for the digital fingerprint of plastics web page hosted in the bic +This is the Angular front end for the DeFinMa web page hosted on the BIC at +[https://definma.apps.de1.bosch-iot-cloud.com](https://definma.apps.de1.bosch-iot-cloud.com). +A deep insight into the project structure can be gained in the +[Bachelor Thesis](https://definma.apps.de1.bosch-iot-cloud.com/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf). ## Bosch styled components @@ -8,7 +11,43 @@ Bosch styled Angular components were added following [this](https://connect.bosch.com/blogs/f6aacf06-98dd-440c-b3a7-0c5a4ad4c1bd/entry/Getting_started_a_Bosch_styled_Angular_Project?lang=de_de) guide, included using the `@inst-iot/bosch-angular-ui-components` package. -## Testing +## General structure -Unit and e2e tests are implemented and can be executed using `ng test` and `protractor ./e2e/protractor.conf.js` -respectively. +All components are displayed inside of the `app.component`, most of them directly as routes, see +[app-routing.module.ts](./src/app/app-routing.module.ts). For all routes except the `/documentation` the user has to be +logged in and has to have the right user level. Login is handled by the +[login.service](./src/app/services/login.service.ts), which also provides the `canActivate` function. + + +### Additional components + +The [error.component](./src/app/error) provides an error pop over. + +The [help.component](./src/app/help) provides the help information for all pages which can be accessed by the question +mark in the top right corner. + +The [img-magnifier](./src/app/img-magnifier) is used for displaying an image with a magnifying glass when hovering over +the image. + +[rb-custom-inputs](./src/app/rb-custom-inputs) provides Bosch styled components which were not included in the library. +These are an array input for displaying nested input elements for every array item, a button with icon and a table. + +The [models](./src/app/models) folder provides TS classes for database objects. + + +### Services + +The [api.service](./src/app/services/api.service.ts) provides API access with integrated authorization and error +handling. + +The [autocomplete.service](./src/app/services/autocomplete.service.ts) uses the _QuickScore_ module for sorting +autocomplete results. + +The [data.service](./src/app/services/data.service.ts) loads some resources needed in multiple Components. Take a look +at the `collectionMap` in line 19 for available resources. + +The [login.service](./src/app/services/login.service.ts) provides login and logout as well as information about the +current user. + +The [validation.service](./src/app/services/validation.service.ts) provides validation together with the +[validate.directive](./src/app/validate.directive.ts) for Angular Forms. diff --git a/angular.json b/angular.json index 5917785..e836054 100644 --- a/angular.json +++ b/angular.json @@ -65,9 +65,7 @@ "maximumWarning": "6kb", "maximumError": "10kb" } - ], - "serviceWorker": true, - "ngswConfigPath": "ngsw-config.json" + ] } } }, diff --git a/ngsw-config.json b/ngsw-config.json deleted file mode 100644 index 4ddf1a7..0000000 --- a/ngsw-config.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "./node_modules/@angular/service-worker/config/schema.json", - "index": "/index.html", - "assetGroups": [ - { - "name": "app", - "installMode": "prefetch", - "resources": { - "files": [ - "/favicon.ico", - "/index.html", - "/manifest.webmanifest", - "/*.css", - "/*.js" - ] - } - }, { - "name": "assets", - "installMode": "lazy", - "updateMode": "prefetch", - "resources": { - "files": [ - "/assets/**", - "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)" - ] - } - } - ] -} diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9883522..bdd4e17 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -9,9 +9,10 @@ import {TemplatesComponent} from './templates/templates.component'; import {SettingsComponent} from './settings/settings.component'; import {UsersComponent} from './users/users.component'; import {ChangelogComponent} from './changelog/changelog.component'; -import {DocumentationDatabaseComponent} from './documentation-database/documentation-database.component'; +import {DocumentationDatabaseComponent} from './documentation/documentation-database/documentation-database.component'; import {PredictionComponent} from './prediction/prediction.component'; import {ModelTemplatesComponent} from './model-templates/model-templates.component'; +import {DocumentationArchitectureComponent} from './documentation/documentation-architecture/documentation-architecture.component'; const routes: Routes = [ @@ -27,6 +28,7 @@ const routes: Routes = [ {path: 'users', component: UsersComponent, canActivate: [LoginService]}, {path: 'settings', component: SettingsComponent, canActivate: [LoginService]}, {path: 'documentation', component: DocumentationComponent}, + {path: 'documentation/architecture', component: DocumentationArchitectureComponent}, {path: 'documentation/database', component: DocumentationDatabaseComponent}, // if not authenticated diff --git a/src/app/app.component.html b/src/app/app.component.html index d026c27..fd3479b 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -15,6 +15,7 @@ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index c40f010..538305f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,6 @@ import {Component, isDevMode, OnInit} from '@angular/core'; import {LoginService} from './services/login.service'; -import {NavigationStart, Router} from '@angular/router'; +import {ActivatedRoute, NavigationStart, Router} from '@angular/router'; import {ModalService} from '@inst-iot/bosch-angular-ui-components'; import {HelpComponent} from './help/help.component'; import {DataService} from './services/data.service'; @@ -22,6 +22,7 @@ export class AppComponent implements OnInit{ constructor( public login: LoginService, public router: Router, + private route: ActivatedRoute, public window: Window, private modal: ModalService, public d: DataService @@ -36,7 +37,7 @@ export class AppComponent implements OnInit{ ngOnInit() { this.login.login().then(res => { - if (!res) { + if (!res && !(this.route.snapshot.url.length && this.route.snapshot.url[0].path === '/documentation')) { this.router.navigate(['/']); } }); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 48598f8..c4b92f8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -26,13 +26,12 @@ import { ParametersPipe } from './parameters.pipe'; import { SettingsComponent } from './settings/settings.component'; import { UsersComponent } from './users/users.component'; import { ChangelogComponent } from './changelog/changelog.component'; -import { DocumentationDatabaseComponent } from './documentation-database/documentation-database.component'; +import { DocumentationDatabaseComponent } from './documentation/documentation-database/documentation-database.component'; import { PredictionComponent } from './prediction/prediction.component'; -import { ServiceWorkerModule } from '@angular/service-worker'; -import { environment } from '../environments/environment'; import { HelpComponent } from './help/help.component'; import { ModelTemplatesComponent } from './model-templates/model-templates.component'; import { SizePipe } from './size.pipe'; +import { DocumentationArchitectureComponent } from './documentation/documentation-architecture/documentation-architecture.component'; @NgModule({ declarations: [ @@ -56,7 +55,8 @@ import { SizePipe } from './size.pipe'; PredictionComponent, HelpComponent, ModelTemplatesComponent, - SizePipe + SizePipe, + DocumentationArchitectureComponent ], imports: [ LocalStorageModule.forRoot({ @@ -73,8 +73,7 @@ import { SizePipe } from './size.pipe'; ReactiveFormsModule, FormFieldsModule, CommonModule, - ChartsModule, - ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }) + ChartsModule ], providers: [ ModalService, diff --git a/src/app/changelog/changelog.component.ts b/src/app/changelog/changelog.component.ts index 5efa4d0..06f3f61 100644 --- a/src/app/changelog/changelog.component.ts +++ b/src/app/changelog/changelog.component.ts @@ -26,7 +26,10 @@ export class ChangelogComponent implements OnInit { loadChangelog(page = 0) { this.api.get(`/changelog/${ - new Date(new Date(this.timestamp).getTime() - new Date(this.timestamp).getTimezoneOffset() * 60000).toISOString() + page > 0 ? this.changelog[0]._id : // use id if no new date was given + Math.floor(new Date( + new Date(this.timestamp).getTime() - new Date(this.timestamp).getTimezoneOffset() * 60000 // adjust timezone + ).getTime() / 1000).toString(16) + '0000000000000000' // id from time }/${page}/${this.pageSize}`, data => { this.changelog = data.map(e => new ChangelogModel().deserialize(e)); if (page) { diff --git a/src/app/documentation/documentation-architecture/documentation-architecture.component.html b/src/app/documentation/documentation-architecture/documentation-architecture.component.html new file mode 100644 index 0000000..ba752f3 --- /dev/null +++ b/src/app/documentation/documentation-architecture/documentation-architecture.component.html @@ -0,0 +1,50 @@ +

Architecture

+ +architecture + +

+ Bosch IoT Cloud space where all applications are hosted: + + https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2 +
+ Find the API documentation here: + + https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/ +
+ Admin database management page: + + https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/ +
+ Code repository UI + + https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui +
+ Code repository API + + https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api +
+

+ +

+ All applications are hosted in the bosch IoT Cloud. The API is hosted in a Node.js container, with a bound MongoDB + instance.
+ The Angular UI is hosted in a staticfile container, serving the built Angular bundle.
+ Finally any machine learning models are hosted in Python containers. +

+ +

Development setup

+ +

+ In any case, it is good to have PxProxy working, following the + + Bosch installation guide + .
+ For pushing to the BIC, you need the CloudFoundry CLI as described in the + BIC documentation. + If the the downloaded version of the CLI should not work, there is an old installer with a definitely working version + on the file share in the bin folder. + Please consider that you need to have a login to the BIC and be marked as space developer for the DeFinMa Org.
+ For front and back end development, you need a + local MongoDB server as well as + Node.js. +

diff --git a/src/app/documentation/documentation-architecture/documentation-architecture.component.scss b/src/app/documentation/documentation-architecture/documentation-architecture.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/documentation/documentation-architecture/documentation-architecture.component.spec.ts b/src/app/documentation/documentation-architecture/documentation-architecture.component.spec.ts new file mode 100644 index 0000000..ee6dd97 --- /dev/null +++ b/src/app/documentation/documentation-architecture/documentation-architecture.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DocumentationArchitectureComponent } from './documentation-architecture.component'; + +describe('DocumentationArchitectureComponent', () => { + let component: DocumentationArchitectureComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ DocumentationArchitectureComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(DocumentationArchitectureComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/documentation/documentation-architecture/documentation-architecture.component.ts b/src/app/documentation/documentation-architecture/documentation-architecture.component.ts new file mode 100644 index 0000000..3dd81d7 --- /dev/null +++ b/src/app/documentation/documentation-architecture/documentation-architecture.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-documentation-architecture', + templateUrl: './documentation-architecture.component.html', + styleUrls: ['./documentation-architecture.component.scss'] +}) +export class DocumentationArchitectureComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/app/documentation-database/documentation-database.component.html b/src/app/documentation/documentation-database/documentation-database.component.html similarity index 73% rename from src/app/documentation-database/documentation-database.component.html rename to src/app/documentation/documentation-database/documentation-database.component.html index 32296bc..0f324f9 100644 --- a/src/app/documentation-database/documentation-database.component.html +++ b/src/app/documentation/documentation-database/documentation-database.component.html @@ -1,7 +1,45 @@

Database

-

- Structure of the MongoDB instance running on the BIC, storing all application data. +

+ The used database instance is a MongoDB instance running on the BIC, storing all application data. The admin database + management page can be accessed + + https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/ + . + However, it is recommended to use a dedicated MongoDB application for anything apart from a quick look. The two tested + applications are MongoDB Compass and + Robo 3T (recommended for trying queries).
+ To connect to the BIC instance from your local application follow the + BIC guide. +
TLDR: +

+For the first time: + +Every time: + + +
Backup
+

+ For creating a database backup, you must follow the same steps from above (except the last one). Additionally you need + the MongoDB server installed. Open the MongoDB bin folder + (normally at C:\Program Files\MongoDB\Server\4.2\bin) in a PowerShell and execute following command for backup, + adjust parameters and credentials as needed:

+ mongodump.exe /port:1120 /db:"6ebe4c5d-0da3-4347-b484-66894dcf3f27" /username:"<:username>" + /password:"<:username>" /out:"C:\Path\to\backup\folder"

+ Restoring the database from a backup is done with mongorestore.exe, more information can be found at the + documentation.
+ The BIC service also creates internal backup, which can be requested to restore, see + MongoDB FAQ

Database model

@@ -274,8 +312,34 @@ The API key, generated when the user is created '5f294dd4aa9ea5085c7d7314' + + models + + Reference to the prediction models the user should have access to. Ignored for dev and + admin as they automatically have access to all models. + + ['5f466fb1e566810dd8b3e919', '5f294d8aaa9ea5085c7d730b'] + + + status + Status of the document, can be either new, validated or + deleted. + 'new' + models + + group + group the model belongs to + 'VN' + + + models + models of the group with _id, name and url to the Python endpoint + {{'{'}}_id: '5f466fb1e566810dd8b3e919', name: POM, url: 'http://localhost:9099/test'{{'}'}} + + + model_files _id Automatically generated unique id diff --git a/src/app/documentation-database/documentation-database.component.scss b/src/app/documentation/documentation-database/documentation-database.component.scss similarity index 100% rename from src/app/documentation-database/documentation-database.component.scss rename to src/app/documentation/documentation-database/documentation-database.component.scss diff --git a/src/app/documentation-database/documentation-database.component.spec.ts b/src/app/documentation/documentation-database/documentation-database.component.spec.ts similarity index 92% rename from src/app/documentation-database/documentation-database.component.spec.ts rename to src/app/documentation/documentation-database/documentation-database.component.spec.ts index fc51dcb..febc10d 100644 --- a/src/app/documentation-database/documentation-database.component.spec.ts +++ b/src/app/documentation/documentation-database/documentation-database.component.spec.ts @@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { DocumentationDatabaseComponent } from './documentation-database.component'; import {Component, Input} from '@angular/core'; -import {RbCustomInputsModule} from '../rb-custom-inputs/rb-custom-inputs.module'; +import {RbCustomInputsModule} from '../../rb-custom-inputs/rb-custom-inputs.module'; // TODO diff --git a/src/app/documentation-database/documentation-database.component.ts b/src/app/documentation/documentation-database/documentation-database.component.ts similarity index 100% rename from src/app/documentation-database/documentation-database.component.ts rename to src/app/documentation/documentation-database/documentation-database.component.ts diff --git a/src/app/documentation/documentation.component.html b/src/app/documentation/documentation.component.html index 3ae7a18..0596bb3 100644 --- a/src/app/documentation/documentation.component.html +++ b/src/app/documentation/documentation.component.html @@ -1,30 +1,11 @@

Documentation

-

- Bosch IoT Cloud space where all applications are hosted: - - https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2 -
- Find the API documentation here: - - https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/ -
- Code repository UI - - https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui -
- Code repository API - - https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api -
-

- -

Introduction

-

View the presentation explaining the main functions - +
+ View the T3000 report and + Bachelor Thesis for an in-depth application description.

User levels

@@ -96,13 +77,6 @@ -

Architecture

-architecture -

- All applications are hosted in the bosch IoT Cloud. The API is hosted in a Node.js container, with a bound MongoDB - instance.
- The Angular UI is hosted in a staticfile container, serving the built Angular bundle.
- Finally any machine learning models are hosted in Python containers. -

+ diff --git a/src/app/model-templates/model-templates.component.ts b/src/app/model-templates/model-templates.component.ts index bab3aee..256fd72 100644 --- a/src/app/model-templates/model-templates.component.ts +++ b/src/app/model-templates/model-templates.component.ts @@ -42,7 +42,7 @@ export class ModelTemplatesComponent implements OnInit { console.log(this.modelGroup); console.log(this.oldModelGroup); if (this.oldModelGroup !== '' && this.modelGroup !== this.oldModelGroup) { // group was changed, delete model in old group - this.deleteModel(null, this.oldModelGroup, this.oldModelName); + this.delete(null, this.oldModelGroup, this.oldModelName); } this.api.post('/model/' + this.modelGroup, this.model, () => { this.newModel = false; diff --git a/src/app/models/changelog.model.ts b/src/app/models/changelog.model.ts index 3ed5c21..df17c13 100644 --- a/src/app/models/changelog.model.ts +++ b/src/app/models/changelog.model.ts @@ -1,6 +1,8 @@ import {BaseModel} from './base.model'; +import {IdModel} from './id.model'; export class ChangelogModel extends BaseModel { + _id: IdModel = null; date: Date; action: string; collection: string; diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html index 98a6b8d..119f1f2 100644 --- a/src/app/sample/sample.component.html +++ b/src/app/sample/sample.component.html @@ -13,13 +13,14 @@ [rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" appValidate="stringOf" (keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" ngModel [appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true" - *ngIf="baseSample.material.name !== undefined || mode === 'new'" + *ngIf="mode === 'new' || (baseSample.material && baseSample.material.name !== undefined)" title="trade name of the material, eg. Ultradur B4300 G6"> Cannot be empty Unknown material, add properties for new material + (click)="setNewMaterial(!newMaterial)" + *ngIf="mode === 'new' || (baseSample.material && baseSample.material.name !== undefined)"> New material diff --git a/src/app/sample/sample.component.ts b/src/app/sample/sample.component.ts index 554620f..3186c67 100644 --- a/src/app/sample/sample.component.ts +++ b/src/app/sample/sample.component.ts @@ -118,6 +118,7 @@ export class SampleComponent implements OnInit, AfterContentChecked { ) { } ngOnInit(): void { + console.log(this.baseSample); this.mode = this.router.url === '/samples/new' ? 'new' : ''; this.loading = 7; this.d.load('materials', () => { @@ -378,8 +379,6 @@ export class SampleComponent implements OnInit, AfterContentChecked { cmSave() { // save measurements and conditions this.samples.forEach(sample => { if (sample.condition.condition_template) { // condition was set - console.log(sample.condition); - console.log(this.d.id.conditionTemplates[sample.condition.condition_template]); this.api.put('/sample/' + sample._id, {condition: pick(sample.condition, ['condition_template', ...this.d.id.conditionTemplates[sample.condition.condition_template].parameters.map(e => e.name)] diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index c573dc1..190edda 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -45,7 +45,6 @@ export class ApiService { observable.subscribe(data => { f(data.body, undefined, data.headers.keys().reduce((s, e) => {s[e.toLowerCase()] = data.headers.get(e); return s; }, {})); }, err => { - console.log(f.length); if (f.length > 1) { f(undefined, err, undefined); } diff --git a/src/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf b/src/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf new file mode 100644 index 0000000..cdf2457 Binary files /dev/null and b/src/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf differ diff --git a/src/assets/docs/Veit-Lukas_T3000.pdf b/src/assets/docs/Veit-Lukas_T3000.pdf new file mode 100644 index 0000000..394cfde Binary files /dev/null and b/src/assets/docs/Veit-Lukas_T3000.pdf differ diff --git a/src/index.html b/src/index.html index 173237a..fec97cb 100644 --- a/src/index.html +++ b/src/index.html @@ -6,8 +6,6 @@ - - diff --git a/src/styles.scss b/src/styles.scss index 339b355..b3fd216 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -46,3 +46,26 @@ button::-moz-focus-inner { .supergraphic { background-image: url("/assets/imgs/supergraphic.svg"); } + +//list styles +ul { + margin: 10px 0 10px 25px; + padding-left: 10px; + list-style: none; + + li { + + &:before { + float: left; + content: ''; + height: 8px; + width: 8px; + background: rgb(0,0,0); + position: relative; + top: 0.5em; + margin-left: -1.5em; + margin-right: .3em; + text-align: right; + } + } +}