Merge pull request #35 in ~VLE2FE/definma-ui from development to master
* commit 'cd4e2aa77b5dd66d4898adf7494e47a0466a9595': added model documentation added material search fixed new user model input and renaming model group renamed material name to product name, removed headings
This commit is contained in:
commit
1f1ce7dd9c
@ -15,6 +15,7 @@ import {ModelTemplatesComponent} from './model-templates/model-templates.compone
|
||||
import {DocumentationArchitectureComponent} from './documentation/documentation-architecture/documentation-architecture.component';
|
||||
import {MaterialsComponent} from './materials/materials.component';
|
||||
import {MaterialComponent} from './material/material.component';
|
||||
import {DocumentationModelsComponent} from './documentation/documentation-models/documentation-models.component';
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
@ -34,6 +35,7 @@ const routes: Routes = [
|
||||
{path: 'documentation', component: DocumentationComponent},
|
||||
{path: 'documentation/architecture', component: DocumentationArchitectureComponent},
|
||||
{path: 'documentation/database', component: DocumentationDatabaseComponent},
|
||||
{path: 'documentation/models', component: DocumentationModelsComponent},
|
||||
|
||||
// if not authenticated
|
||||
{ path: '**', redirectTo: '' }
|
||||
|
@ -18,6 +18,7 @@
|
||||
<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/models" routerLinkActive="active">Models</a>
|
||||
</nav>
|
||||
</ng-container>
|
||||
|
||||
|
@ -34,6 +34,7 @@ import { SizePipe } from './size.pipe';
|
||||
import { DocumentationArchitectureComponent } from './documentation/documentation-architecture/documentation-architecture.component';
|
||||
import { MaterialsComponent } from './materials/materials.component';
|
||||
import { MaterialComponent } from './material/material.component';
|
||||
import { DocumentationModelsComponent } from './documentation/documentation-models/documentation-models.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -60,7 +61,8 @@ import { MaterialComponent } from './material/material.component';
|
||||
SizePipe,
|
||||
DocumentationArchitectureComponent,
|
||||
MaterialsComponent,
|
||||
MaterialComponent
|
||||
MaterialComponent,
|
||||
DocumentationModelsComponent
|
||||
],
|
||||
imports: [
|
||||
LocalStorageModule.forRoot({
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Changelog</h2>
|
||||
|
||||
<div class="header">
|
||||
<rb-form-date-input name="dateInput" label="older than" [options]="{enableTime: true}"
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h4>Architecture</h4>
|
||||
|
||||
<img src="/assets/imgs/architecture.svg" alt="architecture" class="space-below">
|
||||
|
||||
@ -12,8 +11,8 @@
|
||||
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 href="https://definma-db.apps.de1.bosch-iot-cloud.com/">
|
||||
https://definma-db.apps.de1.bosch-iot-cloud.com/
|
||||
</a><br>
|
||||
Code repository UI
|
||||
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-ui">
|
||||
@ -23,6 +22,10 @@
|
||||
<a href="https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api">
|
||||
https://sourcecode.socialcoding.bosch.com/users/vle2fe/repos/definma-api
|
||||
</a><br>
|
||||
Code repository Models
|
||||
<a href="https://sourcecode.socialcoding.bosch.com/users/poe2rng/repos/definma-models">
|
||||
https://sourcecode.socialcoding.bosch.com/users/poe2rng/repos/definma-models
|
||||
</a><br>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Database</h2>
|
||||
|
||||
<p>
|
||||
The used database instance is a MongoDB instance running on the BIC, storing all application data. The admin database
|
||||
@ -31,11 +30,12 @@ Every time:
|
||||
<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
|
||||
the <a href="https://docs.mongodb.com/database-tools/installation/#install-tools">mongodump</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>
|
||||
.\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
|
||||
|
@ -0,0 +1,56 @@
|
||||
<h4>Model file upload</h4>
|
||||
|
||||
<p>
|
||||
Model files have to be saved as a .pkl file in 80_Modelle_BIC. <br>
|
||||
For upload the upload script has to be opened (can be in every environment). The name of the model file has to be
|
||||
entered wih the .pkl ending in the first command and without .pkl in the second.
|
||||
</p>
|
||||
|
||||
<h4 class="space-above">Adding new model scripts</h4>
|
||||
|
||||
<p>
|
||||
Open Spyder in the base environment and open the model.py within.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Enter model file name without .pkl in fetchData</li>
|
||||
<li>Add new prediction function below others</li>
|
||||
<li>duplicate another @app.route and rename according to desired route name and prediction function name</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="space-above">Testing locally</h4>
|
||||
|
||||
<p>
|
||||
To test the model Python script locally, you need to execute it in the base environment, in which all necessary
|
||||
packages have to be installed. Note that Spyder also has to be opened in the base environment.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Open a separate Anaconda Prompt and cd into the definma-UI folder</li>
|
||||
<li>Adapt the model-mock.json at definma-UI/assets/ and enter the new model URL and name</li>
|
||||
<li>Execute "python -m http.server" in the Anaconda Prompt</li>
|
||||
<li>Execute the model.py script in Spyder</li>
|
||||
<li>Navigate to <a href="http://localhost:8000">http://localhost:8000</a> in the browser</li>
|
||||
<li>If there are problems with cached data, open the Browser developer console (Ctrl+Shift+I) and tick
|
||||
"Disable cache" in the Network tab. The console then has to stay open.</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="space-above">Model script upload</h4>
|
||||
|
||||
In the Windows Powershell:
|
||||
|
||||
<ul>
|
||||
<li>cf login (only at the first time)</li>
|
||||
<li>API endpoint: https://api.sys.de1.bosch-iot-cloud.com</li>
|
||||
<li>Enter email with .de.bosch.com</li>
|
||||
<li>Enter BIC password</li>
|
||||
<li>Select space to upload to (currently 3 - development)</li>
|
||||
<li>cd into the folder containing the manifest.yaml (here is also model.py)</li>
|
||||
<li>cf push</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
After upload the new model details have to be entered in the UI.
|
||||
</p>
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { DocumentationModelsComponent } from './documentation-models.component';
|
||||
|
||||
describe('DocumentationModelsComponent', () => {
|
||||
let component: DocumentationModelsComponent;
|
||||
let fixture: ComponentFixture<DocumentationModelsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ DocumentationModelsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocumentationModelsComponent);
|
||||
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-models',
|
||||
templateUrl: './documentation-models.component.html',
|
||||
styleUrls: ['./documentation-models.component.scss']
|
||||
})
|
||||
export class DocumentationModelsComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
<h2>Documentation</h2>
|
||||
|
||||
<p>
|
||||
<a [href]="api.hostName + '/static/intro-presentation/index.html'">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<h2>Edit material</h2>
|
||||
<h2>{{material.name | exists}}</h2>
|
||||
|
||||
<form #materialForm="ngForm" *ngIf="!loading">
|
||||
<rb-form-input name="materialname" label="material name" appValidate="stringNin" [appValidateArgs]="[materialNames]"
|
||||
<rb-form-input name="materialname" label="product name" appValidate="stringNin" [appValidateArgs]="[materialNames]"
|
||||
required [(ngModel)]="material.name" #materialnameInput="ngModel">
|
||||
<ng-template rbFormValidationMessage="failure">{{materialnameInput.errors.failure}}</ng-template>
|
||||
</rb-form-input>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div class="header-addnew">
|
||||
<h2>Materials</h2>
|
||||
<rb-icon-button *ngIf="sampleSelect" mode="secondary" icon="close" (click)="sampleSelect = false"
|
||||
class="validation-close" iconOnly></rb-icon-button>
|
||||
<rb-icon-button [icon]="sampleSelect ? 'checkmark' : 'clear-all'"
|
||||
@ -27,6 +26,11 @@
|
||||
</rb-form-checkbox>
|
||||
</div>
|
||||
|
||||
<div class="material-search space-right">
|
||||
<rb-form-input label="search" [(ngModel)]="materialSearch" icon="close"></rb-form-input>
|
||||
<span class="rb-ic rb-ic-close clickable" (click)="materialSearch = ''"></span>
|
||||
</div>
|
||||
|
||||
<ng-container *ngTemplateOutlet="paging"></ng-container>
|
||||
|
||||
<rb-table ellipsis scrollTop>
|
||||
@ -41,7 +45,8 @@
|
||||
<th>Numbers</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr *ngFor="let material of (materials || []).slice((page - 1) * pageSize, page * pageSize); index as i">
|
||||
<tr *ngFor="let material of (materials || []).filter(materialFilter(materialSearch))
|
||||
.slice((page - 1) * pageSize, page * pageSize); index as i">
|
||||
<td *ngIf="sampleSelect">
|
||||
<rb-form-checkbox *ngIf="material.status !== 'deleted'" [name]="'validate-' + i"
|
||||
[(ngModel)]="material.selected">
|
||||
|
@ -40,8 +40,6 @@
|
||||
}
|
||||
|
||||
.header-addnew {
|
||||
margin-bottom: 40px;
|
||||
|
||||
& > * {
|
||||
display: inline;
|
||||
margin-bottom: 10px;
|
||||
@ -51,3 +49,15 @@
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.material-search {
|
||||
width: 300px;
|
||||
float: left;
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 24px;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ export class MaterialsComponent implements OnInit {
|
||||
materials: MaterialModel[] = [];
|
||||
templateKeys: {key: string, label: string}[] = [];
|
||||
materialStatus = {validated: true, new: true, deleted: false};
|
||||
materialSearch = '';
|
||||
sampleSelect = false;
|
||||
|
||||
page = 1;
|
||||
@ -89,4 +90,8 @@ export class MaterialsComponent implements OnInit {
|
||||
return string[0].toUpperCase() + string.slice(1);
|
||||
}
|
||||
|
||||
materialFilter(ms) {
|
||||
return e => e.name.indexOf(ms) >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Models</h2>
|
||||
|
||||
<rb-icon-button icon="add" mode="primary" (click)="newModel = !newModel; oldModelGroup = ''" class="space-below">
|
||||
New model
|
||||
|
@ -43,7 +43,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.delete(null, this.oldModelGroup, this.oldModelName);
|
||||
this.delete(null, this.oldModelName, this.oldModelGroup);
|
||||
}
|
||||
this.api.post('/model/' + this.modelGroup, omit(this.model, '_id'), () => {
|
||||
this.newModel = false;
|
||||
|
@ -25,6 +25,8 @@ export class UserModel extends BaseModel{
|
||||
if (mode === 'admin') {
|
||||
keys.push('level');
|
||||
keys.push('models');
|
||||
this.devices = this.devices.filter(e => e);
|
||||
this.models = this.models.filter(e => e);
|
||||
}
|
||||
return pick(this, keys);
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Prediction</h2>
|
||||
|
||||
<rb-tab-panel (tabChanged)="groupChange($event)">
|
||||
<ng-container *ngFor="let group of d.arr.modelGroups; index as i">
|
||||
|
@ -122,17 +122,23 @@ export class RbArrayInputComponent implements ControlValueAccessor, OnInit, Afte
|
||||
this.values = [this.values[0]];
|
||||
res = this.values;
|
||||
}
|
||||
if (!res.length) {
|
||||
res = [''];
|
||||
}
|
||||
// if (!res.length) {
|
||||
// res = [''];
|
||||
// }
|
||||
this.onChange(res); // trigger ngModel with filled elements
|
||||
}
|
||||
|
||||
writeValue(obj: any) { // add empty value on init
|
||||
console.log(obj);
|
||||
if (obj) {
|
||||
if (this.pushTemplate !== null) {
|
||||
if (this.pushPath) {
|
||||
this.values = [...obj.filter(e => e[this.pushPath] !== ''), cloneDeep(this.pushTemplate)];
|
||||
}
|
||||
else {
|
||||
this.values = [...obj.filter(e => e !== ''), cloneDeep(this.pushTemplate)];
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.values = obj;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
<form #sampleForm="ngForm" *ngIf="view.base">
|
||||
<div class="sample">
|
||||
<div>
|
||||
<rb-form-input name="materialname" label="material name" [rbDebounceTime]="0" [rbInitialOpen]="true"
|
||||
<rb-form-input name="materialname" label="product name" [rbDebounceTime]="0" [rbInitialOpen]="true"
|
||||
[rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" appValidate="stringOf"
|
||||
(keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" ngModel
|
||||
[appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true"
|
||||
|
@ -1,5 +1,4 @@
|
||||
<div class="header-addnew">
|
||||
<h2>Samples</h2>
|
||||
<a routerLink="/samples/new" *ngIf="login.isLevel.write">
|
||||
<rb-icon-button icon="add" mode="primary" class="space-left">New sample</rb-icon-button>
|
||||
</a>
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
.header-addnew {
|
||||
margin-bottom: 40px;
|
||||
height: 42px;
|
||||
|
||||
& > * {
|
||||
display: inline;
|
||||
|
@ -13,7 +13,6 @@ import {Router} from '@angular/router';
|
||||
|
||||
// TODO: turn off sort field
|
||||
// TODO reset sort when field is excluded
|
||||
// TODO: material name to product
|
||||
// TODO: Eh DPT
|
||||
// TODO: filter button
|
||||
// TODO: check if connect-src to model works
|
||||
@ -55,7 +54,7 @@ export class SamplesComponent implements OnInit {
|
||||
sort: 'added-asc',
|
||||
filters: [
|
||||
{field: 'number', label: 'Number', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
{field: 'material.name', label: 'Material name', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
{field: 'material.name', label: 'Product name', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
{field: 'material.supplier', label: 'Supplier', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
{field: 'material.group', label: 'Material', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
{field: 'material.glass_fiber', label: 'GF', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||
@ -74,7 +73,7 @@ export class SamplesComponent implements OnInit {
|
||||
keys: KeyInterface[] = [
|
||||
{id: 'number', label: 'Number', active: true, sortable: true},
|
||||
{id: 'material.numbers', label: 'Material numbers', active: false, sortable: false},
|
||||
{id: 'material.name', label: 'Material name', active: true, sortable: true},
|
||||
{id: 'material.name', label: 'Product name', active: true, sortable: true},
|
||||
{id: 'material.supplier', label: 'Supplier', active: false, sortable: true},
|
||||
{id: 'material.group', label: 'Material', active: true, sortable: true},
|
||||
{id: 'type', label: 'Type', active: true, sortable: true},
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Settings</h2>
|
||||
|
||||
<form #userForm="ngForm">
|
||||
<rb-form-input name="name" label="user name" appValidate="username" required [(ngModel)]="user.name"
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Templates</h2>
|
||||
|
||||
<rb-form-select name="collectionSelection" label="collection"
|
||||
[(ngModel)]="collection" (ngModelChange)="loadTemplates()">
|
||||
|
@ -1,4 +1,3 @@
|
||||
<h2>Users</h2>
|
||||
|
||||
<rb-icon-button icon="add" mode="primary" (click)="addNewUser()">New user</rb-icon-button>
|
||||
|
||||
|
@ -41,6 +41,9 @@ export class UsersComponent implements OnInit {
|
||||
}
|
||||
|
||||
saveUser(user: UserModel) {
|
||||
console.log(user.models);
|
||||
user.models = user.models.filter(e => e !== '');
|
||||
console.log(user.models);
|
||||
this.api.put<UserModel>('/user/' + user.origName, user.sendFormat('admin'), data => {
|
||||
user.deserialize(data);
|
||||
user.edit = false;
|
||||
@ -48,6 +51,7 @@ export class UsersComponent implements OnInit {
|
||||
}
|
||||
|
||||
saveNewUser() {
|
||||
// this.newUser.models = this.newUser.models.filter(e => e !== '' || e !== undefined);
|
||||
this.api.post('/user/new', {...this.newUser.sendFormat('admin'), pass: this.newUserPass}, data => {
|
||||
this.newUser = null;
|
||||
this.users.push(new UserModel().deserialize(data));
|
||||
|
@ -69,3 +69,7 @@ ul {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-main a.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user