implemented icon buttons, array input, reformatting, minor sample component improvements
This commit is contained in:
parent
4876ba3c0c
commit
a4ed8888e6
5
package-lock.json
generated
5
package-lock.json
generated
@ -12388,6 +12388,11 @@
|
|||||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"str-compare": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/str-compare/-/str-compare-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-eOaGGlccGiKhnq4Q5wmWt9z9r0Y="
|
||||||
|
},
|
||||||
"stream-browserify": {
|
"stream-browserify": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
"@angular/platform-browser-dynamic": "~9.1.7",
|
"@angular/platform-browser-dynamic": "~9.1.7",
|
||||||
"@angular/router": "~9.1.7",
|
"@angular/router": "~9.1.7",
|
||||||
"@hapi/joi": "^17.1.1",
|
"@hapi/joi": "^17.1.1",
|
||||||
"@inst-iot/bosch-angular-ui-components": "file:../Bosch-UI-Components/bosch-angular-ui-components/dist-lib/inst-iot-bosch-angular-ui-components-0.6.0.tgz",
|
"@inst-iot/bosch-angular-ui-components":
|
||||||
|
"file:../Bosch-UI-Components/bosch-angular-ui-components/dist-lib/inst-iot-bosch-angular-ui-components-0.6.0.tgz",
|
||||||
"angular-2-local-storage": "^3.0.2",
|
"angular-2-local-storage": "^3.0.2",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
"chartjs-plugin-datalabels": "^0.7.0",
|
"chartjs-plugin-datalabels": "^0.7.0",
|
||||||
@ -33,6 +34,7 @@
|
|||||||
"ng2-charts": "^2.3.2",
|
"ng2-charts": "^2.3.2",
|
||||||
"quick-score": "0.0.8",
|
"quick-score": "0.0.8",
|
||||||
"rxjs": "~6.5.5",
|
"rxjs": "~6.5.5",
|
||||||
|
"str-compare": "^0.1.2",
|
||||||
"tslib": "^1.10.0",
|
"tslib": "^1.10.0",
|
||||||
"zone.js": "~0.10.2"
|
"zone.js": "~0.10.2"
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,6 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import {ArrayInputHelperService} from './array-input-helper.service';
|
import {ArrayInputHelperService} from './array-input-helper.service';
|
||||||
|
|
||||||
// TODO: implement everywhere
|
|
||||||
|
|
||||||
@Directive({ // directive for template and input values
|
@Directive({ // directive for template and input values
|
||||||
// tslint:disable-next-line:directive-selector
|
// tslint:disable-next-line:directive-selector
|
||||||
@ -31,7 +30,7 @@ export class RbArrayInputItemDirective {
|
|||||||
export class RbArrayInputListenerDirective {
|
export class RbArrayInputListenerDirective {
|
||||||
|
|
||||||
@Input() rbArrayInputListener: string;
|
@Input() rbArrayInputListener: string;
|
||||||
@Input() index: number;
|
@Input() index;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private helperService: ArrayInputHelperService
|
private helperService: ArrayInputHelperService
|
||||||
@ -39,7 +38,6 @@ export class RbArrayInputListenerDirective {
|
|||||||
|
|
||||||
@HostListener('ngModelChange', ['$event'])
|
@HostListener('ngModelChange', ['$event'])
|
||||||
onChange(event) {
|
onChange(event) {
|
||||||
console.log(event);
|
|
||||||
this.helperService.newValue(this.rbArrayInputListener, this.index, event);
|
this.helperService.newValue(this.rbArrayInputListener, this.index, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -54,8 +52,14 @@ export class RbArrayInputListenerDirective {
|
|||||||
})
|
})
|
||||||
export class RbArrayInputComponent implements ControlValueAccessor, OnInit, AfterViewInit {
|
export class RbArrayInputComponent implements ControlValueAccessor, OnInit, AfterViewInit {
|
||||||
|
|
||||||
@Input() pushTemplate: any;
|
pushTemplate: any = '';
|
||||||
@Input() pushPath: string;
|
@Input('pushTemplate') set _pushTemplate(value) {
|
||||||
|
this.pushTemplate = value;
|
||||||
|
if (this.values.length) {
|
||||||
|
this.updateArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Input() pushPath: string = null;
|
||||||
|
|
||||||
@ContentChild(RbArrayInputItemDirective) item: RbArrayInputItemDirective;
|
@ContentChild(RbArrayInputItemDirective) item: RbArrayInputItemDirective;
|
||||||
@ContentChild(RbArrayInputListenerDirective) item2: RbArrayInputListenerDirective;
|
@ContentChild(RbArrayInputListenerDirective) item2: RbArrayInputListenerDirective;
|
||||||
@ -76,26 +80,64 @@ export class RbArrayInputComponent implements ControlValueAccessor, OnInit, Afte
|
|||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
setTimeout(() => { // needed to find reference
|
setTimeout(() => { // needed to find reference
|
||||||
this.helperService.values(this.item2.rbArrayInputListener).subscribe(data => { // action on value change
|
this.helperService.values(this.item2.rbArrayInputListener).subscribe(data => { // action on value change
|
||||||
|
// assign value
|
||||||
|
if (this.pushPath) {
|
||||||
this.values[data.index][this.pushPath] = data.value;
|
this.values[data.index][this.pushPath] = data.value;
|
||||||
console.log(this.values);
|
|
||||||
if (this.values[this.values.length - 1][this.pushPath] === '' && this.values[this.values.length - 2][this.pushPath] === '') { // remove last element if last two are empty
|
|
||||||
this.values.pop();
|
|
||||||
}
|
}
|
||||||
else if (this.values[this.values.length - 1][this.pushPath] !== '') { // add element if last one is filled
|
else {
|
||||||
this.values.push(_.cloneDeep(this.pushTemplate));
|
this.values[data.index] = data.value;
|
||||||
}
|
}
|
||||||
this.onChange(this.values.filter(e => e !== '')); // trigger ngModel with filled elements
|
console.log(111, this.values);
|
||||||
|
this.updateArray();
|
||||||
});
|
});
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateArray() {
|
||||||
|
let res;
|
||||||
|
// adjust fields if pushTemplate is specified
|
||||||
|
if (this.pushTemplate !== null) {
|
||||||
|
if (this.pushPath) {
|
||||||
|
// remove last element if last two are empty
|
||||||
|
if (this.values[this.values.length - 1][this.pushPath] === '' && this.values[this.values.length - 2][this.pushPath] === '') {
|
||||||
|
this.values.pop();
|
||||||
|
}
|
||||||
|
// add element if last all are filled
|
||||||
|
else if (this.values.filter(e => e[this.pushPath] !== '').length === this.values.length) {
|
||||||
|
this.values.push(_.cloneDeep(this.pushTemplate));
|
||||||
|
}
|
||||||
|
res = this.values.filter(e => e[this.pushPath] !== '');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// remove last element if last two are empty
|
||||||
|
if (this.values[this.values.length - 1] === '' && this.values[this.values.length - 2] === '') {
|
||||||
|
this.values.pop();
|
||||||
|
}
|
||||||
|
else if (this.values.filter(e => e !== '').length === this.values.length) { // add element if all are is filled
|
||||||
|
this.values.push(_.cloneDeep(this.pushTemplate));
|
||||||
|
}
|
||||||
|
res = this.values.filter(e => e !== '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.values = [this.values[0]];
|
||||||
|
res = this.values;
|
||||||
|
}
|
||||||
|
if (!res.length) {
|
||||||
|
res = [''];
|
||||||
|
}
|
||||||
|
this.onChange(res); // trigger ngModel with filled elements
|
||||||
|
}
|
||||||
|
|
||||||
writeValue(obj: any) { // add empty value on init
|
writeValue(obj: any) { // add empty value on init
|
||||||
this.values = obj ? obj : [];
|
this.values = obj ? obj : [];
|
||||||
if (this.values.length === 0 || this.values[0] !== '') {
|
if (this.values.length === 0 || this.values[0] !== '') {
|
||||||
console.log(this.values);
|
// add empty last field if pushTemplate is specified
|
||||||
|
if (this.pushTemplate !== null) {
|
||||||
this.values.push(_.cloneDeep(this.pushTemplate));
|
this.values.push(_.cloneDeep(this.pushTemplate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
registerOnChange(fn: any) {
|
registerOnChange(fn: any) {
|
||||||
this.onChange = fn;
|
this.onChange = fn;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
|
||||||
// TODO: apply everywhere
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
// tslint:disable-next-line:component-selector
|
// tslint:disable-next-line:component-selector
|
||||||
|
@ -6,28 +6,48 @@
|
|||||||
<!--<form #sampleForm="ngForm">-->
|
<!--<form #sampleForm="ngForm">-->
|
||||||
<div class="sample">
|
<div class="sample">
|
||||||
<div>
|
<div>
|
||||||
<rb-form-input name="materialname" label="material name" [rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" [rbDebounceTime]="0" [rbInitialOpen]="true" (keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" appValidate="stringOf" [appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true" ngModel>
|
<rb-form-input name="materialname" label="material name" [rbDebounceTime]="0" [rbInitialOpen]="true"
|
||||||
|
[rbFormInputAutocomplete]="autocomplete.bind(this, ac.materialNames)" appValidate="stringOf"
|
||||||
|
(keydown)="preventDefault($event)" (ngModelChange)="findMaterial($event)" ngModel
|
||||||
|
[appValidateArgs]="[ac.materialName]" required [(ngModel)]="material.name" [autofocus]="true">
|
||||||
<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>
|
||||||
<button class="rb-btn rb-secondary" type="button" (click)="setNewMaterial(!newMaterial)"><span class="rb-ic rb-ic-add"></span> New material</button>
|
<rb-icon-button icon="add" mode="secondary" (click)="setNewMaterial(!newMaterial)">New material</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="material shaded-container" *ngIf="newMaterial" [@inOut]>
|
<div class="material shaded-container" *ngIf="newMaterial" [@inOut]>
|
||||||
<h4>Material properties</h4>
|
<h4>Material properties</h4>
|
||||||
<rb-form-input name="supplier" label="supplier" [rbFormInputAutocomplete]="autocomplete.bind(this, suppliers)" [rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required [(ngModel)]="material.supplier" #supplierInput="ngModel">
|
<rb-form-input name="supplier" label="supplier" [rbFormInputAutocomplete]="autocomplete.bind(this, ac.supplier)"
|
||||||
|
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
||||||
|
[(ngModel)]="material.supplier" #supplierInput="ngModel"
|
||||||
|
(focusout)="checkTypo('supplier', modalWarning)">
|
||||||
<ng-template rbFormValidationMessage="failure">{{supplierInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{supplierInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-form-input name="group" label="group" [rbFormInputAutocomplete]="autocomplete.bind(this, groups)" [rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required [(ngModel)]="material.group" #groupInput="ngModel">
|
<rb-form-input name="group" label="group" [rbFormInputAutocomplete]="autocomplete.bind(this, ac.mgroup)"
|
||||||
|
[rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="string" required
|
||||||
|
[(ngModel)]="material.group" #groupInput="ngModel"
|
||||||
|
(focusout)="checkTypo('mgroup', modalWarning)">
|
||||||
<ng-template rbFormValidationMessage="failure">{{groupInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{groupInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<div class="material-numbers">
|
<ng-template #modalWarning>
|
||||||
<rb-form-input *ngFor="let ignore of [].constructor(material.numbers.length); index as i" label="material number" appValidate="string" [name]="'material.number-' + i" (keyup)="handleMaterialNumbers()" [(ngModel)]="material.numbers[i]" ngModel></rb-form-input>
|
<rb-alert alertTitle="Warning" type="warning" okBtnLabel="Use suggestion" cancelBtnLabel="Keep value">
|
||||||
</div>
|
The specified {{modalText.list}} could not be found in the list. <br>
|
||||||
<rb-form-select name="conditionSelect" label="Condition" (ngModelChange)="selectMaterialTemplate($event)" [ngModel]="material.properties.material_template">
|
Did you mean {{modalText.suggestion}}?
|
||||||
|
</rb-alert>
|
||||||
|
</ng-template>
|
||||||
|
<rb-array-input [(ngModel)]="material.numbers" name="materialNumbers" [pushTemplate]="''">
|
||||||
|
<rb-form-input *rbArrayInputItem="let item" [rbArrayInputListener]="'materialNumber'" [index]="item.i"
|
||||||
|
label="material number" appValidate="string" [name]="'materialNumber-' + item.i"
|
||||||
|
[ngModel]="item.value"></rb-form-input>
|
||||||
|
</rb-array-input>
|
||||||
|
<rb-form-select name="conditionSelect" label="Condition" (ngModelChange)="selectMaterialTemplate($event)"
|
||||||
|
[ngModel]="material.properties.material_template">
|
||||||
<option *ngFor="let m of materialTemplates" [value]="m._id">{{m.name}}</option>
|
<option *ngFor="let m of materialTemplates" [value]="m._id">{{m.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
<rb-form-input *ngFor="let parameter of materialTemplate.parameters; index as i" [name]="'materialParameter' + i" [label]="parameter.name" appValidate="string" required [(ngModel)]="material.properties[parameter.name]" #parameterInput="ngModel">
|
<rb-form-input *ngFor="let parameter of materialTemplate.parameters; index as i" [name]="'materialParameter' + i"
|
||||||
|
[label]="parameter.name" appValidate="string" required
|
||||||
|
[(ngModel)]="material.properties[parameter.name]" #parameterInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
@ -36,11 +56,13 @@
|
|||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<rb-form-input name="type" label="type" appValidate="string" required [(ngModel)]="sample.type" #typeInput="ngModel">
|
<rb-form-input name="type" label="type" appValidate="string" required [(ngModel)]="sample.type"
|
||||||
|
#typeInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{typeInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{typeInput.errors.failure}}</ng-template>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-form-input name="color" label="color" appValidate="string" required [(ngModel)]="sample.color" #colorInput="ngModel">
|
<rb-form-input name="color" label="color" appValidate="string" required [(ngModel)]="sample.color"
|
||||||
|
#colorInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{colorInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{colorInput.errors.failure}}</ng-template>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
@ -51,31 +73,43 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notes">
|
<div class="notes">
|
||||||
<rb-form-input name="comment" label="comment" appValidate="stringLength" [appValidateArgs]="[512]" [(ngModel)]="sample.notes.comment" #commentInput="ngModel">
|
<rb-form-input name="comment" label="comment" appValidate="stringLength" [appValidateArgs]="[512]"
|
||||||
|
[(ngModel)]="sample.notes.comment" #commentInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{commentInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{commentInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<h5>Sample references</h5>
|
<h5>Sample references</h5>
|
||||||
<div *ngFor="let reference of sampleReferences; index as i" class="two-col" [@inOut]>
|
<div *ngFor="let reference of sampleReferences; index as i" class="two-col" [@inOut]>
|
||||||
<div>
|
<div>
|
||||||
<rb-form-input [name]="'sr-id' + i" label="sample number" [rbFormInputAutocomplete]="sampleReferenceListBind()" [rbDebounceTime]="300" appValidate="stringOf" [appValidateArgs]="[sampleReferenceAutocomplete[i]]" (ngModelChange)="checkSampleReference($event, i)" [ngModel]="reference[0]" ngModel>
|
<rb-form-input [name]="'sr-id' + i" label="sample number" [rbFormInputAutocomplete]="sampleReferenceListBind()"
|
||||||
|
[rbDebounceTime]="300" appValidate="stringOf"
|
||||||
|
[appValidateArgs]="[sampleReferenceAutocomplete[i]]"
|
||||||
|
(ngModelChange)="checkSampleReference($event, i)" [ngModel]="reference[0]" ngModel>
|
||||||
<ng-template rbFormValidationMessage="failure">Unknown sample number</ng-template>
|
<ng-template rbFormValidationMessage="failure">Unknown sample number</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
</div>
|
</div>
|
||||||
<rb-form-input [name]="'sr-relation' + i" label="relation" appValidate="string" [required]="reference[0] !== ''" [(ngModel)]="reference[1]">
|
<rb-form-input [name]="'sr-relation' + i" label="relation" appValidate="string" [required]="reference[0] !== ''"
|
||||||
|
[(ngModel)]="reference[1]">
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
</div>
|
</div>
|
||||||
<h5>Additional properties</h5>
|
<h5>Additional properties</h5>
|
||||||
<div *ngFor="let field of customFields; index as i" class="two-col" [@inOut]>
|
<rb-array-input [(ngModel)]="customFields" name="customFields" [pushTemplate]="['', '']" pushPath="0"
|
||||||
|
class="two-col" [@inOut]>
|
||||||
|
<ng-container *rbArrayInputItem="let item">
|
||||||
<div>
|
<div>
|
||||||
<rb-form-input [name]="'cf-key' + i" label="key" [rbFormInputAutocomplete]="autocomplete.bind(this, availableCustomFields)" [rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="unique" [appValidateArgs]="[uniqueCfValues(i)]" (ngModelChange)="adjustCustomFields($event, i)" [ngModel]="field[0]" #keyInput="ngModel">
|
<rb-form-input [name]="'cf-key' + item.i" label="key" [rbArrayInputListener]="'cf-key'" [index]="item.i"
|
||||||
|
[rbFormInputAutocomplete]="autocomplete.bind(this, availableCustomFields)" [rbDebounceTime]="0"
|
||||||
|
[rbInitialOpen]="true" appValidate="unique" [appValidateArgs]="[uniqueCfValues(item.i)]"
|
||||||
|
[ngModel]="item.value[0]" #keyInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{keyInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{keyInput.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
</div>
|
</div>
|
||||||
<rb-form-input [name]="'cf-value' + i" label="value" appValidate="string" [required]="field[0] !== ''" [(ngModel)]="field[1]">
|
<rb-form-input [name]="'cf-value' + item.i" label="value" appValidate="string" [required]="item.value[0] !== ''"
|
||||||
|
[ngModel]="item.value[1]">
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
</div>
|
</ng-container>
|
||||||
|
</rb-array-input>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@ -83,14 +117,18 @@
|
|||||||
<div class="conditions shaded-container">
|
<div class="conditions shaded-container">
|
||||||
<h4>
|
<h4>
|
||||||
Condition
|
Condition
|
||||||
<button class="rb-btn rb-secondary condition-set" type="button" (click)="toggleCondition()" [disabled]="!conditionTemplates">{{condition ? 'Do not set condition' : 'Set condition'}}</button>
|
<button class="rb-btn rb-secondary condition-set" type="button" (click)="toggleCondition()"
|
||||||
|
[disabled]="!conditionTemplates">{{condition ? 'Do not set condition' : 'Set condition'}}</button>
|
||||||
</h4>
|
</h4>
|
||||||
<div *ngIf="condition" [@inOut]>
|
<div *ngIf="condition" [@inOut]>
|
||||||
<rb-form-select name="conditionSelect" label="Condition" (ngModelChange)="selectCondition($event)" [ngModel]="condition._id">
|
<rb-form-select name="conditionSelect" label="Condition" (ngModelChange)="selectCondition($event)"
|
||||||
|
[ngModel]="condition._id">
|
||||||
<option *ngFor="let c of conditionTemplates" [value]="c._id">{{c.name}}</option>
|
<option *ngFor="let c of conditionTemplates" [value]="c._id">{{c.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
|
|
||||||
<rb-form-input *ngFor="let parameter of condition.parameters; index as i" [name]="'conditionParameter' + i" [label]="parameter.name" appValidate="string" required [(ngModel)]="sample.condition[parameter.name]" #parameterInput="ngModel">
|
<rb-form-input *ngFor="let parameter of condition.parameters; index as i" [name]="'conditionParameter' + i"
|
||||||
|
[label]="parameter.name" appValidate="string" required
|
||||||
|
[(ngModel)]="sample.condition[parameter.name]" #parameterInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
@ -102,16 +140,23 @@
|
|||||||
<div class="measurements shaded-container">
|
<div class="measurements shaded-container">
|
||||||
<h4>Measurements</h4>
|
<h4>Measurements</h4>
|
||||||
<div *ngFor="let measurement of sample.measurements; index as mIndex" [@inOut]>
|
<div *ngFor="let measurement of sample.measurements; index as mIndex" [@inOut]>
|
||||||
<rb-form-select name="measurementTemplateSelect" label="Template" [(ngModel)]="measurement.measurement_template" (ngModelChange)="clearChart(mIndex)">
|
<rb-form-select name="measurementTemplateSelect" label="Template" [(ngModel)]="measurement.measurement_template"
|
||||||
|
(ngModelChange)="clearChart(mIndex)">
|
||||||
<option *ngFor="let m of measurementTemplates" [value]="m._id">{{m.name}}</option>
|
<option *ngFor="let m of measurementTemplates" [value]="m._id">{{m.name}}</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
|
|
||||||
<div *ngFor="let parameter of getMeasurementTemplate(measurement.measurement_template).parameters; index as pIndex">
|
<div *ngFor="let parameter of getMeasurementTemplate(measurement.measurement_template).parameters;
|
||||||
<rb-form-input *ngIf="!parameter.range.type" [name]="'measurementParameter' + mIndex + '-' + pIndex" [label]="parameter.name" appValidate="string" [(ngModel)]="measurement.values[parameter.name]" #parameterInput="ngModel">
|
index as pIndex">
|
||||||
|
<rb-form-input *ngIf="!parameter.range.type" [name]="'measurementParameter' + mIndex + '-' + pIndex"
|
||||||
|
[label]="parameter.name" appValidate="string" [(ngModel)]="measurement.values[parameter.name]"
|
||||||
|
#parameterInput="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-form-file *ngIf="parameter.range.type" [name]="'measurementParameter' + mIndex + '-' + pIndex" [label]="parameter.name" maxSize="10000000" (ngModelChange)="fileToArray($event, mIndex, parameter.name)" placeholder="Select file or drag and drop" dragDrop required ngModel>
|
<rb-form-file *ngIf="parameter.range.type" [name]="'measurementParameter' + mIndex + '-' + pIndex"
|
||||||
|
[label]="parameter.name" maxSize="10000000" multiple
|
||||||
|
(ngModelChange)="fileToArray($event, mIndex, parameter.name)"
|
||||||
|
placeholder="Select file or drag and drop" dragDrop required ngModel>
|
||||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||||
</rb-form-file>
|
</rb-form-file>
|
||||||
<canvas baseChart *ngIf="parameter.range.type && charts[mIndex][0].data.length > 0" class="dpt-chart" [@inOut]
|
<canvas baseChart *ngIf="parameter.range.type && charts[mIndex][0].data.length > 0" class="dpt-chart" [@inOut]
|
||||||
@ -122,20 +167,26 @@
|
|||||||
chartType="scatter">
|
chartType="scatter">
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
<rb-icon-button icon="delete" mode="danger" (click)="removeMeasurement(mIndex)"
|
||||||
<button class="rb-btn rb-danger" type="button" (click)="removeMeasurement(mIndex)"><span class="rb-ic rb-ic-delete"></span> Delete measurement</button>
|
[disabled]="!measurementTemplates">
|
||||||
|
Delete measurement
|
||||||
|
</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="rb-btn rb-secondary" type="button" (click)="addMeasurement()" [disabled]="!measurementTemplates"><span class="rb-ic rb-ic-add"></span> New measurement</button>
|
<rb-icon-button icon="add" mode="secondary" (click)="addMeasurement()" [disabled]="!measurementTemplates">
|
||||||
|
New measurement
|
||||||
|
</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button class="rb-btn rb-primary" type="submit" (click)="saveSample()" [disabled]="!sampleForm.form.valid">Save sample</button>
|
<button class="rb-btn rb-primary" type="submit" (click)="saveSample()" [disabled]="!sampleForm.form.valid">
|
||||||
|
Save sample
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// import { SampleComponent } from './sample.component';
|
// import { SampleComponent } from './sample.component';
|
||||||
//
|
//
|
||||||
// // TODO
|
// // TODO: tests
|
||||||
//
|
//
|
||||||
// describe('SampleComponent', () => {
|
// describe('SampleComponent', () => {
|
||||||
// let component: SampleComponent;
|
// let component: SampleComponent;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import strCompare from 'str-compare';
|
||||||
import {
|
import {
|
||||||
AfterContentChecked,
|
AfterContentChecked,
|
||||||
Component,
|
Component,
|
||||||
OnInit,
|
OnInit, TemplateRef,
|
||||||
ViewChild
|
ViewChild
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
@ -17,18 +18,14 @@ import {MeasurementModel} from '../models/measurement.model';
|
|||||||
import { ChartOptions } from 'chart.js';
|
import { ChartOptions } from 'chart.js';
|
||||||
import {animate, style, transition, trigger} from '@angular/animations';
|
import {animate, style, transition, trigger} from '@angular/animations';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
|
import {ModalService} from '@inst-iot/bosch-angular-ui-components';
|
||||||
|
import {UserModel} from '../models/user.model';
|
||||||
|
|
||||||
|
|
||||||
// TODO: tests
|
|
||||||
// TODO: confirmation for new group/supplier
|
|
||||||
// TODO: work on better recognition for file input
|
// TODO: work on better recognition for file input
|
||||||
// TODO: only show condition (if not set) and measurements in edit sample dialog at first
|
// TODO: only show condition (if not set) and measurements in edit sample dialog at first
|
||||||
// TODO: multiple spectra
|
|
||||||
// TODO: multiple samples for base data, extend multiple measurements, conditions
|
// TODO: multiple samples for base data, extend multiple measurements, conditions
|
||||||
|
|
||||||
// TODO: material properties, color (in material and sample (not required))
|
|
||||||
|
|
||||||
// TODO: device autocomplete
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-sample',
|
selector: 'app-sample',
|
||||||
templateUrl: './sample.component.html',
|
templateUrl: './sample.component.html',
|
||||||
@ -55,16 +52,18 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
new; // true if new sample should be created
|
new; // true if new sample should be created
|
||||||
newMaterial = false; // true if new material should be created
|
newMaterial = false; // true if new material should be created
|
||||||
materials: MaterialModel[] = []; // all materials
|
materials: MaterialModel[] = []; // all materials
|
||||||
suppliers: string[] = []; // all suppliers
|
ac: {[group: string]: string[]} = { // autocomplete data
|
||||||
groups: string[] = []; // all groups
|
supplier: [],
|
||||||
|
group: [],
|
||||||
|
materialName: []
|
||||||
|
};
|
||||||
conditionTemplates: TemplateModel[]; // all conditions
|
conditionTemplates: TemplateModel[]; // all conditions
|
||||||
condition: TemplateModel | null = null; // selected condition
|
condition: TemplateModel | null = null; // selected condition
|
||||||
materialTemplates: TemplateModel[]; // all material templates
|
materialTemplates: TemplateModel[]; // all material templates
|
||||||
materialTemplate: TemplateModel | null = null; // selected material template
|
materialTemplate: TemplateModel | null = null; // selected material template
|
||||||
materialNames = []; // names of all materials
|
|
||||||
material = new MaterialModel(); // object of current selected material
|
material = new MaterialModel(); // object of current selected material
|
||||||
sample = new SampleModel();
|
sample = new SampleModel();
|
||||||
customFields: [string, string][] = [['', '']];
|
customFields: [string, string][];
|
||||||
sampleReferences: [string, string, string][] = [['', '', '']];
|
sampleReferences: [string, string, string][] = [['', '', '']];
|
||||||
sampleReferenceFinds: {_id: string, number: string}[] = []; // raw sample reference data from db
|
sampleReferenceFinds: {_id: string, number: string}[] = []; // raw sample reference data from db
|
||||||
currentSRIndex = 0; // index of last entered sample reference
|
currentSRIndex = 0; // index of last entered sample reference
|
||||||
@ -74,7 +73,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
measurementTemplates: TemplateModel[];
|
measurementTemplates: TemplateModel[];
|
||||||
loading = 0; // number of currently loading instances
|
loading = 0; // number of currently loading instances
|
||||||
checkFormAfterInit = false;
|
checkFormAfterInit = false;
|
||||||
charts = []; // chart data for spectrums
|
modalText = {list: '', suggestion: ''};
|
||||||
|
charts = []; // chart data for spectra
|
||||||
|
defaultDevice = '';
|
||||||
readonly chartInit = [{
|
readonly chartInit = [{
|
||||||
data: [],
|
data: [],
|
||||||
label: 'Spectrum',
|
label: 'Spectrum',
|
||||||
@ -101,7 +102,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private api: ApiService,
|
private api: ApiService,
|
||||||
private validation: ValidationService,
|
private validation: ValidationService,
|
||||||
public autocomplete: AutocompleteService
|
public autocomplete: AutocompleteService,
|
||||||
|
private modal: ModalService
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -109,15 +111,15 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.loading = 7;
|
this.loading = 7;
|
||||||
this.api.get<MaterialModel[]>('/materials?status=all', (data: any) => {
|
this.api.get<MaterialModel[]>('/materials?status=all', (data: any) => {
|
||||||
this.materials = data.map(e => new MaterialModel().deserialize(e));
|
this.materials = data.map(e => new MaterialModel().deserialize(e));
|
||||||
this.materialNames = data.map(e => e.name);
|
this.ac.materialName = data.map(e => e.name);
|
||||||
this.loading--;
|
this.loading--;
|
||||||
});
|
});
|
||||||
this.api.get<string[]>('/material/suppliers', (data: any) => {
|
this.api.get<string[]>('/material/suppliers', (data: any) => {
|
||||||
this.suppliers = data;
|
this.ac.supplier = data;
|
||||||
this.loading--;
|
this.loading--;
|
||||||
});
|
});
|
||||||
this.api.get<string[]>('/material/groups', (data: any) => {
|
this.api.get<string[]>('/material/groups', (data: any) => {
|
||||||
this.groups = data;
|
this.ac.mgroup = data;
|
||||||
this.loading--;
|
this.loading--;
|
||||||
});
|
});
|
||||||
this.api.get<TemplateModel[]>('/template/conditions', data => {
|
this.api.get<TemplateModel[]>('/template/conditions', data => {
|
||||||
@ -129,6 +131,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.selectMaterialTemplate(this.materialTemplates[0]._id);
|
this.selectMaterialTemplate(this.materialTemplates[0]._id);
|
||||||
this.loading--;
|
this.loading--;
|
||||||
});
|
});
|
||||||
|
this.api.get<UserModel>('/user', data => {
|
||||||
|
this.defaultDevice = data.device_name;
|
||||||
|
});
|
||||||
this.api.get<TemplateModel[]>('/template/measurements', data => {
|
this.api.get<TemplateModel[]>('/template/measurements', data => {
|
||||||
this.measurementTemplates = data.map(e => new TemplateModel().deserialize(e));
|
this.measurementTemplates = data.map(e => new TemplateModel().deserialize(e));
|
||||||
if (!this.new) {
|
if (!this.new) {
|
||||||
@ -149,7 +154,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.material = sData.material;
|
this.material = sData.material;
|
||||||
this.customFields = this.sample.notes.custom_fields && this.sample.notes.custom_fields !== {} ? Object.keys(this.sample.notes.custom_fields).map(e => [e, this.sample.notes.custom_fields[e]]) : [['', '']];
|
this.customFields = this.sample.notes.custom_fields && this.sample.notes.custom_fields !== {} ?
|
||||||
|
Object.keys(this.sample.notes.custom_fields).map(e => [e, this.sample.notes.custom_fields[e]]) : [['', '']];
|
||||||
if (this.sample.notes.sample_references.length) {
|
if (this.sample.notes.sample_references.length) {
|
||||||
this.sampleReferences = [];
|
this.sampleReferences = [];
|
||||||
this.sampleReferenceAutocomplete = [];
|
this.sampleReferenceAutocomplete = [];
|
||||||
@ -185,7 +191,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
|
|
||||||
ngAfterContentChecked() {
|
ngAfterContentChecked() {
|
||||||
// attach validators to dynamic condition fields when all values are available and template was fully created
|
// attach validators to dynamic condition fields when all values are available and template was fully created
|
||||||
if (this.condition && this.condition.hasOwnProperty('parameters') && this.condition.parameters.length > 0 && this.condition.parameters[0].hasOwnProperty('range') && this.sampleForm && this.sampleForm.form.get('conditionParameter0')) {
|
if (this.condition && this.condition.hasOwnProperty('parameters') && this.condition.parameters.length > 0 &&
|
||||||
|
this.condition.parameters[0].hasOwnProperty('range') && this.sampleForm && this.sampleForm.form.get('conditionParameter0')) {
|
||||||
for (const i in this.condition.parameters) {
|
for (const i in this.condition.parameters) {
|
||||||
if (this.condition.parameters[i]) {
|
if (this.condition.parameters[i]) {
|
||||||
this.attachValidator('conditionParameter' + i, this.condition.parameters[i].range, true);
|
this.attachValidator('conditionParameter' + i, this.condition.parameters[i].range, true);
|
||||||
@ -194,7 +201,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// attach validators to dynamic material fields when all values are available and template was fully created
|
// attach validators to dynamic material fields when all values are available and template was fully created
|
||||||
if (this.materialTemplate && this.materialTemplate.hasOwnProperty('parameters') && this.materialTemplate.parameters.length > 0 && this.materialTemplate.parameters[0].hasOwnProperty('range') && this.sampleForm && this.sampleForm.form.get('materialParameter0')) {
|
if (this.materialTemplate && this.materialTemplate.hasOwnProperty('parameters') && this.materialTemplate.parameters.length > 0 &&
|
||||||
|
this.materialTemplate.parameters[0].hasOwnProperty('range') && this.sampleForm && this.sampleForm.form.get('materialParameter0')) {
|
||||||
for (const i in this.materialTemplate.parameters) {
|
for (const i in this.materialTemplate.parameters) {
|
||||||
if (this.materialTemplate.parameters[i]) {
|
if (this.materialTemplate.parameters[i]) {
|
||||||
this.attachValidator('materialParameter' + i, this.materialTemplate.parameters[i].range, true);
|
this.attachValidator('materialParameter' + i, this.materialTemplate.parameters[i].range, true);
|
||||||
@ -250,7 +258,6 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
saveSample() {
|
saveSample() {
|
||||||
new Promise<void>(resolve => {
|
new Promise<void>(resolve => {
|
||||||
if (this.newMaterial) { // save material first if new one exists
|
if (this.newMaterial) { // save material first if new one exists
|
||||||
this.material.numbers = this.material.numbers.filter(e => e !== '');
|
|
||||||
this.api.post<MaterialModel>('/material/new', this.material.sendFormat(), data => {
|
this.api.post<MaterialModel>('/material/new', this.material.sendFormat(), data => {
|
||||||
this.materials.push(data); // add material to data
|
this.materials.push(data); // add material to data
|
||||||
this.material = data;
|
this.material = data;
|
||||||
@ -268,7 +275,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.sample.notes.custom_fields[element[0]] = element[1];
|
this.sample.notes.custom_fields[element[0]] = element[1];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.sample.notes.sample_references = this.sampleReferences.filter(e => e[0] && e[1] && e[2]).map(e => ({sample_id: e[2], relation: e[1]}));
|
this.sample.notes.sample_references = this.sampleReferences
|
||||||
|
.filter(e => e[0] && e[1] && e[2])
|
||||||
|
.map(e => ({sample_id: e[2], relation: e[1]}));
|
||||||
new Promise<SampleModel>(resolve => {
|
new Promise<SampleModel>(resolve => {
|
||||||
if (this.new) {
|
if (this.new) {
|
||||||
this.api.post<SampleModel>('/sample/new', this.sample.sendFormat(), resolve);
|
this.api.post<SampleModel>('/sample/new', this.sample.sendFormat(), resolve);
|
||||||
@ -289,7 +298,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.api.post<MeasurementModel>('/measurement/new', measurement.sendFormat());
|
this.api.post<MeasurementModel>('/measurement/new', measurement.sendFormat());
|
||||||
}
|
}
|
||||||
else { // update measurement
|
else { // update measurement
|
||||||
this.api.put<MeasurementModel>('/measurement/' + measurement._id, measurement.sendFormat(['sample_id', 'measurement_template']));
|
this.api.put<MeasurementModel>('/measurement/' + measurement._id,
|
||||||
|
measurement.sendFormat(['sample_id', 'measurement_template']));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (measurement._id !== null) { // existing measurement was left empty to delete
|
else if (measurement._id !== null) { // existing measurement was left empty to delete
|
||||||
@ -321,7 +331,6 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: rework later
|
|
||||||
setNewMaterial(value = null) {
|
setNewMaterial(value = null) {
|
||||||
if (value === null) {
|
if (value === null) {
|
||||||
this.newMaterial = !this.sample.material_id;
|
this.newMaterial = !this.sample.material_id;
|
||||||
@ -333,24 +342,12 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.sampleForm.form.get('materialname').setValidators([Validators.required]);
|
this.sampleForm.form.get('materialname').setValidators([Validators.required]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.sampleForm.form.get('materialname').setValidators([Validators.required, this.validation.generate('stringOf', [this.materialNames])]);
|
this.sampleForm.form.get('materialname')
|
||||||
|
.setValidators([Validators.required, this.validation.generate('stringOf', [this.ac.materialName])]);
|
||||||
}
|
}
|
||||||
this.sampleForm.form.get('materialname').updateValueAndValidity();
|
this.sampleForm.form.get('materialname').updateValueAndValidity();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMaterialNumbers() {
|
|
||||||
const fieldNo = this.material.numbers.length;
|
|
||||||
const filledFields = this.material.numbers.filter(e => e !== '').length;
|
|
||||||
// append new field
|
|
||||||
if (filledFields === fieldNo) {
|
|
||||||
this.material.numbers.push('');
|
|
||||||
}
|
|
||||||
// remove if two end fields are empty
|
|
||||||
if (fieldNo > 1 && this.material.numbers[fieldNo - 1] === '' && this.material.numbers[fieldNo - 2] === '') {
|
|
||||||
this.material.numbers.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectCondition(id) {
|
selectCondition(id) {
|
||||||
this.condition = this.conditionTemplates.find(e => e._id === id);
|
this.condition = this.conditionTemplates.find(e => e._id === id);
|
||||||
console.log(this.condition);
|
console.log(this.condition);
|
||||||
@ -372,7 +369,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMeasurement() {
|
addMeasurement() {
|
||||||
this.sample.measurements.push(new MeasurementModel(this.measurementTemplates[0]._id));
|
this.sample.measurements.push(new MeasurementModel(this.measurementTemplates.filter(e => e.name === 'spectrum').reverse()[0]._id));
|
||||||
|
this.sample.measurements[this.sample.measurements.length - 1].values.device = this.defaultDevice;
|
||||||
this.charts.push(_.cloneDeep(this.chartInit));
|
this.charts.push(_.cloneDeep(this.chartInit));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,12 +387,22 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileToArray(files, mIndex, parameter) {
|
fileToArray(files, mIndex, parameter) {
|
||||||
|
for (const i in files) {
|
||||||
|
if (files.hasOwnProperty(i)) {
|
||||||
const fileReader = new FileReader();
|
const fileReader = new FileReader();
|
||||||
fileReader.onload = () => {
|
fileReader.onload = () => {
|
||||||
this.sample.measurements[mIndex].values[parameter] = fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
let index: number = mIndex;
|
||||||
this.generateChart(this.sample.measurements[mIndex].values[parameter], mIndex);
|
if (Number(i) > 0) { // append further spectra
|
||||||
|
this.addMeasurement();
|
||||||
|
index = this.sample.measurements.length - 1;
|
||||||
|
}
|
||||||
|
this.sample.measurements[index].values[parameter] =
|
||||||
|
fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
||||||
|
this.generateChart(this.sample.measurements[index].values[parameter], index);
|
||||||
};
|
};
|
||||||
fileReader.readAsText(files[0]);
|
fileReader.readAsText(files[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateChart(spectrum, index) {
|
generateChart(spectrum, index) {
|
||||||
@ -411,22 +419,17 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustCustomFields(value, index) {
|
checkTypo(list, modal: TemplateRef<any>) {
|
||||||
this.customFields[index][0] = value;
|
if (this.ac[list].indexOf(this.material[list]) < 0) { // entry is not in lise
|
||||||
const fieldNo = this.customFields.length;
|
this.modalText.list = list;
|
||||||
let filledFields = 0;
|
this.modalText.suggestion = this.ac[list] // find possible entry from list
|
||||||
this.customFields.forEach(field => {
|
.map(e => ({v: e, s: strCompare.sorensenDice(e, this.material[list])}))
|
||||||
if (field[0] !== '') {
|
.sort((a, b) => b.s - a.s)[0].v;
|
||||||
filledFields ++;
|
this.modal.open(modal).then(result => {
|
||||||
|
if (result) { // use suggestion
|
||||||
|
this.material[list] = this.modalText.suggestion;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// append new field
|
|
||||||
if (filledFields === fieldNo) {
|
|
||||||
this.customFields.push(['', '']);
|
|
||||||
}
|
|
||||||
// remove if two end fields are empty
|
|
||||||
if (fieldNo > 1 && this.customFields[fieldNo - 1][0] === '' && this.customFields[fieldNo - 2][0] === '') {
|
|
||||||
this.customFields.pop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,7 +460,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
|
|
||||||
sampleReferenceList(value) {
|
sampleReferenceList(value) {
|
||||||
return new Observable(observer => {
|
return new Observable(observer => {
|
||||||
this.api.get<{_id: string, number: string}[]>('/samples?status=all&page-size=25&sort=number-asc&fields[]=number&fields[]=_id&filters[]=%7B%22mode%22%3A%22stringin%22%2C%22field%22%3A%22number%22%2C%22values%22%3A%5B%22' + value + '%22%5D%7D', data => {
|
this.api.get<{_id: string, number: string}[]>(
|
||||||
|
'/samples?status=all&page-size=25&sort=number-asc&fields[]=number&fields[]=_id&' +
|
||||||
|
'filters[]=%7B%22mode%22%3A%22stringin%22%2C%22field%22%3A%22number%22%2C%22values%22%3A%5B%22' + value + '%22%5D%7D', data => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
this.sampleReferenceAutocomplete[this.currentSRIndex] = data.map(e => e.number);
|
this.sampleReferenceAutocomplete[this.currentSRIndex] = data.map(e => e.number);
|
||||||
this.sampleReferenceFinds = data;
|
this.sampleReferenceFinds = data;
|
||||||
@ -483,12 +488,14 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uniqueCfValues(index) { // returns all names until index for unique check
|
uniqueCfValues(index) { // returns all names until index for unique check
|
||||||
return this.customFields.slice(0, index).map(e => e[0]);
|
return this.customFields ? this.customFields.slice(0, index).map(e => e[0]) : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 1. ngAfterViewInit wird ja jedes mal nach einem ngOnChanges aufgerufen, also zB wenn sich dein ngFor aufbaut. Du könntest also in der Methode prüfen, ob die Daten schon da sind und dann dementsprechend handeln. Das wäre die Eleganteste Variante
|
// 1. ngAfterViewInit wird ja jedes mal nach einem ngOnChanges aufgerufen, also zB wenn sich dein ngFor aufbaut. Du könntest also in der
|
||||||
|
// Methode prüfen, ob die Daten schon da sind und dann dementsprechend handeln. Das wäre die Eleganteste Variante
|
||||||
// 2. Der state "dirty" soll eigentlich anzeigen, wenn ein Form-Field vom User geändert wurde; damit missbrauchst du es hier etwas
|
// 2. Der state "dirty" soll eigentlich anzeigen, wenn ein Form-Field vom User geändert wurde; damit missbrauchst du es hier etwas
|
||||||
// 3. Die Dirty-Variante: Pack in deine ngFor ein {{ onFirstLoad(data) }} rein, das einfach ausgeführt wird. müsstest dann natürlich abfangen, dass das nicht nach jedem view-cycle neu getriggert wird. Schön ist das nicht, aber besser als mit Timeouts^^
|
// 3. Die Dirty-Variante: Pack in deine ngFor ein {{ onFirstLoad(data) }} rein, das einfach ausgeführt wird. müsstest dann natürlich
|
||||||
|
// abfangen, dass das nicht nach jedem view-cycle neu getriggert wird. Schön ist das nicht, aber besser als mit Timeouts^^
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="header-addnew">
|
<div class="header-addnew">
|
||||||
<h2>Samples</h2>
|
<h2>Samples</h2>
|
||||||
<a routerLink="/samples/new">
|
<a routerLink="/samples/new">
|
||||||
<button class="rb-btn rb-primary"><span class="rb-ic rb-ic-add"></span> New sample</button>
|
<rb-icon-button icon="add" mode="primary">New sample</rb-icon-button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -12,14 +12,17 @@
|
|||||||
<form class="filters">
|
<form class="filters">
|
||||||
<div class="status-selection">
|
<div class="status-selection">
|
||||||
<label class="label">Status</label>
|
<label class="label">Status</label>
|
||||||
<rb-form-checkbox name="status-validated" [(ngModel)]="filters.status.validated" [disabled]="!filters.status.new" (ngModelChange)="loadSamples({firstPage: true})">
|
<rb-form-checkbox name="status-validated" [(ngModel)]="filters.status.validated"
|
||||||
|
[disabled]="!filters.status.new" (ngModelChange)="loadSamples({firstPage: true})">
|
||||||
validated
|
validated
|
||||||
</rb-form-checkbox>
|
</rb-form-checkbox>
|
||||||
<rb-form-checkbox name="status-new" [(ngModel)]="filters.status.new" [disabled]="!filters.status.validated" (ngModelChange)="loadSamples({firstPage: true})">
|
<rb-form-checkbox name="status-new" [(ngModel)]="filters.status.new" [disabled]="!filters.status.validated"
|
||||||
|
(ngModelChange)="loadSamples({firstPage: true})">
|
||||||
new
|
new
|
||||||
</rb-form-checkbox>
|
</rb-form-checkbox>
|
||||||
</div>
|
</div>
|
||||||
<rb-form-select name="pageSizeSelection" label="page size" [(ngModel)]="filters.pageSize" class="selection" (ngModelChange)="loadSamples({firstPage: true})" #pageSizeSelection>
|
<rb-form-select name="pageSizeSelection" label="page size" [(ngModel)]="filters.pageSize" class="selection"
|
||||||
|
(ngModelChange)="loadSamples({firstPage: true})" #pageSizeSelection>
|
||||||
<option value="3">3</option>
|
<option value="3">3</option>
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
<option value="25">25</option>
|
<option value="25">25</option>
|
||||||
@ -29,15 +32,18 @@
|
|||||||
<option value="500">500</option>
|
<option value="500">500</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
|
|
||||||
<rb-form-multi-select name="fieldSelect" idField="id" [items]="keys" [(ngModel)]="isActiveKey" label="Fields" class="selection" (ngModelChange)="loadSamples({}, $event)">
|
<rb-form-multi-select name="fieldSelect" idField="id" [items]="keys" [(ngModel)]="isActiveKey" label="Fields"
|
||||||
|
class="selection" (ngModelChange)="loadSamples({}, $event)">
|
||||||
<span *rbFormMultiSelectOption="let item" class="load-first-page">{{item.label}}</span>
|
<span *rbFormMultiSelectOption="let item" class="load-first-page">{{item.label}}</span>
|
||||||
</rb-form-multi-select>
|
</rb-form-multi-select>
|
||||||
|
|
||||||
<div class="fieldfilters">
|
<div class="fieldfilters">
|
||||||
<div *ngFor="let filter of filters.filters">
|
<div *ngFor="let filter of filters.filters">
|
||||||
<ng-container *ngIf="isActiveKey[filter.field]">
|
<ng-container *ngIf="isActiveKey[filter.field]">
|
||||||
<rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active" (ngModelChange)="loadSamples({firstPage: true})"></rb-form-checkbox>
|
<rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active"
|
||||||
<rb-form-select [name]="'filtermode-' + filter.field" class="filtermode" [(ngModel)]="filter.mode" (ngModelChange)="updateFilterFields(filter.field)">
|
(ngModelChange)="loadSamples({firstPage: true})"></rb-form-checkbox>
|
||||||
|
<rb-form-select [name]="'filtermode-' + filter.field" class="filtermode" [(ngModel)]="filter.mode"
|
||||||
|
(ngModelChange)="updateFilterFields(filter.field)">
|
||||||
<option value="eq" title="field is equal to value">=</option>
|
<option value="eq" title="field is equal to value">=</option>
|
||||||
<option value="ne" title="field is not equal to value">≠</option>
|
<option value="ne" title="field is not equal to value">≠</option>
|
||||||
<option value="lt" title="field is lower than value"><</option>
|
<option value="lt" title="field is lower than value"><</option>
|
||||||
@ -49,13 +55,26 @@
|
|||||||
<option value="nin" title="field is not one of the values">∉</option>
|
<option value="nin" title="field is not one of the values">∉</option>
|
||||||
</rb-form-select>
|
</rb-form-select>
|
||||||
<div class="filter-inputs">
|
<div class="filter-inputs">
|
||||||
<ng-container *ngFor="let ignore of [].constructor(filter.values.length); index as i">
|
<rb-array-input [(ngModel)]="filter.values" [name]="'filter-' + filter.field"
|
||||||
<rb-form-date-input *ngIf="filter.field === 'added'; else noDate" [name]="'filter-' + filter.field + i" [label]="filter.label" [(ngModel)]="filter.values[i]" (ngModelChange)="updateFilterFields(filter.field)"></rb-form-date-input>
|
[pushTemplate]="!(filter.mode === 'in' || filter.mode === 'nin') ? null :''"
|
||||||
<ng-template #noDate>
|
(ngModelChange)="updateFilterFields(filter.field)">
|
||||||
<rb-form-input *ngIf="!filter.autocomplete.length" [name]="'filter-' + filter.field + i" [label]="filter.label" [(ngModel)]="filter.values[i]" (ngModelChange)="updateFilterFields(filter.field)"></rb-form-input>
|
<ng-container *rbArrayInputItem="let item"
|
||||||
<rb-form-input *ngIf="filter.autocomplete.length" [name]="'filter-' + filter.field + i" [label]="filter.label" [rbFormInputAutocomplete]="autocomplete.bind(this, filter.autocomplete)" [rbDebounceTime]="0" (keydown)="preventDefault($event, 'Enter')" [(ngModel)]="filter.values[i]" (ngModelChange)="updateFilterFields(filter.field)" ngModel></rb-form-input>
|
[ngSwitch]="(filter.autocomplete.length ? 'autocomplete' : '') +
|
||||||
</ng-template>
|
(filter.field == 'added' ? 'date' : '')">
|
||||||
|
<rb-form-date-input *ngSwitchCase="'date'" [rbArrayInputListener]="'filter-' + filter.field"
|
||||||
|
[name]="'filter-' + filter.field + item.i" [index]="item.i"
|
||||||
|
[label]="filter.label" [(ngModel)]="item.value"></rb-form-date-input>
|
||||||
|
<rb-form-input *ngSwitchCase="''" [rbArrayInputListener]="'filter-' + filter.field"
|
||||||
|
[name]="'filter-' + filter.field + item.i" [index]="item.i"
|
||||||
|
[label]="filter.label" [(ngModel)]="item.value"></rb-form-input>
|
||||||
|
<rb-form-input *ngSwitchCase="'autocomplete'" [rbArrayInputListener]="'filter-' + filter.field"
|
||||||
|
[name]="'filter-' + filter.field + item.i" [index]="item.i"
|
||||||
|
[label]="filter.label" [(ngModel)]="item.value"
|
||||||
|
[rbDebounceTime]="0" (keydown)="preventDefault($event, 'Enter')"
|
||||||
|
[rbFormInputAutocomplete]="autocomplete.bind(this, filter.autocomplete)"
|
||||||
|
ngModel></rb-form-input>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
</rb-array-input>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
@ -68,18 +87,20 @@
|
|||||||
<ng-container *ngTemplateOutlet="paging"></ng-container>
|
<ng-container *ngTemplateOutlet="paging"></ng-container>
|
||||||
|
|
||||||
<div class="download">
|
<div class="download">
|
||||||
<button class="rb-btn rb-secondary" type="button" [rbModal]="linkModal" ><span class="rb-ic rb-ic-download"></span> JSON download link
|
<rb-icon-button icon="download" mode="secondary" [rbModal]="linkModal">JSON download link</rb-icon-button>
|
||||||
</button>
|
<ng-template #linkModal>
|
||||||
<ng-template #linkModal let-close="close">
|
<label for="jsonUrl">URL for JSON download</label>
|
||||||
URL for JSON download:
|
<textarea class="linkmodal" id="jsonUrl" #linkarea [value]="sampleUrl({export: true, host: true})"
|
||||||
<textarea class="linkmodal" #linkarea [value]="sampleUrl({export: true, host: true})" (keydown)="preventDefault($event)"></textarea>
|
(keydown)="preventDefault($event)"></textarea>
|
||||||
<rb-form-checkbox name="download-csv" [(ngModel)]="downloadCsv">
|
<rb-form-checkbox name="download-csv" [(ngModel)]="downloadCsv">
|
||||||
add spectra
|
add spectra
|
||||||
</rb-form-checkbox>
|
</rb-form-checkbox>
|
||||||
<button class="rb-btn rb-secondary" type="button" (click)="clipboard()"><span class="rb-ic rb-ic-clipboard"></span> Copy to clipboard</button>
|
<rb-icon-button icon="clipboard" mode="secondary" (click)="clipboard()">Copy to clipboard</rb-icon-button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<a [href]="csvUrl" download="samples.csv">
|
<a [href]="csvUrl" download="samples.csv">
|
||||||
<button class="rb-btn rb-secondary" type="button" (mousedown)="csvUrl = sampleUrl({csv: true, export: true})"><span class="rb-ic rb-ic-download"></span> Download result as CSV</button>
|
<rb-icon-button icon="download" mode="secondary" (mousedown)="csvUrl = sampleUrl({csv: true, export: true})">
|
||||||
|
Download result as CSV
|
||||||
|
</rb-icon-button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -89,8 +110,12 @@
|
|||||||
<div class="sort-header">
|
<div class="sort-header">
|
||||||
<span>{{key.label}}</span>
|
<span>{{key.label}}</span>
|
||||||
<ng-container *ngIf="key.sortable">
|
<ng-container *ngIf="key.sortable">
|
||||||
<span class="rb-ic rb-ic-up sort-arr-up" (click)="setSort(key.id + '-' + 'desc')"><span *ngIf="filters.sort === key.id + '-' + 'desc'"></span></span>
|
<span class="rb-ic rb-ic-up sort-arr-up" (click)="setSort(key.id + '-' + 'desc')">
|
||||||
<span class="rb-ic rb-ic-down sort-arr-down" (click)="setSort(key.id + '-' + 'asc')"><span *ngIf="filters.sort === key.id + '-' + 'asc'"></span></span>
|
<span *ngIf="filters.sort === key.id + '-' + 'desc'"></span>
|
||||||
|
</span>
|
||||||
|
<span class="rb-ic rb-ic-down sort-arr-down" (click)="setSort(key.id + '-' + 'asc')">
|
||||||
|
<span *ngIf="filters.sort === key.id + '-' + 'asc'"></span>
|
||||||
|
</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
@ -103,7 +128,9 @@
|
|||||||
<td *ngIf="isActiveKey['material.name']">{{materials[sample.material_id].name}}</td>
|
<td *ngIf="isActiveKey['material.name']">{{materials[sample.material_id].name}}</td>
|
||||||
<td *ngIf="isActiveKey['material.supplier']">{{materials[sample.material_id].supplier}}</td>
|
<td *ngIf="isActiveKey['material.supplier']">{{materials[sample.material_id].supplier}}</td>
|
||||||
<td *ngIf="isActiveKey['material.group']">{{materials[sample.material_id].group}}</td>
|
<td *ngIf="isActiveKey['material.group']">{{materials[sample.material_id].group}}</td>
|
||||||
<td *ngFor="let key of activeTemplateKeys.material">{{materials[sample.material_id].properties[key[2]] | exists}}</td>
|
<td *ngFor="let key of activeTemplateKeys.material">
|
||||||
|
{{materials[sample.material_id].properties[key[2]] | exists}}
|
||||||
|
</td>
|
||||||
<td *ngIf="isActiveKey['type']">{{sample.type}}</td>
|
<td *ngIf="isActiveKey['type']">{{sample.type}}</td>
|
||||||
<td *ngIf="isActiveKey['color']">{{sample.color}}</td>
|
<td *ngIf="isActiveKey['color']">{{sample.color}}</td>
|
||||||
<td *ngIf="isActiveKey['batch']">{{sample.batch}}</td>
|
<td *ngIf="isActiveKey['batch']">{{sample.batch}}</td>
|
||||||
@ -121,7 +148,8 @@
|
|||||||
<button class="rb-btn rb-link" type="button" (click)="loadPage(-1)" [disabled]="page === 1">
|
<button class="rb-btn rb-link" type="button" (click)="loadPage(-1)" [disabled]="page === 1">
|
||||||
<span class="rb-ic rb-ic-back-left"></span>
|
<span class="rb-ic rb-ic-back-left"></span>
|
||||||
</button>
|
</button>
|
||||||
<rb-form-input label="page" (change)="loadPage({toPage: $event.target.value - page})" [ngModel]="page"></rb-form-input>
|
<rb-form-input label="page" (change)="loadPage({toPage: $event.target.value - page})" [ngModel]="page">
|
||||||
|
</rb-form-input>
|
||||||
<span>
|
<span>
|
||||||
of {{pages}} ({{totalSamples}} samples)
|
of {{pages}} ({{totalSamples}} samples)
|
||||||
</span>
|
</span>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// import { SamplesComponent } from './samples.component';
|
// import { SamplesComponent } from './samples.component';
|
||||||
//
|
//
|
||||||
// // TODO
|
// // TODO: tests
|
||||||
//
|
//
|
||||||
// describe('SamplesComponent', () => {
|
// describe('SamplesComponent', () => {
|
||||||
// let component: SamplesComponent;
|
// let component: SamplesComponent;
|
||||||
|
@ -54,7 +54,7 @@ export class SamplesComponent implements OnInit {
|
|||||||
{field: 'color', label: 'Color', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
{field: 'color', label: 'Color', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||||
{field: 'batch', label: 'Batch', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
{field: 'batch', label: 'Batch', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||||
{field: 'notes', label: 'Notes', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
{field: 'notes', label: 'Notes', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||||
{field: 'added', label: 'Added', active: false, autocomplete: [], mode: 'eq', values: [new Date()]}
|
{field: 'added', label: 'Added', active: false, autocomplete: [], mode: 'eq', values: ['']}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
page = 1;
|
page = 1;
|
||||||
@ -92,7 +92,8 @@ export class SamplesComponent implements OnInit {
|
|||||||
this.materials[material._id] = material;
|
this.materials[material._id] = material;
|
||||||
});
|
});
|
||||||
this.filters.filters.find(e => e.field === 'material.name').autocomplete = mData.map(e => e.name);
|
this.filters.filters.find(e => e.field === 'material.name').autocomplete = mData.map(e => e.name);
|
||||||
this.filters.filters.find(e => e.field === 'color').autocomplete = [...new Set(mData.reduce((s, e) => {s.push(...e.numbers.map(el => el.color)); return s; }, []))];
|
this.filters.filters.find(e => e.field === 'color').autocomplete =
|
||||||
|
[...new Set(mData.reduce((s, e) => {s.push(...e.numbers.map(el => el.color)); return s; }, []))];
|
||||||
this.loadSamples();
|
this.loadSamples();
|
||||||
});
|
});
|
||||||
this.api.get('/user/key', (data: {key: string}) => {
|
this.api.get('/user/key', (data: {key: string}) => {
|
||||||
@ -114,9 +115,22 @@ export class SamplesComponent implements OnInit {
|
|||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
item.parameters.forEach(parameter => {
|
item.parameters.forEach(parameter => {
|
||||||
const parameterName = encodeURIComponent(parameter.name);
|
const parameterName = encodeURIComponent(parameter.name);
|
||||||
if (parameter.name !== 'dpt' && !templateKeys.find(e => new RegExp('.' + parameterName + '$').test(e.id))) { // exclude spectrum
|
// exclude spectrum
|
||||||
templateKeys.push({id: `${collection === 'materials' ? 'material.properties' : collection + '.' + item.name}.${parameterName}`, label: `${this.ucFirst(item.name)} ${this.ucFirst(parameter.name)}`, active: false, sortable: true});
|
if (parameter.name !== 'dpt' && !templateKeys.find(e => new RegExp('.' + parameterName + '$').test(e.id))) {
|
||||||
this.filters.filters.push({field: `${collection === 'materials' ? 'material.properties' : collection + '.' + item.name}.${parameterName}`, label: `${this.ucFirst(item.name)} ${this.ucFirst(parameter.name)}`, active: false, autocomplete: [], mode: 'eq', values: ['']});
|
templateKeys.push({
|
||||||
|
id: `${collection === 'materials' ? 'material.properties' : collection + '.' + item.name}.${parameterName}`,
|
||||||
|
label: `${this.ucFirst(item.name)} ${this.ucFirst(parameter.name)}`,
|
||||||
|
active: false,
|
||||||
|
sortable: true
|
||||||
|
});
|
||||||
|
this.filters.filters.push({
|
||||||
|
field: `${collection === 'materials' ? 'material.properties' : collection + '.' + item.name}.${parameterName}`,
|
||||||
|
label: `${this.ucFirst(item.name)} ${this.ucFirst(parameter.name)}`,
|
||||||
|
active: false,
|
||||||
|
autocomplete: [],
|
||||||
|
mode: 'eq',
|
||||||
|
values: ['']
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -156,10 +170,22 @@ export class SamplesComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sampleUrl(options: {paging?: boolean, pagingOptions?: {firstPage?: boolean, toPage?: number, event?: Event}, csv?: boolean, export?: boolean, host?: boolean}) { // return url to fetch samples
|
sampleUrl(options: {
|
||||||
|
paging?: boolean,
|
||||||
|
pagingOptions?: {
|
||||||
|
firstPage?: boolean,
|
||||||
|
toPage?: number,
|
||||||
|
event?: Event
|
||||||
|
},
|
||||||
|
csv?: boolean,
|
||||||
|
export?: boolean,
|
||||||
|
host?: boolean
|
||||||
|
}) { // return url to fetch samples
|
||||||
const additionalTableKeys = ['material_id', '_id']; // keys which should always be added if export = false
|
const additionalTableKeys = ['material_id', '_id']; // keys which should always be added if export = false
|
||||||
const query: string[] = [];
|
const query: string[] = [];
|
||||||
query.push('status=' + (this.filters.status.new && this.filters.status.validated ? 'all' : (this.filters.status.new ? 'new' : 'validated')));
|
query.push(
|
||||||
|
'status=' + (this.filters.status.new && this.filters.status.validated ? 'all' : (this.filters.status.new ? 'new' : 'validated'))
|
||||||
|
);
|
||||||
if (options.paging) {
|
if (options.paging) {
|
||||||
if (this.samples[0]) { // do not include from-id when page size was changed
|
if (this.samples[0]) { // do not include from-id when page size was changed
|
||||||
if (!options.pagingOptions.firstPage) {
|
if (!options.pagingOptions.firstPage) {
|
||||||
@ -182,11 +208,11 @@ export class SamplesComponent implements OnInit {
|
|||||||
query.push('key=' + this.apiKey);
|
query.push('key=' + this.apiKey);
|
||||||
}
|
}
|
||||||
this.keys.forEach(key => {
|
this.keys.forEach(key => {
|
||||||
if (key.active && (options.export || (!options.export && key.id.indexOf('material') < 0))) { // do not load material properties for table
|
// do not load material properties for table
|
||||||
|
if (key.active && (options.export || (!options.export && key.id.indexOf('material') < 0))) {
|
||||||
query.push('fields[]=' + key.id);
|
query.push('fields[]=' + key.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(this.filters.filters);
|
|
||||||
|
|
||||||
query.push(..._.cloneDeep(this.filters.filters)
|
query.push(..._.cloneDeep(this.filters.filters)
|
||||||
.map(e => {
|
.map(e => {
|
||||||
@ -199,7 +225,6 @@ export class SamplesComponent implements OnInit {
|
|||||||
.filter(e => e.active && e.values.length > 0)
|
.filter(e => e.active && e.values.length > 0)
|
||||||
.map(e => 'filters[]=' + encodeURIComponent(JSON.stringify(_.pick(e, ['mode', 'field', 'values']))))
|
.map(e => 'filters[]=' + encodeURIComponent(JSON.stringify(_.pick(e, ['mode', 'field', 'values']))))
|
||||||
);
|
);
|
||||||
console.log(this.filters);
|
|
||||||
if (!options.export) {
|
if (!options.export) {
|
||||||
additionalTableKeys.forEach(key => {
|
additionalTableKeys.forEach(key => {
|
||||||
if (query.indexOf('fields[]=' + key) < 0) { // add key if not already added
|
if (query.indexOf('fields[]=' + key) < 0) { // add key if not already added
|
||||||
@ -210,8 +235,9 @@ export class SamplesComponent implements OnInit {
|
|||||||
else if (this.downloadCsv) {
|
else if (this.downloadCsv) {
|
||||||
query.push('fields[]=measurements.spectrum.dpt');
|
query.push('fields[]=measurements.spectrum.dpt');
|
||||||
}
|
}
|
||||||
console.log('/samples?' + query.join('&'));
|
return (options.host && isDevMode() ? window.location.host : '') +
|
||||||
return (options.host && isDevMode() ? window.location.host : '') + (options.export ? this.api.hostName : '') + '/samples?' + query.join('&');
|
(options.export ? this.api.hostName : '') +
|
||||||
|
'/samples?' + query.join('&');
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPage(delta) {
|
loadPage(delta) {
|
||||||
@ -225,17 +251,6 @@ export class SamplesComponent implements OnInit {
|
|||||||
updateFilterFields(field) {
|
updateFilterFields(field) {
|
||||||
const filter = this.filters.filters.find(e => e.field === field);
|
const filter = this.filters.filters.find(e => e.field === field);
|
||||||
filter.active = true;
|
filter.active = true;
|
||||||
if (filter.mode === 'in' || filter.mode === 'nin') {
|
|
||||||
if (filter.values[filter.values.length - 1] === '' && filter.values[filter.values.length - 2] === '') {
|
|
||||||
filter.values.pop();
|
|
||||||
}
|
|
||||||
else if (filter.values[filter.values.length - 1] !== '') {
|
|
||||||
filter.values.push((filter.field === 'added' ? new Date() : '') as string & Date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
filter.values = [filter.values[0] as string & Date];
|
|
||||||
}
|
|
||||||
if (filter.active) {
|
if (filter.active) {
|
||||||
this.loadSamples({firstPage: true});
|
this.loadSamples({firstPage: true});
|
||||||
}
|
}
|
||||||
@ -248,15 +263,16 @@ export class SamplesComponent implements OnInit {
|
|||||||
|
|
||||||
updateActiveKeys() { // array with all activeKeys
|
updateActiveKeys() { // array with all activeKeys
|
||||||
this.activeKeys = this.keys.filter(e => e.active);
|
this.activeKeys = this.keys.filter(e => e.active);
|
||||||
this.activeTemplateKeys.material = this.keys.filter(e => e.id.indexOf('material.properties.') >= 0 && e.active).map(e => e.id.split('.').map(el => decodeURIComponent(el)));
|
this.activeTemplateKeys.material = this.keys
|
||||||
this.activeTemplateKeys.measurements = this.keys.filter(e => e.id.indexOf('measurements.') >= 0 && e.active).map(e => e.id.split('.').map(el => decodeURIComponent(el)));
|
.filter(e => e.id.indexOf('material.properties.') >= 0 && e.active)
|
||||||
console.log(this.activeTemplateKeys);
|
.map(e => e.id.split('.')
|
||||||
console.log(this.keys); // TODO: glass fiber filter not working
|
.map(el => decodeURIComponent(el)));
|
||||||
|
this.activeTemplateKeys.measurements = this.keys.filter(e => e.id.indexOf('measurements.') >= 0 && e.active)
|
||||||
|
.map(e => e.id.split('.')
|
||||||
|
.map(el => decodeURIComponent(el))); // TODO: glass fiber filter not working
|
||||||
}
|
}
|
||||||
|
|
||||||
calcFieldSelectKeys() {
|
calcFieldSelectKeys() {
|
||||||
console.log('CALC');
|
|
||||||
console.log(this.keys);
|
|
||||||
this.keys.forEach(key => {
|
this.keys.forEach(key => {
|
||||||
this.isActiveKey[key.id] = key.active;
|
this.isActiveKey[key.id] = key.active;
|
||||||
});
|
});
|
||||||
|
@ -33,8 +33,6 @@ export class LoginService implements CanActivate {
|
|||||||
|
|
||||||
login(username = '', password = '') {
|
login(username = '', password = '') {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
console.log(username);
|
|
||||||
console.log(password);
|
|
||||||
if (username !== '' || password !== '') { // some credentials given
|
if (username !== '' || password !== '') { // some credentials given
|
||||||
let credentials: string[];
|
let credentials: string[];
|
||||||
const credentialString: string = this.storage.get('basicAuth');
|
const credentialString: string = this.storage.get('basicAuth');
|
||||||
@ -54,7 +52,6 @@ export class LoginService implements CanActivate {
|
|||||||
this.storage.set('basicAuth', btoa(credentials[0] + ':' + password));
|
this.storage.set('basicAuth', btoa(credentials[0] + ':' + password));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(this.storage.get('basicAuth'));
|
|
||||||
this.api.get('/authorized', (data: any, error) => {
|
this.api.get('/authorized', (data: any, error) => {
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (data.status === 'Authorization successful') {
|
if (data.status === 'Authorization successful') {
|
||||||
|
@ -40,12 +40,13 @@
|
|||||||
class="parameters">
|
class="parameters">
|
||||||
<ng-container *rbArrayInputItem="let item">
|
<ng-container *rbArrayInputItem="let item">
|
||||||
<rb-form-input [rbArrayInputListener]="'parameter-name-' + group.name" appValidate="parameterName"
|
<rb-form-input [rbArrayInputListener]="'parameter-name-' + group.name" appValidate="parameterName"
|
||||||
[index]="item.i" [name]="'parameter-name-' + group.name + item.i" label="parameter name"
|
[index]="item.i" [name]="'parameter-name-' + group.name + item.i"
|
||||||
[ngModel]="item.value.name" #parameterName="ngModel">
|
label="parameter name" [ngModel]="item.value.name" #parameterName="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{parameterName.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{parameterName.errors.failure}}</ng-template>
|
||||||
</rb-form-input>
|
</rb-form-input>
|
||||||
<rb-form-textarea [name]="'parameter-range-' + group.name + item.i" label="range" appValidate="parameterRange"
|
<rb-form-textarea [name]="'parameter-range-' + group.name + item.i" label="range"
|
||||||
[(ngModel)]="item.value.rangeString" #parameterRange="ngModel">
|
appValidate="parameterRange" [(ngModel)]="item.value.rangeString"
|
||||||
|
#parameterRange="ngModel">
|
||||||
<ng-template rbFormValidationMessage="failure">{{parameterRange.errors.failure}}</ng-template>
|
<ng-template rbFormValidationMessage="failure">{{parameterRange.errors.failure}}</ng-template>
|
||||||
</rb-form-textarea>
|
</rb-form-textarea>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
Loading…
Reference in New Issue
Block a user