diff --git a/README.md b/README.md index 584be18..00b887f 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,11 @@ This is the Angular front end for the digital fingerprint of plastics web page h ## Bosch styled components -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. +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 -Unit and e2e tests are implemented and can be executed using `ng test` and `protractor ./e2e/protractor.conf.js` respectively. +Unit and e2e tests are implemented and can be executed using `ng test` and `protractor ./e2e/protractor.conf.js` +respectively. diff --git a/angular.json b/angular.json index 126fb2c..023e2a4 100644 --- a/angular.json +++ b/angular.json @@ -26,7 +26,11 @@ "assets": [ "src/favicon.ico", "src/assets", - { "glob": "**/*", "input": "./node_modules/@inst-iot/bosch-angular-ui-components/assets", "output": "./assets" } + { + "glob": "**/*", + "input": "./node_modules/@inst-iot/bosch-angular-ui-components/assets", + "output": "./assets" + } ], "styles": [ "src/styles.scss" diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c8bfb07..91652bc 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -50,7 +50,7 @@ import { DocumentationDatabaseComponent } from './documentation-database/documen ], imports: [ LocalStorageModule.forRoot({ - prefix: 'dfop', + prefix: 'definma', storageType: 'localStorage' }), BrowserModule, diff --git a/src/app/changelog/changelog.component.html b/src/app/changelog/changelog.component.html index d2c64d8..8954f31 100644 --- a/src/app/changelog/changelog.component.html +++ b/src/app/changelog/changelog.component.html @@ -21,7 +21,7 @@ - + Date Action diff --git a/src/app/documentation-database/documentation-database.component.html b/src/app/documentation-database/documentation-database.component.html index a2e8ca7..d957144 100644 --- a/src/app/documentation-database/documentation-database.component.html +++ b/src/app/documentation-database/documentation-database.component.html @@ -22,10 +22,10 @@ type - The material status of the sample, can be either granulate, part - or tension rod. + The material status of the sample, can be either as-delivered/raw or + processed. - 'granulate' + 'processed' number @@ -118,13 +118,13 @@ name - + Trade name of the material 'Ultradur B4300 G6' numbers - Trade name of the material - + Bosch material part numbers + ['5515753021, '5515753404'] properties @@ -149,6 +149,30 @@ 'new' + material_groups + + _id + Automatically generated unique id + '5f2e631291c5d68f8a0708f9' + + + name + The chemical material type + 'PA66' + + + material_supplier + + _id + Automatically generated unique id + '5f2e631991c5d68f8a0709c3' + + + name + The material supplier + 'BASF' + + measurements _id diff --git a/src/app/documentation-database/documentation-database.component.scss b/src/app/documentation-database/documentation-database.component.scss index f3900d2..247c3ea 100644 --- a/src/app/documentation-database/documentation-database.component.scss +++ b/src/app/documentation-database/documentation-database.component.scss @@ -1,11 +1,5 @@ -.field-reference td { - white-space: normal; - text-overflow: initial; - max-width: none; - - &:nth-child(3) { - font-family: boschmono, monospace; - } +.field-reference td:nth-child(3) { + font-family: boschmono, monospace; } span.name { diff --git a/src/app/error/error.component.html b/src/app/error/error.component.html index 5a16414..4612d39 100644 --- a/src/app/error/error.component.html +++ b/src/app/error/error.component.html @@ -1,3 +1,11 @@ - {{message}} +
+ {{message}} +
+
+ Details +
+

{{detail}}

+
+
diff --git a/src/app/error/error.component.ts b/src/app/error/error.component.ts index fe0940d..5ecd4e0 100644 --- a/src/app/error/error.component.ts +++ b/src/app/error/error.component.ts @@ -8,6 +8,7 @@ import { Component, OnInit } from '@angular/core'; export class ErrorComponent implements OnInit { message = ''; + details: string[] = []; constructor() { } diff --git a/src/app/img-magnifier/img-magnifier.component.scss b/src/app/img-magnifier/img-magnifier.component.scss index f72791e..e895365 100644 --- a/src/app/img-magnifier/img-magnifier.component.scss +++ b/src/app/img-magnifier/img-magnifier.component.scss @@ -11,9 +11,7 @@ .magnifier { position: absolute; - background: #FFF; - background-repeat: no-repeat; - background-position: -500px -500px; + background: #FFF no-repeat -500px -500px; z-index: 99; border: 1px solid #FFF; box-shadow: 10px 10px 25px $color-bosch-light-gray-b25; diff --git a/src/app/img-magnifier/img-magnifier.component.ts b/src/app/img-magnifier/img-magnifier.component.ts index 5a339db..299967b 100644 --- a/src/app/img-magnifier/img-magnifier.component.ts +++ b/src/app/img-magnifier/img-magnifier.component.ts @@ -7,9 +7,9 @@ import {AfterViewInit, Component, ElementRef, Input, OnInit, ViewChild} from '@a }) export class ImgMagnifierComponent implements OnInit, AfterViewInit { - @Input('src') src: string; - @Input('zoom') zoom: number; - @Input('magnifierSize') magnifierSize: {width: number, height: number}; + @Input() src: string; + @Input() zoom: number; + @Input() magnifierSize: {width: number, height: number}; @ViewChild('mainImg') mainImg: ElementRef; backgroundSize; @@ -31,11 +31,18 @@ export class ImgMagnifierComponent implements OnInit, AfterViewInit { calcPos(event) { const img = this.mainImg.nativeElement.getBoundingClientRect(); - this.magnifierPos.x = Math.min(img.width - this.magnifierSize.width, Math.max(0, event.pageX - img.left - this.window.pageXOffset - this.magnifierSize.width / 2)); - this.magnifierPos.y = Math.min(img.height - this.magnifierSize.height + 7, Math.max(0, event.pageY - img.top - this.window.pageYOffset - this.magnifierSize.height / 2)); + this.magnifierPos.x = Math.min( + img.width - this.magnifierSize.width, + Math.max(0, event.pageX - img.left - this.window.pageXOffset - this.magnifierSize.width / 2) + ); + this.magnifierPos.y = Math.min( + img.height - this.magnifierSize.height + 7, + Math.max(0, event.pageY - img.top - this.window.pageYOffset - this.magnifierSize.height / 2) + ); } calcBackgroundSize() { - this.backgroundSize = this.mainImg ? (this.mainImg.nativeElement.width * this.zoom - this.magnifierSize.width) + 'px ' + (this.mainImg.nativeElement.height * this.zoom - this.magnifierSize.height) + 'px ' : '0 0'; + this.backgroundSize = this.mainImg ? (this.mainImg.nativeElement.width * this.zoom - this.magnifierSize.width) + 'px ' + + (this.mainImg.nativeElement.height * this.zoom - this.magnifierSize.height) + 'px ' : '0 0'; } } diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 6de06e5..4c41623 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -3,17 +3,22 @@
- + {{usernameInput.errors.failure}} - + {{passwordInput.errors.failure}} - + {{emailInput.errors.failure}} Forgot password - +
{{message}}
diff --git a/src/app/rb-custom-inputs/rb-table/rb-table.component.html b/src/app/rb-custom-inputs/rb-table/rb-table.component.html index 6bbb804..ff94c8a 100644 --- a/src/app/rb-custom-inputs/rb-table/rb-table.component.html +++ b/src/app/rb-custom-inputs/rb-table/rb-table.component.html @@ -1,5 +1,5 @@ -
- +
+
diff --git a/src/app/rb-custom-inputs/rb-table/rb-table.component.scss b/src/app/rb-custom-inputs/rb-table/rb-table.component.scss index c1b1e0a..57f52f6 100644 --- a/src/app/rb-custom-inputs/rb-table/rb-table.component.scss +++ b/src/app/rb-custom-inputs/rb-table/rb-table.component.scss @@ -1,6 +1,6 @@ @import "~@inst-iot/bosch-angular-ui-components/styles/variables/colors"; -.table-wrapper { +.table-wrapper.scroll-top { overflow-x: auto; width: 100%; @@ -20,10 +20,6 @@ table { ::ng-deep td, ::ng-deep th { padding: 8px 5px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - max-width: 200px; } ::ng-deep th { @@ -32,4 +28,11 @@ table { } } - +table.ellipsis { + ::ng-deep td, ::ng-deep th { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + max-width: 200px; + } +} diff --git a/src/app/rb-custom-inputs/rb-table/rb-table.component.ts b/src/app/rb-custom-inputs/rb-table/rb-table.component.ts index 67e4f68..d9fc915 100644 --- a/src/app/rb-custom-inputs/rb-table/rb-table.component.ts +++ b/src/app/rb-custom-inputs/rb-table/rb-table.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import {Component, Input, OnInit} from '@angular/core'; @Component({ // tslint:disable-next-line:component-selector @@ -8,6 +8,9 @@ import { Component, OnInit } from '@angular/core'; }) export class RbTableComponent implements OnInit { + @Input() scrollTop; + @Input() ellipsis; + constructor() { } ngOnInit(): void { diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html index 017fa35..587b890 100644 --- a/src/app/sample/sample.component.html +++ b/src/app/sample/sample.component.html @@ -8,7 +8,8 @@ + [appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true" + title="trade name of the material, eg. Ultradur B4300 G6"> Cannot be empty Unknown material, add properties for new material @@ -22,14 +23,16 @@ [rbFormInputAutocomplete]="autocomplete.bind(this, d.arr.materialSuppliers)" [rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required [(ngModel)]="material.supplier" #supplierInput="ngModel" - (focusout)="checkTypo($event, 'materialSuppliers', 'supplier', modalWarning)"> + (focusout)="checkTypo($event, 'materialSuppliers', 'supplier', modalWarning)" + title="material supplier, eg. BASF"> {{supplierInput.errors.failure}}
+ (focusout)="checkTypo($event, 'materialGroups', 'group', modalWarning)" + title="chemical material type, eg. PA66"> {{groupInput.errors.failure}} @@ -41,9 +44,9 @@ + [ngModel]="item.value" title="Bosch material part number, eg. 5515753021">
- @@ -57,18 +60,19 @@
- - - - + + + Cannot be empty + #colorInput="ngModel" title="sample color, eg. black"> {{colorInput.errors.failure}} Cannot be empty - + {{batchInput.errors.failure}}
@@ -76,7 +80,8 @@
+ [(ngModel)]="sample.notes.comment" #commentInput="ngModel" + title="general remarks that cannot be expressed in additional properties, eg. stabilized"> {{commentInput.errors.failure}}
Sample references
@@ -85,12 +90,13 @@ + (ngModelChange)="checkSampleReference($event, i)" [ngModel]="reference[0]" ngModel + title="sample number of the referenced sample, eg. An31"> Unknown sample number
+ [(ngModel)]="reference[1]" title="description how the samples are connected, eg. belongs to"> Cannot be empty @@ -102,12 +108,12 @@ + [ngModel]="item.value[0]" #keyInput="ngModel" title="name of additional property, eg. vwz"> {{keyInput.errors.failure}} + [ngModel]="item.value[1]" title="value of additional property, eg. 0 min"> Cannot be empty @@ -121,7 +127,8 @@ + rbNumberConverter rbMin="1" [(ngModel)]="sampleCount" class="sample-count" + title="number of samples to create with this base information"> Cannot be empty Must be at least 1 diff --git a/src/app/samples/samples.component.html b/src/app/samples/samples.component.html index 5c6acf2..69a14f9 100644 --- a/src/app/samples/samples.component.html +++ b/src/app/samples/samples.component.html @@ -127,7 +127,7 @@ - + all @@ -213,7 +213,7 @@ Comment{{sampleDetailsSample.notes.comment | exists}} {{customField[0]}} - {{customField[0]}} + {{customField[1]}} {{reference.relation}} @@ -223,6 +223,10 @@ + + {{conditionField[0]}} + {{conditionField[1]}} + {{measurement.name}} {{measurement.value}} diff --git a/src/app/samples/samples.component.ts b/src/app/samples/samples.component.ts index db184fe..51f3fbb 100644 --- a/src/app/samples/samples.component.ts +++ b/src/app/samples/samples.component.ts @@ -3,6 +3,7 @@ import {ApiService} from '../services/api.service'; import {AutocompleteService} from '../services/autocomplete.service'; import cloneDeep from 'lodash/cloneDeep'; import pick from 'lodash/pick'; +import omit from 'lodash/omit'; import {SampleModel} from '../models/sample.model'; import {LoginService} from '../services/login.service'; import {ModalService} from '@inst-iot/bosch-angular-ui-components'; @@ -27,7 +28,7 @@ interface KeyInterface { styleUrls: ['./samples.component.scss'] }) - +// TODO: save last settings export class SamplesComponent implements OnInit { @@ -65,7 +66,7 @@ export class SamplesComponent implements OnInit { loadSamplesQueue = []; // arguments of queued up loadSamples() calls keys: KeyInterface[] = [ {id: 'number', label: 'Number', active: true, sortable: true}, - {id: 'material.numbers', label: 'Material numbers', active: true, sortable: false}, + {id: 'material.numbers', label: 'Material numbers', active: false, sortable: false}, {id: 'material.name', label: 'Material name', active: true, sortable: true}, {id: 'material.supplier', label: 'Supplier', active: true, sortable: true}, {id: 'material.group', label: 'Material', active: false, sortable: true}, @@ -105,6 +106,7 @@ export class SamplesComponent implements OnInit { this.filters.filters.find(e => e.field === 'material.group').autocomplete = this.d.arr.materialGroups; }); this.d.load('userKey'); + this.d.load('conditionTemplates'); this.loadTemplateKeys('material', 'type'); this.loadTemplateKeys('measurement', 'status'); } @@ -284,7 +286,6 @@ export class SamplesComponent implements OnInit { }); } - // TODO: add measurements when ressource service is done sampleDetails(id: string, modal: TemplateRef) { this.sampleDetailsSample = null; this.api.get('/sample/' + id, data => { @@ -295,11 +296,21 @@ export class SamplesComponent implements OnInit { else { this.sampleDetailsSample.custom_fields_entries = []; } + if (Object.keys(data.condition).length) { + this.sampleDetailsSample.condition_entries = Object.entries(omit(this.sampleDetailsSample.condition, ['condition_template'])) + .map(e => { + e[0] = `${this.ucFirst(this.d.id.conditionTemplates[this.sampleDetailsSample.condition.condition_template].name)} ${e[0]}`; + return e; + }); + } + else { + this.sampleDetailsSample.condition_entries = []; + } this.sampleDetailsSample.measurement_entries = []; this.sampleDetailsSample.measurements.forEach(measurement => { // convert measurements for more optimized display without dpt const name = this.d.id.measurementTemplates[measurement.measurement_template].name; this.sampleDetailsSample.measurement_entries.push(...Object.entries(measurement.values).filter(e => e[0] !== 'dpt') - .map(e => ({name: this.ucFirst(name) + ' ' + this.ucFirst(e[0]), value: e[1]}))); + .map(e => ({name: this.ucFirst(name) + ' ' + e[0], value: e[1]}))); }); new Promise(resolve => { if (data.notes.sample_references.length) { // load referenced samples if available diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index 60780d9..14e6f7a 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -50,6 +50,11 @@ export class ApiService { else { const modalRef = this.modalService.openComponent(ErrorComponent); modalRef.instance.message = 'Network request failed!'; + const details = [err.error.status]; + if (err.error.details) { + details.push(err.error.details); + } + modalRef.instance.details = details; modalRef.result.then(() => { this.window.location.reload(); }); diff --git a/src/styles.scss b/src/styles.scss index 245b146..6ad32c2 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -25,10 +25,6 @@ button::-moz-focus-inner { border: 0; } -.supergraphic { - background-image: url("assets/imgs/supergraphic.svg"); -} - .clickable { cursor: pointer; }