Merge pull request #32 in ~VLE2FE/definma-ui from development to master
* commit '08d5ac8366279aae4da809a545c4949b2d583c6e': fixed changelog paging
This commit is contained in:
commit
c3ab2810dc
47
README.md
47
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.
|
||||
|
@ -65,9 +65,7 @@
|
||||
"maximumWarning": "6kb",
|
||||
"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 {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
|
||||
|
@ -15,6 +15,7 @@
|
||||
<ng-container *ngIf="isDocumentation">
|
||||
<nav *rbSubNavItems>
|
||||
<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>
|
||||
</nav>
|
||||
</ng-container>
|
||||
|
@ -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(['/']);
|
||||
}
|
||||
});
|
||||
|
@ -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,
|
||||
|
@ -26,7 +26,10 @@ export class ChangelogComponent implements OnInit {
|
||||
|
||||
loadChangelog(page = 0) {
|
||||
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 => {
|
||||
this.changelog = data.map(e => new ChangelogModel().deserialize(e));
|
||||
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>
|
||||
|
||||
<p class="space-below">
|
||||
Structure of the MongoDB instance running on the BIC, storing all application data.
|
||||
<p>
|
||||
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>
|
||||
|
||||
<h4>Database model</h4>
|
||||
@ -274,8 +312,34 @@
|
||||
<td>The API key, generated when the user is created</td>
|
||||
<td>'5f294dd4aa9ea5085c7d7314'</td>
|
||||
</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>
|
||||
<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>
|
||||
<td>_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 {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
|
||||
|
@ -1,30 +1,11 @@
|
||||
<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>
|
||||
<a [href]="api.hostName + '/static/intro-presentation/index.html'">
|
||||
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>
|
||||
|
||||
<h4>User levels</h4>
|
||||
@ -96,13 +77,6 @@
|
||||
</tr>
|
||||
</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.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;
|
||||
|
@ -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;
|
||||
|
@ -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">
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
<ng-template rbFormValidationMessage="failure">Unknown material, add properties for new material</ng-template>
|
||||
</rb-form-input>
|
||||
<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
|
||||
</rb-icon-button>
|
||||
</div>
|
||||
|
@ -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)]
|
||||
|
@ -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);
|
||||
}
|
||||
|
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="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
<meta name="theme-color" content="#1976d2">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user