basic account management (Login/Logout)
This commit is contained in:
@ -6,14 +6,14 @@
|
||||
<!--<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">
|
||||
<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" #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">
|
||||
<div class="material shaded-container" *ngIf="newMaterial" [@inOut]>
|
||||
<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>
|
||||
@ -38,7 +38,7 @@
|
||||
</rb-form-input>
|
||||
|
||||
<div class="material-numbers">
|
||||
<div *ngFor="let number of material.numbers; index as i" class="two-col">
|
||||
<div *ngFor="let number of material.numbers; index as i" class="two-col" [@inOut]>
|
||||
<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}">
|
||||
@ -69,7 +69,7 @@
|
||||
<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 *ngFor="let field of customFields; index as i" class="two-col" [@inOut]>
|
||||
<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>
|
||||
@ -89,7 +89,7 @@
|
||||
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">
|
||||
<div *ngIf="condition" [@inOut]>
|
||||
<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>
|
||||
@ -105,8 +105,8 @@
|
||||
|
||||
<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">
|
||||
<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)">
|
||||
<option *ngFor="let m of measurementTemplates" [value]="m._id">{{m.name}}</option>
|
||||
</rb-form-select>
|
||||
|
||||
@ -115,9 +115,16 @@
|
||||
<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>
|
||||
<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>
|
||||
<ng-template rbFormValidationMessage="required">Cannot be empty</ng-template>
|
||||
</rb-form-file>
|
||||
<canvas baseChart *ngIf="parameter.range.type && charts[mIndex][0].data.length > 0" class="dpt-chart" [@inOut]
|
||||
[datasets]="charts[mIndex]"
|
||||
[labels]="[]"
|
||||
[options]="chartOptions"
|
||||
[legend]="false"
|
||||
chartType="scatter">
|
||||
</canvas>
|
||||
</div>
|
||||
|
||||
<button class="rb-btn rb-danger" type="button" (click)="removeMeasurement(mIndex)"><span class="rb-ic rb-ic-delete"></span> Delete measurement</button>
|
||||
@ -130,7 +137,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div>
|
||||
<button class="rb-btn rb-primary" type="submit" (click)="saveSample()" [disabled]="!sampleForm.form.valid">Save sample</button>
|
||||
|
@ -15,3 +15,7 @@ td:first-child {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-column-gap: 10px;
|
||||
}
|
||||
|
||||
.dpt-chart {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
@ -14,20 +14,35 @@ import {NgForm, Validators} from '@angular/forms';
|
||||
import {ValidationService} from '../services/validation.service';
|
||||
import {TemplateModel} from '../models/template.model';
|
||||
import {MeasurementModel} from '../models/measurement.model';
|
||||
import { ChartOptions } from 'chart.js';
|
||||
import {animate, style, transition, trigger} from '@angular/animations';
|
||||
|
||||
// TODO: tests
|
||||
// TODO: confirmation for new group/supplier
|
||||
// TODO: DPT preview
|
||||
// TODO: work on better recognition for file input
|
||||
// TODO: only show condition (if not set) and measurements in edit sample dialog at first
|
||||
// TODO: multiple spectra, drag and drop
|
||||
// TODO: multiple spectra
|
||||
// TODO: multiple samples for base data, extend multiple measurements, conditions
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-sample',
|
||||
templateUrl: './sample.component.html',
|
||||
styleUrls: ['./sample.component.scss']
|
||||
styleUrls: ['./sample.component.scss'],
|
||||
animations: [
|
||||
trigger(
|
||||
'inOut', [
|
||||
transition(':enter', [
|
||||
style({height: 0, opacity: 0}),
|
||||
animate('0.5s ease-out', style({height: '*', opacity: 1}))
|
||||
]),
|
||||
transition(':leave', [
|
||||
style({height: '*', opacity: 1}),
|
||||
animate('0.5s ease-in', style({height: 0, opacity: 0}))
|
||||
])
|
||||
]
|
||||
)
|
||||
]
|
||||
})
|
||||
export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
|
||||
@ -49,6 +64,27 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
measurementTemplates: TemplateModel[];
|
||||
loading = 0; // number of currently loading instances
|
||||
checkFormAfterInit = false;
|
||||
charts = []; // chart data for spectrums
|
||||
readonly chartInit = [{
|
||||
data: [],
|
||||
label: 'Spectrum',
|
||||
showLine: true,
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
borderColor: '#00a8b0',
|
||||
borderWidth: 2
|
||||
}];
|
||||
readonly chartOptions: ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{ticks: {min: 400, max: 4000, stepSize: 400, reverse: true}}],
|
||||
yAxes: [{ticks: {min: 0, max: 1}}]
|
||||
},
|
||||
responsive: true,
|
||||
tooltips: {enabled: false},
|
||||
hover: {mode: null},
|
||||
maintainAspectRatio: true,
|
||||
plugins: {datalabels: {display: false}}
|
||||
};
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
@ -90,6 +126,19 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
this.loading++;
|
||||
this.api.get<SampleModel>('/sample/' + this.route.snapshot.paramMap.get('id'), sData => {
|
||||
this.sample.deserialize(sData);
|
||||
this.charts = [];
|
||||
const spectrumTemplate = this.measurementTemplates.find(e => e.name === 'spectrum')._id;
|
||||
let spectrumCounter = 0;
|
||||
this.sample.measurements.forEach((measurement, i) => {
|
||||
this.charts.push(_.cloneDeep(this.chartInit));
|
||||
if (measurement.measurement_template === spectrumTemplate) {
|
||||
setTimeout(() => {
|
||||
this.generateChart(measurement.values.dpt, i);
|
||||
console.log(this.charts);
|
||||
}, spectrumCounter * 20);
|
||||
spectrumCounter ++;
|
||||
}
|
||||
});
|
||||
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) {
|
||||
@ -225,8 +274,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
this.setNewMaterial();
|
||||
}
|
||||
|
||||
preventSubmit(event) {
|
||||
if (event.key === 'Enter') {
|
||||
preventDefault(event) {
|
||||
if (event.key && event.key === 'Enter' || event.type === 'dragover') {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
@ -285,6 +334,7 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
|
||||
addMeasurement() {
|
||||
this.sample.measurements.push(new MeasurementModel(this.measurementTemplates[0]._id));
|
||||
this.charts.push(_.cloneDeep(this.chartInit));
|
||||
}
|
||||
|
||||
removeMeasurement(index) {
|
||||
@ -292,14 +342,24 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
||||
this.api.delete('/measurement/' + this.sample.measurements[index]._id);
|
||||
}
|
||||
this.sample.measurements.splice(index, 1);
|
||||
this.charts.splice(index, 1);
|
||||
}
|
||||
|
||||
fileToArray(event, mIndex, parameter) {
|
||||
clearChart(index) {
|
||||
this.charts[index][0].data = [];
|
||||
}
|
||||
|
||||
fileToArray(files, mIndex, parameter) {
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onload = () => {
|
||||
this.sample.measurements[mIndex].values[parameter] = fileReader.result.toString().split('\r\n').map(e => e.split(','));
|
||||
this.generateChart(this.sample.measurements[mIndex].values[parameter], mIndex);
|
||||
};
|
||||
fileReader.readAsText(event.target.files[0]);
|
||||
fileReader.readAsText(files[0]);
|
||||
}
|
||||
|
||||
generateChart(spectrum, index) {
|
||||
this.charts[index][0].data = spectrum.map(e => ({x: parseFloat(e[0]), y: parseFloat(e[1])}));
|
||||
}
|
||||
|
||||
toggleCondition() {
|
||||
|
Reference in New Issue
Block a user