first version of sample.component finished
This commit is contained in:
157
src/app/sample/sample.component.html
Normal file
157
src/app/sample/sample.component.html
Normal file
@ -0,0 +1,157 @@
|
||||
<h2>{{new ? 'Add new sample' : 'Edit sample ' + sample.number}}</h2>
|
||||
|
||||
<rb-loading-spinner *ngIf="loading"></rb-loading-spinner>
|
||||
|
||||
<form #sampleForm="ngForm" *ngIf="!responseData && !loading">
|
||||
<!--<form #sampleForm="ngForm">-->
|
||||
<div class="sample">
|
||||
<div>
|
||||
<rb-form-input name="materialname" label="material name" [rbFormInputAutocomplete]="autocomplete.bind(this, materialNames)" [rbDebounceTime]="0" [rbInitialOpen]="true" (keydown)="preventSubmit($event)" (ngModelChange)="findMaterial($event)" appValidate="stringOf" [appValidateArgs]="[materialNames]" required [(ngModel)]="material.name" [autofocus]="true" #materialNameInput="ngModel">
|
||||
<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>
|
||||
<button class="rb-btn rb-secondary" type="button" (click)="setNewMaterial(true)"><span class="rb-ic rb-ic-add"></span> New material</button>
|
||||
</div>
|
||||
|
||||
<div class="material shaded-container" *ngIf="newMaterial">
|
||||
<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">
|
||||
<ng-template rbFormValidationMessage="failure">{{supplierInput.errors.failure}}</ng-template>
|
||||
</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">
|
||||
<ng-template rbFormValidationMessage="failure">{{groupInput.errors.failure}}</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-input name="mineral" label="mineral" type="number" required rbNumberConverter rbMin="0" rbMax="100" [(ngModel)]="material.mineral" ngModel>
|
||||
<ng-template rbFormValidationMessage="required">Invalid value</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMin">Minimum value is 0</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMax">Maximum value is 100</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-input name="glass_fiber" label="glass_fiber" type="number" required rbNumberConverter rbMin="0" rbMax="100" [(ngModel)]="material.glass_fiber" ngModel>
|
||||
<ng-template rbFormValidationMessage="required">Invalid value</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMin">Minimum value is 0</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMax">Maximum value is 100</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-input name="carbon_fiber" label="carbon_fiber" type="number" required rbNumberConverter rbMin="0" rbMax="100" [(ngModel)]="material.carbon_fiber" ngModel>
|
||||
<ng-template rbFormValidationMessage="required">Invalid value</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMin">Minimum value is 0</ng-template>
|
||||
<ng-template rbFormValidationMessage="rbMax">Maximum value is 100</ng-template>
|
||||
</rb-form-input>
|
||||
|
||||
<div class="material-numbers">
|
||||
<div *ngFor="let number of material.numbers; index as i" class="two-col">
|
||||
<rb-form-input label="color" appValidate="string" [required]="i < material.numbers.length - 1" (keyup)="handleMaterialNumbers()" [(ngModel)]="number.color" ngModel [ngModelOptions]="{standalone: true}">
|
||||
</rb-form-input>
|
||||
<rb-form-input label="material number" appValidate="string" [(ngModel)]="number.number" ngModel [ngModelOptions]="{standalone: true}">
|
||||
</rb-form-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<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="required">Cannot be empty</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-input name="color" label="color" [rbFormInputAutocomplete]="autocomplete.bind(this, getColors(material))" [rbDebounceTime]="0" [rbInitialOpen]="true" appValidate="stringOf" [appValidateArgs]="[getColors(material)]" required [(ngModel)]="sample.color" #colorInput="ngModel">
|
||||
<ng-template rbFormValidationMessage="failure">{{colorInput.errors.failure}}</ng-template>
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-input name="batch" label="batch" appValidate="string" [(ngModel)]="sample.batch" #batchInput="ngModel">
|
||||
<ng-template rbFormValidationMessage="failure">{{batchInput.errors.failure}}</ng-template>
|
||||
</rb-form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="notes">
|
||||
<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>
|
||||
</rb-form-input>
|
||||
<h5>Additional properties</h5>
|
||||
<div *ngFor="let field of customFields; index as i" class="two-col">
|
||||
<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">
|
||||
<ng-template rbFormValidationMessage="failure">{{keyInput.errors.failure}}</ng-template>
|
||||
</rb-form-input>
|
||||
</div>
|
||||
<rb-form-input [name]="'cf-value' + i" label="value" appValidate="string" [required]="field[0] !== ''" [(ngModel)]="field[1]">
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
</rb-form-input>
|
||||
</div>
|
||||
<!-- TODO: Sample reference-->
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="conditions shaded-container">
|
||||
<h4>
|
||||
Condition
|
||||
<button class="rb-btn rb-secondary condition-set" type="button" (click)="toggleCondition()" [disabled]="!conditionTemplates">{{condition ? 'Do not set condition' : 'Set condition'}}</button>
|
||||
</h4>
|
||||
<div *ngIf="condition">
|
||||
<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>
|
||||
</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">
|
||||
<ng-template rbFormValidationMessage="failure">{{parameterInput.errors.failure}}</ng-template>
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
</rb-form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="measurements shaded-container">
|
||||
<h4>Measurements</h4>
|
||||
<div *ngFor="let measurement of sample.measurements; index as mIndex">
|
||||
<rb-form-select name="measurementTemplateSelect" label="Template" [(ngModel)]="measurement.measurement_template">
|
||||
<option *ngFor="let m of measurementTemplates" [value]="m._id">{{m.name}}</option>
|
||||
</rb-form-select>
|
||||
|
||||
<div *ngFor="let parameter of getMeasurementTemplate(measurement.measurement_template).parameters; 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="required">Cannot be empty</ng-template>
|
||||
</rb-form-input>
|
||||
<rb-form-file *ngIf="parameter.range.type" [name]="'measurementParameter' + mIndex + '-' + pIndex" [label]="parameter.name" maxSize="10000000" (change)="fileToArray($event, mIndex, parameter.name)" required ngModel>
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
</rb-form-file>
|
||||
</div>
|
||||
|
||||
<button class="rb-btn rb-danger" type="button" (click)="removeMeasurement(mIndex)"><span class="rb-ic rb-ic-delete"></span> Delete measurement</button>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<button class="rb-btn rb-primary" type="submit" (click)="saveSample()" [disabled]="!sampleForm.form.valid">Save sample</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div *ngIf="responseData">
|
||||
<h3>Successfully added sample:</h3>
|
||||
<rb-table id="response-data">
|
||||
<tr><td>Sample number</td><td>{{responseData.number}}</td></tr>
|
||||
<tr><td>Type</td><td>{{responseData.type}}</td></tr>
|
||||
<tr><td>color</td><td>{{responseData.color}}</td></tr>
|
||||
<tr><td>Batch</td><td>{{responseData.batch}}</td></tr>
|
||||
<tr><td>Material</td><td>{{material.name}}</td></tr>
|
||||
</rb-table>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<a routerLink="/samples">
|
||||
<button class="rb-btn rb-primary" type="button">Return to samples</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
17
src/app/sample/sample.component.scss
Normal file
17
src/app/sample/sample.component.scss
Normal file
@ -0,0 +1,17 @@
|
||||
::ng-deep rb-table#response-data > table {
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
td:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.condition-set {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.two-col {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-column-gap: 10px;
|
||||
}
|
25
src/app/sample/sample.component.spec.ts
Normal file
25
src/app/sample/sample.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SampleComponent } from './sample.component';
|
||||
|
||||
describe('SampleComponent', () => {
|
||||
let component: SampleComponent;
|
||||
let fixture: ComponentFixture<SampleComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SampleComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SampleComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
341
src/app/sample/sample.component.ts
Normal file
341
src/app/sample/sample.component.ts
Normal file
@ -0,0 +1,341 @@
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
AfterContentChecked,
|
||||
Component,
|
||||
OnInit,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {AutocompleteService} from '../services/autocomplete.service';
|
||||
import {ApiService} from '../services/api.service';
|
||||
import {MaterialModel} from '../models/material.model';
|
||||
import {SampleModel} from '../models/sample.model';
|
||||
import {NgForm, Validators} from '@angular/forms';
|
||||
import {ValidationService} from '../services/validation.service';
|
||||
import {TemplateModel} from '../models/template.model';
|
||||
import {MeasurementModel} from '../models/measurement.model';
|
||||
|
||||
// TODO: tests
|
||||
// TODO: confirmation for new group/supplier
|
||||
// TODO: DPT preview
|
||||
// TODO: work on better recognition for file input
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-sample',
|
||||
templateUrl: './sample.component.html',
|
||||
styleUrls: ['./sample.component.scss']
|
||||
})
|
||||
export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
|
||||
@ViewChild('sampleForm') sampleForm: NgForm;
|
||||
|
||||
new; // true if new sample should be created
|
||||
newMaterial = false; // true if new material should be created
|
||||
materials: MaterialModel[] = []; // all materials
|
||||
suppliers: string[] = []; // all suppliers
|
||||
groups: string[] = []; // all groups
|
||||
conditionTemplates: TemplateModel[]; // all conditions
|
||||
condition: TemplateModel | null = null; // selected condition
|
||||
materialNames = []; // names of all materials
|
||||
material = new MaterialModel(); // object of current selected material
|
||||
sample = new SampleModel();
|
||||
customFields: [string, string][] = [['', '']];
|
||||
availableCustomFields: string[] = [];
|
||||
responseData: SampleModel; // gets filled with response data after saving the sample
|
||||
measurementTemplates: TemplateModel[];
|
||||
loading = 0; // number of currently loading instances
|
||||
checkFormAfterInit = false;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private route: ActivatedRoute,
|
||||
private api: ApiService,
|
||||
private validation: ValidationService,
|
||||
public autocomplete: AutocompleteService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.new = this.router.url === '/samples/new';
|
||||
this.loading = 6;
|
||||
this.api.get<MaterialModel[]>('/materials?status=all', (data: any) => {
|
||||
this.materials = data.map(e => new MaterialModel().deserialize(e));
|
||||
this.materialNames = data.map(e => e.name);
|
||||
this.loading--;
|
||||
});
|
||||
this.api.get<string[]>('/material/suppliers', (data: any) => {
|
||||
this.suppliers = data;
|
||||
this.loading--;
|
||||
});
|
||||
this.api.get<string[]>('/material/groups', (data: any) => {
|
||||
this.groups = data;
|
||||
this.loading--;
|
||||
});
|
||||
this.api.get<TemplateModel[]>('/template/conditions', data => {
|
||||
this.conditionTemplates = data.map(e => new TemplateModel().deserialize(e));
|
||||
this.loading--;
|
||||
});
|
||||
this.api.get<TemplateModel[]>('/template/measurements', data => {
|
||||
this.measurementTemplates = data.map(e => new TemplateModel().deserialize(e));
|
||||
this.loading--;
|
||||
});
|
||||
this.api.get<TemplateModel[]>('/sample/notes/fields', data => {
|
||||
this.availableCustomFields = data.map(e => e.name);
|
||||
this.loading--;
|
||||
});
|
||||
if (!this.new) {
|
||||
this.loading++;
|
||||
this.api.get<SampleModel>('/sample/' + this.route.snapshot.paramMap.get('id'), sData => {
|
||||
this.sample.deserialize(sData);
|
||||
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]]) : [['', '']];
|
||||
if ('condition_template' in this.sample.condition) {
|
||||
this.selectCondition(this.sample.condition.condition_template);
|
||||
}
|
||||
console.log('data loaded');
|
||||
this.loading--;
|
||||
this.checkFormAfterInit = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterContentChecked() {
|
||||
// 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')) {
|
||||
for (const i in this.condition.parameters) {
|
||||
if (this.condition.parameters[i]) {
|
||||
this.attachValidator('conditionParameter' + i, this.condition.parameters[i].range, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.sampleForm && this.sampleForm.form.get('measurementParameter0-0')) {
|
||||
this.sample.measurements.forEach((measurement, mIndex) => {
|
||||
const template = this.getMeasurementTemplate(measurement.measurement_template);
|
||||
for (const i in template.parameters) {
|
||||
if (template.parameters[i]) {
|
||||
this.attachValidator('measurementParameter' + mIndex + '-' + i, template.parameters[i].range, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (this.checkFormAfterInit) {
|
||||
this.checkFormAfterInit = false;
|
||||
this.initialValidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initialValidate() {
|
||||
console.log('initVal');
|
||||
Object.keys(this.sampleForm.form.controls).forEach(field => {
|
||||
this.sampleForm.form.get(field).updateValueAndValidity();
|
||||
});
|
||||
}
|
||||
|
||||
attachValidator(name: string, range: {[prop: string]: any}, required: boolean) {
|
||||
if (this.sampleForm.form.get(name)) {
|
||||
const validators = [];
|
||||
if (required) {
|
||||
validators.push(Validators.required);
|
||||
}
|
||||
if (range.hasOwnProperty('values')) {
|
||||
validators.push(this.validation.generate('stringOf', [range.values]));
|
||||
}
|
||||
else if (range.hasOwnProperty('min') && range.hasOwnProperty('max')) {
|
||||
validators.push(this.validation.generate('minMax', [range.min, range.max]));
|
||||
}
|
||||
else if (range.hasOwnProperty('min')) {
|
||||
validators.push(this.validation.generate('min', [range.min]));
|
||||
}
|
||||
else if (range.hasOwnProperty('max')) {
|
||||
validators.push(this.validation.generate('max', [range.max]));
|
||||
}
|
||||
this.sampleForm.form.get(name).setValidators(validators);
|
||||
}
|
||||
}
|
||||
|
||||
saveSample() {
|
||||
new Promise<void>(resolve => {
|
||||
if (this.newMaterial) { // save material first if new one exists
|
||||
for (const i in this.material.numbers) { // remove empty numbers fields
|
||||
if (this.material.numbers[i].color === '') {
|
||||
this.material.numbers.splice(i as any as number, 1);
|
||||
}
|
||||
}
|
||||
this.api.post<MaterialModel>('/material/new', this.material.sendFormat(), data => {
|
||||
this.materials.push(data); // add material to data
|
||||
this.material = data;
|
||||
this.sample.material_id = data._id; // add new material id to sample data
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
}).then(() => { // save sample
|
||||
this.sample.notes.custom_fields = {};
|
||||
this.customFields.forEach(element => {
|
||||
if (element[0] !== '') {
|
||||
this.sample.notes.custom_fields[element[0]] = element[1];
|
||||
}
|
||||
});
|
||||
new Promise<SampleModel>(resolve => {
|
||||
if (this.new) {
|
||||
this.api.post<SampleModel>('/sample/new', this.sample.sendFormat(), resolve);
|
||||
}
|
||||
else {
|
||||
this.api.put<SampleModel>('/sample/' + this.sample._id, this.sample.sendFormat(), resolve);
|
||||
}
|
||||
}).then( data => {
|
||||
this.responseData = new SampleModel().deserialize(data);
|
||||
this.material = this.materials.find(e => e._id === this.responseData.material_id);
|
||||
this.sample.measurements.forEach(measurement => {
|
||||
if (Object.keys(measurement.values).map(e => measurement.values[e]).join('') !== '') {
|
||||
Object.keys(measurement.values).forEach(key => {
|
||||
measurement.values[key] = measurement.values[key] === '' ? null : measurement.values[key];
|
||||
});
|
||||
if (measurement._id === null) { // new measurement
|
||||
measurement.sample_id = data._id;
|
||||
this.api.post<MeasurementModel>('/measurement/new', measurement.sendFormat());
|
||||
}
|
||||
else { // update measurement
|
||||
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
|
||||
this.api.delete('/measurement/' + measurement._id);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
findMaterial(name) {
|
||||
const res = this.materials.find(e => e.name === name); // search for match
|
||||
if (res) {
|
||||
this.material = _.cloneDeep(res);
|
||||
this.sample.material_id = this.material._id;
|
||||
}
|
||||
else {
|
||||
this.sample.material_id = null;
|
||||
}
|
||||
this.setNewMaterial();
|
||||
}
|
||||
|
||||
preventSubmit(event) {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
getColors(material) {
|
||||
return material ? material.numbers.map(e => e.color) : [];
|
||||
}
|
||||
|
||||
// TODO: rework later
|
||||
setNewMaterial(value = null) {
|
||||
if (value === null) {
|
||||
this.newMaterial = !this.sample.material_id;
|
||||
}
|
||||
else {
|
||||
this.newMaterial = value;
|
||||
}
|
||||
if (this.newMaterial) {
|
||||
this.sampleForm.form.get('materialname').setValidators([Validators.required]);
|
||||
}
|
||||
else {
|
||||
this.sampleForm.form.get('materialname').setValidators([Validators.required, this.validation.generate('stringOf', [this.materialNames])]);
|
||||
}
|
||||
this.sampleForm.form.get('materialname').updateValueAndValidity();
|
||||
}
|
||||
|
||||
handleMaterialNumbers() {
|
||||
const fieldNo = this.material.numbers.length;
|
||||
let filledFields = 0;
|
||||
this.material.numbers.forEach(mNumber => {
|
||||
if (mNumber.color !== '') {
|
||||
filledFields ++;
|
||||
}
|
||||
});
|
||||
// append new field
|
||||
if (filledFields === fieldNo) {
|
||||
this.material.addNumber();
|
||||
}
|
||||
// remove if two end fields are empty
|
||||
if (fieldNo > 1 && this.material.numbers[fieldNo - 1].color === '' && this.material.numbers[fieldNo - 2].color === '') {
|
||||
this.material.popNumber();
|
||||
}
|
||||
}
|
||||
|
||||
selectCondition(id) {
|
||||
this.condition = this.conditionTemplates.find(e => e._id === id);
|
||||
console.log(this.condition);
|
||||
console.log(this.sample);
|
||||
if ('condition_template' in this.sample.condition) {
|
||||
this.sample.condition.condition_template = id;
|
||||
}
|
||||
}
|
||||
|
||||
getMeasurementTemplate(id): TemplateModel {
|
||||
return this.measurementTemplates && id ? this.measurementTemplates.find(e => e._id === id) : new TemplateModel();
|
||||
}
|
||||
|
||||
addMeasurement() {
|
||||
this.sample.measurements.push(new MeasurementModel(this.measurementTemplates[0]._id));
|
||||
}
|
||||
|
||||
removeMeasurement(index) {
|
||||
if (this.sample.measurements[index]._id !== null) {
|
||||
this.api.delete('/measurement/' + this.sample.measurements[index]._id);
|
||||
}
|
||||
this.sample.measurements.splice(index, 1);
|
||||
}
|
||||
|
||||
fileToArray(event, mIndex, parameter) {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => {
|
||||
this.sample.measurements[mIndex].values[parameter] = fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
||||
};
|
||||
fileReader.readAsText(event.target.files[0]);
|
||||
}
|
||||
|
||||
toggleCondition() {
|
||||
if (this.condition) {
|
||||
this.condition = null;
|
||||
}
|
||||
else {
|
||||
this.sample.condition = {condition_template: null};
|
||||
this.selectCondition(this.conditionTemplates[0]._id);
|
||||
}
|
||||
}
|
||||
|
||||
adjustCustomFields(value, index) {
|
||||
this.customFields[index][0] = value;
|
||||
const fieldNo = this.customFields.length;
|
||||
let filledFields = 0;
|
||||
this.customFields.forEach(field => {
|
||||
if (field[0] !== '') {
|
||||
filledFields ++;
|
||||
}
|
||||
});
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
uniqueCfValues(index) { // returns all names until index for unique check
|
||||
return 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
|
||||
// 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^^
|
Reference in New Issue
Block a user