fixed changelog paging
This commit is contained in:
parent
52e0d94e61
commit
08d5ac8366
47
README.md
47
README.md
@ -1,6 +1,9 @@
|
|||||||
# DeFinMa - UI
|
# 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
|
## 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)
|
[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.
|
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`
|
All components are displayed inside of the `app.component`, most of them directly as routes, see
|
||||||
respectively.
|
[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.
|
||||||
|
@ -65,9 +65,7 @@
|
|||||||
"maximumWarning": "6kb",
|
"maximumWarning": "6kb",
|
||||||
"maximumError": "10kb"
|
"maximumError": "10kb"
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"serviceWorker": true,
|
|
||||||
"ngswConfigPath": "ngsw-config.json"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -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)"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -9,9 +9,10 @@ import {TemplatesComponent} from './templates/templates.component';
|
|||||||
import {SettingsComponent} from './settings/settings.component';
|
import {SettingsComponent} from './settings/settings.component';
|
||||||
import {UsersComponent} from './users/users.component';
|
import {UsersComponent} from './users/users.component';
|
||||||
import {ChangelogComponent} from './changelog/changelog.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 {PredictionComponent} from './prediction/prediction.component';
|
||||||
import {ModelTemplatesComponent} from './model-templates/model-templates.component';
|
import {ModelTemplatesComponent} from './model-templates/model-templates.component';
|
||||||
|
import {DocumentationArchitectureComponent} from './documentation/documentation-architecture/documentation-architecture.component';
|
||||||
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
@ -27,6 +28,7 @@ const routes: Routes = [
|
|||||||
{path: 'users', component: UsersComponent, canActivate: [LoginService]},
|
{path: 'users', component: UsersComponent, canActivate: [LoginService]},
|
||||||
{path: 'settings', component: SettingsComponent, canActivate: [LoginService]},
|
{path: 'settings', component: SettingsComponent, canActivate: [LoginService]},
|
||||||
{path: 'documentation', component: DocumentationComponent},
|
{path: 'documentation', component: DocumentationComponent},
|
||||||
|
{path: 'documentation/architecture', component: DocumentationArchitectureComponent},
|
||||||
{path: 'documentation/database', component: DocumentationDatabaseComponent},
|
{path: 'documentation/database', component: DocumentationDatabaseComponent},
|
||||||
|
|
||||||
// if not authenticated
|
// if not authenticated
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<ng-container *ngIf="isDocumentation">
|
<ng-container *ngIf="isDocumentation">
|
||||||
<nav *rbSubNavItems>
|
<nav *rbSubNavItems>
|
||||||
<a routerLink="/documentation" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">General</a>
|
<a routerLink="/documentation" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">General</a>
|
||||||
|
<a routerLink="/documentation/architecture" routerLinkActive="active">Architecture</a>
|
||||||
<a routerLink="/documentation/database" routerLinkActive="active">Database</a>
|
<a routerLink="/documentation/database" routerLinkActive="active">Database</a>
|
||||||
</nav>
|
</nav>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {Component, isDevMode, OnInit} from '@angular/core';
|
import {Component, isDevMode, OnInit} from '@angular/core';
|
||||||
import {LoginService} from './services/login.service';
|
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 {ModalService} from '@inst-iot/bosch-angular-ui-components';
|
||||||
import {HelpComponent} from './help/help.component';
|
import {HelpComponent} from './help/help.component';
|
||||||
import {DataService} from './services/data.service';
|
import {DataService} from './services/data.service';
|
||||||
@ -22,6 +22,7 @@ export class AppComponent implements OnInit{
|
|||||||
constructor(
|
constructor(
|
||||||
public login: LoginService,
|
public login: LoginService,
|
||||||
public router: Router,
|
public router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
public window: Window,
|
public window: Window,
|
||||||
private modal: ModalService,
|
private modal: ModalService,
|
||||||
public d: DataService
|
public d: DataService
|
||||||
@ -36,7 +37,7 @@ export class AppComponent implements OnInit{
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.login.login().then(res => {
|
this.login.login().then(res => {
|
||||||
if (!res) {
|
if (!res && !(this.route.snapshot.url.length && this.route.snapshot.url[0].path === '/documentation')) {
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -26,13 +26,12 @@ import { ParametersPipe } from './parameters.pipe';
|
|||||||
import { SettingsComponent } from './settings/settings.component';
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
import { UsersComponent } from './users/users.component';
|
import { UsersComponent } from './users/users.component';
|
||||||
import { ChangelogComponent } from './changelog/changelog.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 { PredictionComponent } from './prediction/prediction.component';
|
||||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
|
||||||
import { environment } from '../environments/environment';
|
|
||||||
import { HelpComponent } from './help/help.component';
|
import { HelpComponent } from './help/help.component';
|
||||||
import { ModelTemplatesComponent } from './model-templates/model-templates.component';
|
import { ModelTemplatesComponent } from './model-templates/model-templates.component';
|
||||||
import { SizePipe } from './size.pipe';
|
import { SizePipe } from './size.pipe';
|
||||||
|
import { DocumentationArchitectureComponent } from './documentation/documentation-architecture/documentation-architecture.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -56,7 +55,8 @@ import { SizePipe } from './size.pipe';
|
|||||||
PredictionComponent,
|
PredictionComponent,
|
||||||
HelpComponent,
|
HelpComponent,
|
||||||
ModelTemplatesComponent,
|
ModelTemplatesComponent,
|
||||||
SizePipe
|
SizePipe,
|
||||||
|
DocumentationArchitectureComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
LocalStorageModule.forRoot({
|
LocalStorageModule.forRoot({
|
||||||
@ -73,8 +73,7 @@ import { SizePipe } from './size.pipe';
|
|||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
FormFieldsModule,
|
FormFieldsModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
ChartsModule,
|
ChartsModule
|
||||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production })
|
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
ModalService,
|
ModalService,
|
||||||
|
@ -26,7 +26,10 @@ export class ChangelogComponent implements OnInit {
|
|||||||
|
|
||||||
loadChangelog(page = 0) {
|
loadChangelog(page = 0) {
|
||||||
this.api.get<ChangelogModel[]>(`/changelog/${
|
this.api.get<ChangelogModel[]>(`/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 => {
|
}/${page}/${this.pageSize}`, data => {
|
||||||
this.changelog = data.map(e => new ChangelogModel().deserialize(e));
|
this.changelog = data.map(e => new ChangelogModel().deserialize(e));
|
||||||
if (page) {
|
if (page) {
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
<h4>Architecture</h4>
|
||||||
|
|
||||||
|
<img src="/assets/imgs/architecture.svg" alt="architecture" class="space-below">
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Bosch IoT Cloud space where all applications are hosted:
|
||||||
|
<a href="https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2">
|
||||||
|
https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2
|
||||||
|
</a><br>
|
||||||
|
Find the API documentation here:
|
||||||
|
<a href="https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/">
|
||||||
|
https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/
|
||||||
|
</a><br>
|
||||||
|
Admin database management page:
|
||||||
|
<a href="https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/">
|
||||||
|
https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/
|
||||||
|
</a><br>
|
||||||
|
Code repository UI
|
||||||
|
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui">
|
||||||
|
https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui
|
||||||
|
</a><br>
|
||||||
|
Code repository API
|
||||||
|
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api">
|
||||||
|
https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api
|
||||||
|
</a><br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
All applications are hosted in the bosch IoT Cloud. The API is hosted in a Node.js container, with a bound MongoDB
|
||||||
|
instance. <br>
|
||||||
|
The Angular UI is hosted in a staticfile container, serving the built Angular bundle. <br>
|
||||||
|
Finally any machine learning models are hosted in Python containers.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>Development setup</h4>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
In any case, it is good to have PxProxy working, following the
|
||||||
|
<a href="https://inside-docupedia.bosch.com/confluence/pages/viewpage.action?pageId=608652557">
|
||||||
|
Bosch installation guide
|
||||||
|
</a>. <br>
|
||||||
|
For pushing to the BIC, you need the CloudFoundry CLI as described in the
|
||||||
|
<a href="https://inside-docupedia.bosch.com/confluence/display/BICI/Cloud+Foundry+CLI">BIC documentation</a>.
|
||||||
|
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. <br>
|
||||||
|
For front and back end development, you need a
|
||||||
|
<a href="https://www.mongodb.com/try/download/community">local MongoDB server</a> as well as
|
||||||
|
<a href="https://nodejs.org/en/">Node.js</a>.
|
||||||
|
</p>
|
@ -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<DocumentationArchitectureComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ DocumentationArchitectureComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(DocumentationArchitectureComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,45 @@
|
|||||||
<h2>Database</h2>
|
<h2>Database</h2>
|
||||||
|
|
||||||
<p class="space-below">
|
<p>
|
||||||
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
|
||||||
|
<a href="https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/">
|
||||||
|
https://definma-db.apps.de1.bosch-iot-cloud.com/api-doc/
|
||||||
|
</a>.
|
||||||
|
However, it is recommended to use a dedicated MongoDB application for anything apart from a quick look. The two tested
|
||||||
|
applications are <a href="https://www.mongodb.com/products/compass">MongoDB Compass</a> and
|
||||||
|
<a href="https://robomongo.org/s">Robo 3T</a> (recommended for trying queries).<br>
|
||||||
|
To connect to the BIC instance from your local application follow the
|
||||||
|
<a href="https://inside-docupedia.bosch.com/confluence/display/BICI/MongoDB+Client+Tool+via+SSH+Tunnel">BIC guide</a>.
|
||||||
|
<br>TLDR:
|
||||||
|
</p>
|
||||||
|
For the first time:
|
||||||
|
<ul>
|
||||||
|
<li>cf login</li>
|
||||||
|
<li>cf enable-ssh <app-name, probably definma-api></li>
|
||||||
|
<li>cf create-service-key <service-name, probably definmadb> <key-name, can be whatever></li>
|
||||||
|
</ul>
|
||||||
|
Every time:
|
||||||
|
<ul>
|
||||||
|
<li>cf ssh -L 1120:st0cvm200118.internal-mongodb.de1.bosch-iot-cloud.com:30000 definma-api</li>
|
||||||
|
<li>
|
||||||
|
Login into your application with localhost:1120 and use credentials and Authentication Database from the BIC
|
||||||
|
(Data can be found at Home>DeFinMa>production>definma-api>Services>dots on the right of definmadb>View Credentials)
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h6>Backup</h6>
|
||||||
|
<p>
|
||||||
|
For creating a database backup, you must follow the same steps from above (except the last one). Additionally you need
|
||||||
|
the <a href="https://www.mongodb.com/try/download/community">MongoDB server</a> 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: <br><br>
|
||||||
|
mongodump.exe /port:1120 /db:"6ebe4c5d-0da3-4347-b484-66894dcf3f27" /username:"<:username>"
|
||||||
|
/password:"<:username>" /out:"C:\Path\to\backup\folder"<br><br>
|
||||||
|
Restoring the database from a backup is done with mongorestore.exe, more information can be found at the
|
||||||
|
<a href="https://docs.mongodb.com/database-tools/">documentation</a>. <br>
|
||||||
|
The BIC service also creates internal backup, which can be requested to restore, see
|
||||||
|
<a href="https://inside-docupedia.bosch.com/confluence/pages/viewpage.action?pageId=565402281">MongoDB FAQ</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>Database model</h4>
|
<h4>Database model</h4>
|
||||||
@ -274,8 +312,34 @@
|
|||||||
<td>The API key, generated when the user is created</td>
|
<td>The API key, generated when the user is created</td>
|
||||||
<td>'5f294dd4aa9ea5085c7d7314'</td>
|
<td>'5f294dd4aa9ea5085c7d7314'</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>models</td>
|
||||||
|
<td>
|
||||||
|
Reference to the prediction models the user should have access to. Ignored for <span class="name">dev</span> and
|
||||||
|
<span class="name">admin</span> as they automatically have access to all models.
|
||||||
|
</td>
|
||||||
|
<td>['5f466fb1e566810dd8b3e919', '5f294d8aaa9ea5085c7d730b']</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>status</td>
|
||||||
|
<td>Status of the document, can be either <span class="name">new</span>, <span class="name">validated</span> or
|
||||||
|
<span class="name">deleted</span>.</td>
|
||||||
|
<td>'new'</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr><th>models</th><th></th><th></th></tr>
|
<tr><th>models</th><th></th><th></th></tr>
|
||||||
|
<tr>
|
||||||
|
<td>group</td>
|
||||||
|
<td>group the model belongs to</td>
|
||||||
|
<td>'VN'</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>models</td>
|
||||||
|
<td>models of the group with _id, name and url to the Python endpoint</td>
|
||||||
|
<td>{{'{'}}_id: '5f466fb1e566810dd8b3e919', name: POM, url: 'http://localhost:9099/test'{{'}'}}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr><th>model_files</th><th></th><th></th></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>_id</td>
|
<td>_id</td>
|
||||||
<td>Automatically generated unique id</td>
|
<td>Automatically generated unique id</td>
|
@ -2,7 +2,7 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
|
|
||||||
import { DocumentationDatabaseComponent } from './documentation-database.component';
|
import { DocumentationDatabaseComponent } from './documentation-database.component';
|
||||||
import {Component, Input} from '@angular/core';
|
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
|
// TODO
|
||||||
|
|
@ -1,30 +1,11 @@
|
|||||||
<h2>Documentation</h2>
|
<h2>Documentation</h2>
|
||||||
|
|
||||||
<p>
|
|
||||||
Bosch IoT Cloud space where all applications are hosted:
|
|
||||||
<a href="https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2">
|
|
||||||
https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2
|
|
||||||
</a><br>
|
|
||||||
Find the API documentation here:
|
|
||||||
<a href="https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/">
|
|
||||||
https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/
|
|
||||||
</a><br>
|
|
||||||
Code repository UI
|
|
||||||
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui">
|
|
||||||
https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui
|
|
||||||
</a><br>
|
|
||||||
Code repository API
|
|
||||||
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api">
|
|
||||||
https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api
|
|
||||||
</a><br>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h4>Introduction</h4>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<a [href]="api.hostName + '/static/intro-presentation/index.html'">
|
<a [href]="api.hostName + '/static/intro-presentation/index.html'">
|
||||||
View the presentation explaining the main functions
|
View the presentation explaining the main functions
|
||||||
</a>
|
</a><br>
|
||||||
|
View the <a href="/assets/docs/Veit-Lukas_T3000.pdf">T3000 report</a> and
|
||||||
|
<a href="/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf">Bachelor Thesis</a> for an in-depth application description.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>User levels</h4>
|
<h4>User levels</h4>
|
||||||
@ -96,13 +77,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</rb-table>
|
</rb-table>
|
||||||
|
|
||||||
<h4>Architecture</h4>
|
|
||||||
|
|
||||||
<img src="/assets/imgs/architecture.svg" alt="architecture" class="space-below">
|
|
||||||
|
|
||||||
<p>
|
|
||||||
All applications are hosted in the bosch IoT Cloud. The API is hosted in a Node.js container, with a bound MongoDB
|
|
||||||
instance. <br>
|
|
||||||
The Angular UI is hosted in a staticfile container, serving the built Angular bundle. <br>
|
|
||||||
Finally any machine learning models are hosted in Python containers.
|
|
||||||
</p>
|
|
||||||
|
@ -42,7 +42,7 @@ export class ModelTemplatesComponent implements OnInit {
|
|||||||
console.log(this.modelGroup);
|
console.log(this.modelGroup);
|
||||||
console.log(this.oldModelGroup);
|
console.log(this.oldModelGroup);
|
||||||
if (this.oldModelGroup !== '' && this.modelGroup !== this.oldModelGroup) { // group was changed, delete model in old group
|
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.api.post('/model/' + this.modelGroup, this.model, () => {
|
||||||
this.newModel = false;
|
this.newModel = false;
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import {BaseModel} from './base.model';
|
import {BaseModel} from './base.model';
|
||||||
|
import {IdModel} from './id.model';
|
||||||
|
|
||||||
export class ChangelogModel extends BaseModel {
|
export class ChangelogModel extends BaseModel {
|
||||||
|
_id: IdModel = null;
|
||||||
date: Date;
|
date: Date;
|
||||||
action: string;
|
action: string;
|
||||||
collection: string;
|
collection: string;
|
||||||
|
@ -13,13 +13,14 @@
|
|||||||
[rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" appValidate="stringOf"
|
[rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" appValidate="stringOf"
|
||||||
(keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" ngModel
|
(keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" ngModel
|
||||||
[appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true"
|
[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">
|
title="trade name of the material, eg. Ultradur B4300 G6">
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
<ng-template rbFormValidationMessage="failure">Unknown material, add properties for new material</ng-template>
|
<ng-template rbFormValidationMessage="failure">Unknown material, add properties for new material</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-icon-button class="set-new-material space-below" icon="add" mode="secondary"
|
<rb-icon-button class="set-new-material space-below" icon="add" mode="secondary"
|
||||||
(click)="setNewMaterial(!newMaterial)" *ngIf="baseSample.material.name !== undefined">
|
(click)="setNewMaterial(!newMaterial)"
|
||||||
|
*ngIf="mode === 'new' || (baseSample.material && baseSample.material.name !== undefined)">
|
||||||
New material
|
New material
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -118,6 +118,7 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
console.log(this.baseSample);
|
||||||
this.mode = this.router.url === '/samples/new' ? 'new' : '';
|
this.mode = this.router.url === '/samples/new' ? 'new' : '';
|
||||||
this.loading = 7;
|
this.loading = 7;
|
||||||
this.d.load('materials', () => {
|
this.d.load('materials', () => {
|
||||||
@ -378,8 +379,6 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
cmSave() { // save measurements and conditions
|
cmSave() { // save measurements and conditions
|
||||||
this.samples.forEach(sample => {
|
this.samples.forEach(sample => {
|
||||||
if (sample.condition.condition_template) { // condition was set
|
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,
|
this.api.put('/sample/' + sample._id,
|
||||||
{condition: pick(sample.condition,
|
{condition: pick(sample.condition,
|
||||||
['condition_template', ...this.d.id.conditionTemplates[sample.condition.condition_template].parameters.map(e => e.name)]
|
['condition_template', ...this.d.id.conditionTemplates[sample.condition.condition_template].parameters.map(e => e.name)]
|
||||||
|
@ -45,7 +45,6 @@ export class ApiService {
|
|||||||
observable.subscribe(data => {
|
observable.subscribe(data => {
|
||||||
f(data.body, undefined, data.headers.keys().reduce((s, e) => {s[e.toLowerCase()] = data.headers.get(e); return s; }, {}));
|
f(data.body, undefined, data.headers.keys().reduce((s, e) => {s[e.toLowerCase()] = data.headers.get(e); return s; }, {}));
|
||||||
}, err => {
|
}, err => {
|
||||||
console.log(f.length);
|
|
||||||
if (f.length > 1) {
|
if (f.length > 1) {
|
||||||
f(undefined, err, undefined);
|
f(undefined, err, undefined);
|
||||||
}
|
}
|
||||||
|
BIN
src/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf
Normal file
BIN
src/assets/docs/Veit-Lukas_Bachelor-Thesis.pdf
Normal file
Binary file not shown.
BIN
src/assets/docs/Veit-Lukas_T3000.pdf
Normal file
BIN
src/assets/docs/Veit-Lukas_T3000.pdf
Normal file
Binary file not shown.
@ -6,8 +6,6 @@
|
|||||||
<base href="/">
|
<base href="/">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<link rel="manifest" href="manifest.webmanifest">
|
|
||||||
<meta name="theme-color" content="#1976d2">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
|
@ -46,3 +46,26 @@ button::-moz-focus-inner {
|
|||||||
.supergraphic {
|
.supergraphic {
|
||||||
background-image: url("/assets/imgs/supergraphic.svg");
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user