Merge pull request #26 in ~VLE2FE/definma-ui from development to master
* commit 'bf02c1b99ec50f665bfece94e451b7954dd281a6': added required parameter range added notes.comments field
This commit is contained in:
commit
f73e7908d9
@ -37,7 +37,9 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div *rbSubBrandHeader>
|
<div *rbSubBrandHeader>
|
||||||
<rb-icon-button icon="bug" mode="secondary" class="space-right" [rbModal]="bugModal">Bug</rb-icon-button>
|
<rb-icon-button icon="bug" mode="secondary" class="space-right" [rbModal]="bugModal" *ngIf="false">
|
||||||
|
Bug
|
||||||
|
</rb-icon-button>
|
||||||
<ng-template let-close="close" #bugModal>
|
<ng-template let-close="close" #bugModal>
|
||||||
<h3>Report a bug</h3>
|
<h3>Report a bug</h3>
|
||||||
<rb-form-textarea class="bug-textarea" label="What did you do?" [(ngModel)]="bugReport.do"></rb-form-textarea>
|
<rb-form-textarea class="bug-textarea" label="What did you do?" [(ngModel)]="bugReport.do"></rb-form-textarea>
|
||||||
@ -46,7 +48,7 @@
|
|||||||
<rb-icon-button icon="mail" mode="primary" (mouseup)="closeBugReport(close)">Send report</rb-icon-button>
|
<rb-icon-button icon="mail" mode="primary" (mouseup)="closeBugReport(close)">Send report</rb-icon-button>
|
||||||
</a>
|
</a>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<span class="dev-label" *ngIf="devMode">DEVELOPMENT</span>
|
<span class="dev-label" *ngIf="devMode && false">DEVELOPMENT</span>
|
||||||
DeFinMa
|
DeFinMa
|
||||||
</div>
|
</div>
|
||||||
</rb-full-header>
|
</rb-full-header>
|
||||||
|
@ -1 +1,3 @@
|
|||||||
<app-login></app-login>
|
<app-login *ngIf="!login.isLoggedIn"></app-login>
|
||||||
|
|
||||||
|
<img src="/assets/imgs/key-visual.png" alt="" class="key-visual">
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
app-login {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.key-visual {
|
||||||
|
width: 70%;
|
||||||
|
float: right;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import {LoginService} from '../services/login.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
@ -7,7 +8,9 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class HomeComponent implements OnInit {
|
export class HomeComponent implements OnInit {
|
||||||
|
|
||||||
constructor() { }
|
constructor(
|
||||||
|
public login: LoginService
|
||||||
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,10 @@
|
|||||||
[disabled]="!sampleForm.form.valid">
|
[disabled]="!sampleForm.form.valid">
|
||||||
Save sample
|
Save sample
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
|
<rb-icon-button class="delete-sample" icon="delete" mode="danger" *ngIf="samples.length > 1"
|
||||||
|
(click)="deleteConfirm(modalDeleteConfirm)">
|
||||||
|
Delete samples
|
||||||
|
</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
<ng-template #generateSamples>
|
<ng-template #generateSamples>
|
||||||
<rb-form-input type="number" name="sample-count" label="number of samples" pattern="^\d+?$" required
|
<rb-form-input type="number" name="sample-count" label="number of samples" pattern="^\d+?$" required
|
||||||
@ -285,15 +289,10 @@
|
|||||||
[disabled]="!cmForm.form.valid">
|
[disabled]="!cmForm.form.valid">
|
||||||
Summary
|
Summary
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
<rb-icon-button class="delete-sample" icon="delete" mode="danger" *ngIf="mode !== 'new'"
|
<rb-icon-button class="delete-sample" icon="delete" mode="danger" *ngIf="samples.length === 1"
|
||||||
(click)="deleteConfirm(modalDeleteConfirm)">
|
(click)="deleteConfirm(modalDeleteConfirm)">
|
||||||
Delete sample
|
Delete sample
|
||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
<ng-template #modalDeleteConfirm>
|
|
||||||
<rb-alert alertTitle="Are you sure?" type="danger" okBtnLabel="Delete sample" cancelBtnLabel="Cancel">
|
|
||||||
Do you really want to delete this sample?
|
|
||||||
</rb-alert>
|
|
||||||
</ng-template>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -322,3 +321,9 @@
|
|||||||
</rb-icon-button>
|
</rb-icon-button>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
<ng-template #modalDeleteConfirm>
|
||||||
|
<rb-alert alertTitle="Are you sure?" type="danger" [okBtnLabel]="'Delete sample' + (samples.length > 1 ? 's' : '')" cancelBtnLabel="Cancel">
|
||||||
|
Do you really want to delete {{samples.length > 1 ? 'these samples' : 'this sample'}}?
|
||||||
|
</rb-alert>
|
||||||
|
</ng-template>
|
||||||
|
@ -176,11 +176,8 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.view.base = true;
|
this.view.base = true;
|
||||||
}
|
}
|
||||||
this.loading += sampleIds.length;
|
this.loading += sampleIds.length;
|
||||||
this.samples = [];
|
this.api.get<SampleModel>('/sample/' + sampleIds[0], sData => { // special treatment for first id
|
||||||
sampleIds.forEach((sampleId, i) => {
|
this.samples = [new SampleModel().deserialize(sData)];
|
||||||
this.api.get<SampleModel>('/sample/' + sampleId, sData => {
|
|
||||||
this.samples.push(new SampleModel().deserialize(sData));
|
|
||||||
if (i === 0) {
|
|
||||||
this.baseSample.deserialize(sData);
|
this.baseSample.deserialize(sData);
|
||||||
this.material = new MaterialModel().deserialize(sData.material); // read material
|
this.material = new MaterialModel().deserialize(sData.material); // read material
|
||||||
this.customFields = this.baseSample.notes.custom_fields && this.baseSample.notes.custom_fields !== {} ? // read custom fields
|
this.customFields = this.baseSample.notes.custom_fields && this.baseSample.notes.custom_fields !== {} ? // read custom fields
|
||||||
@ -203,30 +200,32 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
if (this.mode === 'editOne') {
|
if (this.mode === 'editOne') {
|
||||||
this.charts = [[]];
|
this.charts = [[]];
|
||||||
let spectrumCounter = 0; // generate charts for spectrum measurements
|
let spectrumCounter = 0; // generate charts for spectrum measurements
|
||||||
this.samples[i].measurements.forEach((measurement, j) => {
|
this.samples[0].measurements.forEach((measurement, i) => {
|
||||||
this.charts[i].push(cloneDeep(this.chartInit));
|
this.charts[0].push(cloneDeep(this.chartInit));
|
||||||
if (measurement.values.dpt) {
|
if (measurement.values.dpt) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.generateChart(measurement.values.dpt, 0, j);
|
this.generateChart(measurement.values.dpt, 0, i);
|
||||||
}, spectrumCounter * 20); // generate charts one after another to avoid freezing the UI
|
}, spectrumCounter * 20); // generate charts one after another to avoid freezing the UI
|
||||||
spectrumCounter ++;
|
spectrumCounter ++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.checkFormAfterInit = true;
|
this.loading--;
|
||||||
}
|
sampleIds.slice(1).forEach(sampleId => {
|
||||||
else {
|
this.api.get<SampleModel>('/sample/' + sampleId, data => {
|
||||||
|
this.samples.push(new SampleModel().deserialize(data));
|
||||||
['type', 'color', 'batch', 'notes'].forEach((key) => {
|
['type', 'color', 'batch', 'notes'].forEach((key) => {
|
||||||
console.log(isEqual(sData[key], this.baseSample[key]));
|
console.log(isEqual(data[key], this.baseSample[key]));
|
||||||
if (!isEqual(sData[key], this.baseSample[key])) {
|
if (!isEqual(data[key], this.baseSample[key])) {
|
||||||
this.baseSample[key] = undefined;
|
this.baseSample[key] = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!isEqual(sData.material.name, this.baseSample.material.name)) {
|
if (!isEqual(data.material.name, this.baseSample.material.name)) {
|
||||||
this.baseSample.material.name = undefined;
|
this.baseSample.material.name = undefined;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
this.loading--;
|
this.loading--;
|
||||||
|
this.checkFormAfterInit = true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -240,12 +239,12 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
this.samples.forEach((gSample, gIndex) => {
|
this.samples.forEach((gSample, gIndex) => {
|
||||||
if (this.d.id.conditionTemplates[gSample.condition.condition_template]) {
|
if (this.d.id.conditionTemplates[gSample.condition.condition_template]) {
|
||||||
this.d.id.conditionTemplates[gSample.condition.condition_template].parameters.forEach((parameter, pIndex) => {
|
this.d.id.conditionTemplates[gSample.condition.condition_template].parameters.forEach((parameter, pIndex) => {
|
||||||
this.attachValidator(this.cmForm, `conditionParameter-${gIndex}-${pIndex}`, parameter.range, true);
|
this.attachValidator(this.cmForm, `conditionParameter-${gIndex}-${pIndex}`, parameter.range);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
gSample.measurements.forEach((measurement, mIndex) => {
|
gSample.measurements.forEach((measurement, mIndex) => {
|
||||||
this.d.id.measurementTemplates[measurement.measurement_template].parameters.forEach((parameter, pIndex) => {
|
this.d.id.measurementTemplates[measurement.measurement_template].parameters.forEach((parameter, pIndex) => {
|
||||||
this.attachValidator(this.cmForm, `measurementParameter-${gIndex}-${mIndex}-${pIndex}`, parameter.range, false);
|
this.attachValidator(this.cmForm, `measurementParameter-${gIndex}-${mIndex}-${pIndex}`, parameter.range);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -253,7 +252,7 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
|
|
||||||
if (this.sampleForm && this.material.properties.material_template) { // material template is set
|
if (this.sampleForm && this.material.properties.material_template) { // material template is set
|
||||||
this.d.id.materialTemplates[this.material.properties.material_template].parameters.forEach((parameter, i) => {
|
this.d.id.materialTemplates[this.material.properties.material_template].parameters.forEach((parameter, i) => {
|
||||||
this.attachValidator(this.sampleForm, 'materialParameter' + i, parameter.range, true);
|
this.attachValidator(this.sampleForm, 'materialParameter' + i, parameter.range);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,10 +288,10 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// attach validators specified in range to input with name
|
// attach validators specified in range to input with name
|
||||||
attachValidator(form, name: string, range: {[prop: string]: any}, required: boolean) {
|
attachValidator(form, name: string, range: {[prop: string]: any}) {
|
||||||
if (form && form.form.get(name)) {
|
if (form && form.form.get(name)) {
|
||||||
const validators = [];
|
const validators = [];
|
||||||
if (required) {
|
if (range.hasOwnProperty('required')) {
|
||||||
validators.push(Validators.required);
|
validators.push(Validators.required);
|
||||||
}
|
}
|
||||||
if (range.hasOwnProperty('values')) {
|
if (range.hasOwnProperty('values')) {
|
||||||
@ -531,7 +530,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
|
|||||||
deleteConfirm(modal) {
|
deleteConfirm(modal) {
|
||||||
this.modal.open(modal).then(result => {
|
this.modal.open(modal).then(result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.api.delete('/sample/' + this.baseSample._id);
|
this.samples.forEach(sample => {
|
||||||
|
this.api.delete('/sample/' + sample._id);
|
||||||
|
});
|
||||||
this.router.navigate(['/samples']);
|
this.router.navigate(['/samples']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -199,6 +199,7 @@
|
|||||||
<td *ngFor="let key of activeTemplateKeys.condition">
|
<td *ngFor="let key of activeTemplateKeys.condition">
|
||||||
{{sample.condition ? sample.condition[key[1]] : '' | exists}}
|
{{sample.condition ? sample.condition[key[1]] : '' | exists}}
|
||||||
</td>
|
</td>
|
||||||
|
<td *ngIf="isActiveKey['notes.comment']">{{sample.notes | exists: 'comment'}}</td>
|
||||||
<td *ngIf="isActiveKey['notes']">{{sample.notes | object: ['_id', 'sample_references']}}</td>
|
<td *ngIf="isActiveKey['notes']">{{sample.notes | object: ['_id', 'sample_references']}}</td>
|
||||||
<td *ngFor="let key of activeTemplateKeys.measurements">{{sample[key[1]] | exists: key[2]}}</td>
|
<td *ngFor="let key of activeTemplateKeys.measurements">{{sample[key[1]] | exists: key[2]}}</td>
|
||||||
<td *ngIf="isActiveKey['status']">{{sample.status}}</td>
|
<td *ngIf="isActiveKey['status']">{{sample.status}}</td>
|
||||||
|
@ -64,7 +64,7 @@ export class SamplesComponent implements OnInit {
|
|||||||
{field: 'type', label: 'Type', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
{field: 'type', label: 'Type', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||||
{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.comment', label: 'Comment', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
{field: 'notes.comment', label: 'Comment', active: false, autocomplete: [], mode: 'eq', values: ['']},
|
||||||
{field: 'added', label: 'Added', active: false, autocomplete: [], mode: 'eq', values: ['']}
|
{field: 'added', label: 'Added', active: false, autocomplete: [], mode: 'eq', values: ['']}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -80,7 +80,7 @@ export class SamplesComponent implements OnInit {
|
|||||||
{id: 'type', label: 'Type', active: true, sortable: true},
|
{id: 'type', label: 'Type', active: true, sortable: true},
|
||||||
{id: 'color', label: 'Color', active: false, sortable: true},
|
{id: 'color', label: 'Color', active: false, sortable: true},
|
||||||
{id: 'batch', label: 'Batch', active: true, sortable: true},
|
{id: 'batch', label: 'Batch', active: true, sortable: true},
|
||||||
// {id: 'notes.comment', label: 'Comment', active: false, sortable: false},
|
{id: 'notes.comment', label: 'Comment', active: false, sortable: false},
|
||||||
{id: 'notes', label: 'Notes', active: false, sortable: false},
|
{id: 'notes', label: 'Notes', active: false, sortable: false},
|
||||||
{id: 'status', label: 'Status', active: false, sortable: true},
|
{id: 'status', label: 'Status', active: false, sortable: true},
|
||||||
{id: 'added', label: 'Added', active: true, sortable: true}
|
{id: 'added', label: 'Added', active: true, sortable: true}
|
||||||
@ -129,7 +129,7 @@ export class SamplesComponent implements OnInit {
|
|||||||
this.d.load('userKey', onLoad);
|
this.d.load('userKey', onLoad);
|
||||||
this.d.load('conditionTemplates', onLoad);
|
this.d.load('conditionTemplates', onLoad);
|
||||||
this.loadTemplateKeys('material', 'type', onLoad);
|
this.loadTemplateKeys('material', 'type', onLoad);
|
||||||
this.loadTemplateKeys('condition', 'notes', onLoad);
|
this.loadTemplateKeys('condition', 'notes.comment', onLoad);
|
||||||
this.loadTemplateKeys('measurement', 'status', onLoad);
|
this.loadTemplateKeys('measurement', 'status', onLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +177,10 @@ export class SamplesComponent implements OnInit {
|
|||||||
key.active = event[key.id];
|
key.active = event[key.id];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const sortId = this.filters.sort.replace(/(-asc|-desc)/, '');
|
||||||
|
if (event.hasOwnProperty(sortId) && !event[sortId]) { // reset sort if sort field was unselected
|
||||||
|
this.setSort('_id-asc');
|
||||||
|
}
|
||||||
this.updateActiveKeys();
|
this.updateActiveKeys();
|
||||||
}
|
}
|
||||||
this.loadSamplesQueue.push(options);
|
this.loadSamplesQueue.push(options);
|
||||||
@ -254,8 +258,8 @@ export class SamplesComponent implements OnInit {
|
|||||||
e.values = e.values.map(el => new Date(new Date(el).getTime() - new Date(el).getTimezoneOffset() * 60000).toISOString());
|
e.values = e.values.map(el => new Date(new Date(el).getTime() - new Date(el).getTimezoneOffset() * 60000).toISOString());
|
||||||
}
|
}
|
||||||
if (e.mode === 'null') {
|
if (e.mode === 'null') {
|
||||||
e.mode = 'eq';
|
e.mode = 'in';
|
||||||
e.values[0] = null;
|
e.values = [null, ''];
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
})
|
})
|
||||||
@ -346,7 +350,7 @@ 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.filters.filters.forEach(filter => {
|
this.filters.filters.forEach(filter => { // disable filters of fields not displayed
|
||||||
if (!this.isActiveKey[filter.field]) {
|
if (!this.isActiveKey[filter.field]) {
|
||||||
filter.active = false;
|
filter.active = false;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,9 @@ export class LoginService implements CanActivate {
|
|||||||
logout() {
|
logout() {
|
||||||
this.storage.remove('basicAuth');
|
this.storage.remove('basicAuth');
|
||||||
this.loggedIn = false;
|
this.loggedIn = false;
|
||||||
|
this.levels.forEach(level => {
|
||||||
|
this.isLevel[level] = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot = null, state: RouterStateSnapshot = null): Observable<boolean> {
|
canActivate(route: ActivatedRouteSnapshot = null, state: RouterStateSnapshot = null): Observable<boolean> {
|
||||||
|
@ -153,13 +153,12 @@ export class ValidationService {
|
|||||||
max: Joi.number(),
|
max: Joi.number(),
|
||||||
|
|
||||||
type: Joi.string()
|
type: Joi.string()
|
||||||
.valid('array')
|
.valid('string', 'number', 'boolean', 'array'),
|
||||||
|
|
||||||
|
required: Joi.boolean()
|
||||||
})
|
})
|
||||||
.oxor('values', 'min')
|
.oxor('values', 'min')
|
||||||
.oxor('values', 'max')
|
.oxor('values', 'max')
|
||||||
.oxor('type', 'values')
|
|
||||||
.oxor('type', 'min')
|
|
||||||
.oxor('type', 'max')
|
|
||||||
.required()
|
.required()
|
||||||
.validate(JSON.parse(data));
|
.validate(JSON.parse(data));
|
||||||
if (error) {
|
if (error) {
|
||||||
|
BIN
src/assets/imgs/key-visual.png
Normal file
BIN
src/assets/imgs/key-visual.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 394 KiB |
@ -42,3 +42,7 @@ button::-moz-focus-inner {
|
|||||||
.space-left {
|
.space-left {
|
||||||
margin-left: $default-spacing;
|
margin-left: $default-spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.supergraphic {
|
||||||
|
background-image: url("/assets/imgs/supergraphic.svg");
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user