diff --git a/src/app/app.component.html b/src/app/app.component.html
index e32372c..d98d743 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -37,7 +37,9 @@
- Bug
+
+ Bug
+
Report a bug
@@ -46,7 +48,7 @@
Send report
- DEVELOPMENT
+ DEVELOPMENT
DeFinMa
diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 3317c9b..7f03ce2 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1 +1,3 @@
-
+
+
+
diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss
index e69de29..4ae35d4 100644
--- a/src/app/home/home.component.scss
+++ b/src/app/home/home.component.scss
@@ -0,0 +1,8 @@
+app-login {
+ float: left;
+}
+
+.key-visual {
+ width: 70%;
+ float: right;
+}
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index f56c8c1..1cb0ce7 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
+import {LoginService} from '../services/login.service';
@Component({
selector: 'app-home',
@@ -7,7 +8,9 @@ import { Component, OnInit } from '@angular/core';
})
export class HomeComponent implements OnInit {
- constructor() { }
+ constructor(
+ public login: LoginService
+ ) { }
ngOnInit() {
}
diff --git a/src/app/sample/sample.component.html b/src/app/sample/sample.component.html
index 61de958..cc94873 100644
--- a/src/app/sample/sample.component.html
+++ b/src/app/sample/sample.component.html
@@ -139,6 +139,10 @@
[disabled]="!sampleForm.form.valid">
Save sample
+ 1"
+ (click)="deleteConfirm(modalDeleteConfirm)">
+ Delete samples
+
Summary
-
Delete sample
-
-
- Do you really want to delete this sample?
-
-
@@ -322,3 +321,9 @@
+
+
+ 1 ? 's' : '')" cancelBtnLabel="Cancel">
+ Do you really want to delete {{samples.length > 1 ? 'these samples' : 'this sample'}}?
+
+
diff --git a/src/app/sample/sample.component.ts b/src/app/sample/sample.component.ts
index 888b267..cdcfa03 100644
--- a/src/app/sample/sample.component.ts
+++ b/src/app/sample/sample.component.ts
@@ -176,57 +176,56 @@ export class SampleComponent implements OnInit, AfterContentChecked {
this.view.base = true;
}
this.loading += sampleIds.length;
- this.samples = [];
- sampleIds.forEach((sampleId, i) => {
- this.api.get('/sample/' + sampleId, sData => {
- this.samples.push(new SampleModel().deserialize(sData));
- if (i === 0) {
- this.baseSample.deserialize(sData);
- this.material = new MaterialModel().deserialize(sData.material); // read material
- this.customFields = this.baseSample.notes.custom_fields && this.baseSample.notes.custom_fields !== {} ? // read custom fields
- Object.keys(this.baseSample.notes.custom_fields).map(e => [e, this.baseSample.notes.custom_fields[e]]) : [];
- if (this.baseSample.notes.sample_references.length) { // read sample references
- this.sampleReferences = [];
- this.sampleReferenceAutocomplete = [];
- let loadCounter = this.baseSample.notes.sample_references.length; // count down instances still loading
- this.baseSample.notes.sample_references.forEach(reference => {
- this.api.get('/sample/' + reference.sample_id, srData => { // get sample numbers for ids
- this.sampleReferences.push([srData.number, reference.relation, reference.sample_id]);
- this.sampleReferenceAutocomplete.push([srData.number]);
- if (!--loadCounter) { // insert empty template when all instances were loaded
- this.sampleReferences.push(['', '', '']);
- this.sampleReferenceAutocomplete.push([]);
- }
- });
- });
+ this.api.get('/sample/' + sampleIds[0], sData => { // special treatment for first id
+ this.samples = [new SampleModel().deserialize(sData)];
+ this.baseSample.deserialize(sData);
+ this.material = new MaterialModel().deserialize(sData.material); // read material
+ this.customFields = this.baseSample.notes.custom_fields && this.baseSample.notes.custom_fields !== {} ? // read custom fields
+ Object.keys(this.baseSample.notes.custom_fields).map(e => [e, this.baseSample.notes.custom_fields[e]]) : [];
+ if (this.baseSample.notes.sample_references.length) { // read sample references
+ this.sampleReferences = [];
+ this.sampleReferenceAutocomplete = [];
+ let loadCounter = this.baseSample.notes.sample_references.length; // count down instances still loading
+ this.baseSample.notes.sample_references.forEach(reference => {
+ this.api.get('/sample/' + reference.sample_id, srData => { // get sample numbers for ids
+ this.sampleReferences.push([srData.number, reference.relation, reference.sample_id]);
+ this.sampleReferenceAutocomplete.push([srData.number]);
+ if (!--loadCounter) { // insert empty template when all instances were loaded
+ this.sampleReferences.push(['', '', '']);
+ this.sampleReferenceAutocomplete.push([]);
+ }
+ });
+ });
+ }
+ if (this.mode === 'editOne') {
+ this.charts = [[]];
+ let spectrumCounter = 0; // generate charts for spectrum measurements
+ this.samples[0].measurements.forEach((measurement, i) => {
+ this.charts[0].push(cloneDeep(this.chartInit));
+ if (measurement.values.dpt) {
+ setTimeout(() => {
+ this.generateChart(measurement.values.dpt, 0, i);
+ }, spectrumCounter * 20); // generate charts one after another to avoid freezing the UI
+ spectrumCounter ++;
}
- if (this.mode === 'editOne') {
- this.charts = [[]];
- let spectrumCounter = 0; // generate charts for spectrum measurements
- this.samples[i].measurements.forEach((measurement, j) => {
- this.charts[i].push(cloneDeep(this.chartInit));
- if (measurement.values.dpt) {
- setTimeout(() => {
- this.generateChart(measurement.values.dpt, 0, j);
- }, spectrumCounter * 20); // generate charts one after another to avoid freezing the UI
- spectrumCounter ++;
- }
- });
- }
- this.checkFormAfterInit = true;
- }
- else {
+ });
+ }
+ this.loading--;
+ sampleIds.slice(1).forEach(sampleId => {
+ this.api.get('/sample/' + sampleId, data => {
+ this.samples.push(new SampleModel().deserialize(data));
['type', 'color', 'batch', 'notes'].forEach((key) => {
- console.log(isEqual(sData[key], this.baseSample[key]));
- if (!isEqual(sData[key], this.baseSample[key])) {
+ console.log(isEqual(data[key], this.baseSample[key]));
+ if (!isEqual(data[key], this.baseSample[key])) {
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.loading--;
+ this.loading--;
+ this.checkFormAfterInit = true;
+ });
});
});
}
@@ -240,12 +239,12 @@ export class SampleComponent implements OnInit, AfterContentChecked {
this.samples.forEach((gSample, gIndex) => {
if (this.d.id.conditionTemplates[gSample.condition.condition_template]) {
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) => {
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
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
- attachValidator(form, name: string, range: {[prop: string]: any}, required: boolean) {
+ attachValidator(form, name: string, range: {[prop: string]: any}) {
if (form && form.form.get(name)) {
const validators = [];
- if (required) {
+ if (range.hasOwnProperty('required')) {
validators.push(Validators.required);
}
if (range.hasOwnProperty('values')) {
@@ -531,7 +530,9 @@ export class SampleComponent implements OnInit, AfterContentChecked {
deleteConfirm(modal) {
this.modal.open(modal).then(result => {
if (result) {
- this.api.delete('/sample/' + this.baseSample._id);
+ this.samples.forEach(sample => {
+ this.api.delete('/sample/' + sample._id);
+ });
this.router.navigate(['/samples']);
}
});
diff --git a/src/app/samples/samples.component.html b/src/app/samples/samples.component.html
index ec9a033..52d0898 100644
--- a/src/app/samples/samples.component.html
+++ b/src/app/samples/samples.component.html
@@ -199,6 +199,7 @@
{{sample.condition ? sample.condition[key[1]] : '' | exists}}
|
+ {{sample.notes | exists: 'comment'}} |
{{sample.notes | object: ['_id', 'sample_references']}} |
{{sample[key[1]] | exists: key[2]}} |
{{sample.status}} |
diff --git a/src/app/samples/samples.component.ts b/src/app/samples/samples.component.ts
index 08f5b19..33ce4fd 100644
--- a/src/app/samples/samples.component.ts
+++ b/src/app/samples/samples.component.ts
@@ -64,7 +64,7 @@ export class SamplesComponent implements OnInit {
{field: 'type', label: 'Type', 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: '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: ['']}
]
};
@@ -80,7 +80,7 @@ export class SamplesComponent implements OnInit {
{id: 'type', label: 'Type', active: true, sortable: true},
{id: 'color', label: 'Color', active: false, 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: 'status', label: 'Status', active: false, 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('conditionTemplates', onLoad);
this.loadTemplateKeys('material', 'type', onLoad);
- this.loadTemplateKeys('condition', 'notes', onLoad);
+ this.loadTemplateKeys('condition', 'notes.comment', onLoad);
this.loadTemplateKeys('measurement', 'status', onLoad);
}
@@ -177,6 +177,10 @@ export class SamplesComponent implements OnInit {
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.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());
}
if (e.mode === 'null') {
- e.mode = 'eq';
- e.values[0] = null;
+ e.mode = 'in';
+ e.values = [null, ''];
}
return e;
})
@@ -346,7 +350,7 @@ export class SamplesComponent implements OnInit {
updateActiveKeys() { // array with all activeKeys
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]) {
filter.active = false;
}
diff --git a/src/app/services/login.service.ts b/src/app/services/login.service.ts
index 05b14f3..e8dd0db 100644
--- a/src/app/services/login.service.ts
+++ b/src/app/services/login.service.ts
@@ -80,6 +80,9 @@ export class LoginService implements CanActivate {
logout() {
this.storage.remove('basicAuth');
this.loggedIn = false;
+ this.levels.forEach(level => {
+ this.isLevel[level] = false;
+ });
}
canActivate(route: ActivatedRouteSnapshot = null, state: RouterStateSnapshot = null): Observable {
diff --git a/src/app/services/validation.service.ts b/src/app/services/validation.service.ts
index 0deb86e..8584154 100644
--- a/src/app/services/validation.service.ts
+++ b/src/app/services/validation.service.ts
@@ -153,13 +153,12 @@ export class ValidationService {
max: Joi.number(),
type: Joi.string()
- .valid('array')
+ .valid('string', 'number', 'boolean', 'array'),
+
+ required: Joi.boolean()
})
.oxor('values', 'min')
.oxor('values', 'max')
- .oxor('type', 'values')
- .oxor('type', 'min')
- .oxor('type', 'max')
.required()
.validate(JSON.parse(data));
if (error) {
diff --git a/src/assets/imgs/key-visual.png b/src/assets/imgs/key-visual.png
new file mode 100644
index 0000000..a6e2633
Binary files /dev/null and b/src/assets/imgs/key-visual.png differ
diff --git a/src/styles.scss b/src/styles.scss
index fbc3cbc..339b355 100644
--- a/src/styles.scss
+++ b/src/styles.scss
@@ -42,3 +42,7 @@ button::-moz-focus-inner {
.space-left {
margin-left: $default-spacing;
}
+
+.supergraphic {
+ background-image: url("/assets/imgs/supergraphic.svg");
+}