diff --git a/src/app/home/home.component.html b/src/app/home/home.component.html
index 7f03ce2..f4d5282 100644
--- a/src/app/home/home.component.html
+++ b/src/app/home/home.component.html
@@ -1,3 +1,23 @@
-
+
+
+
+
-
+
+
+
+ {{key.id}}
+
+
+
+
+
+
+
+
diff --git a/src/app/home/home.component.ts b/src/app/home/home.component.ts
index 1cb0ce7..792bf95 100644
--- a/src/app/home/home.component.ts
+++ b/src/app/home/home.component.ts
@@ -1,5 +1,15 @@
import { Component, OnInit } from '@angular/core';
import {LoginService} from '../services/login.service';
+import { ApiService } from '../services/api.service';
+import {Chart} from 'chart.js';
+
+
+
+interface KeyInterface {
+ id: string;
+ count: number;
+ active: boolean;
+}
@Component({
selector: 'app-home',
@@ -8,11 +18,121 @@ import {LoginService} from '../services/login.service';
})
export class HomeComponent implements OnInit {
+ keys: KeyInterface[] = [];
+ isActiveKey: { [key: string]: boolean } = {}; // object to check if key is currently active
+ myChart: Chart;
+
constructor(
- public login: LoginService
+ public login: LoginService,
+ public api: ApiService
) { }
ngOnInit() {
+ // fetch all available groups
+ this.fetchData('/material/groups', data => this.createGroup(data));
+ //this.initChart();
+ console.log(this.login.username);
}
+ // api access with callback
+ async fetchData(URL: string, processor: any) {
+ this.api.get(URL, (sData, err, headers) => {
+ processor(sData);
+ });
+ }
+
+ // Fill interface with data
+ createGroup(data: any) {
+ let temp: KeyInterface[] = [];
+
+ for (var i = 0; i < data.length; i++) {
+ temp.push({ id: data[i], count: 0, active: false });
+ }
+ this.keys = temp; // invoke update in rb-multiselect
+ this.calcFieldSelectKeys();
+ // fetch all samples populated with according group
+ this.fetchData('/samples?status%5B%5D=validated&status=new&page-size=10&sort=_id-asc&fields%5B%5D=material.group', data => this.countSamples(data));
+ }
+
+ // loop through samples and count
+ countSamples(data: any) {
+ for (var i = 0; i < data.length; i++) {
+ this.keys.forEach(key => {
+ if (key.id === data[i].material.group) {
+ key.count += 1;
+ }
+ });
+ }
+ this.initChart();
+ }
+
+ // preset select
+ calcFieldSelectKeys() {
+ this.keys.forEach(key => {
+ this.isActiveKey[key.id] = key.active;
+ });
+ }
+
+ // update keys based on select
+ updateGroups(event: any) {
+ this.keys.forEach(key => {
+ if (event.hasOwnProperty(key.id)) {
+ key.active = event[key.id];
+ }
+ });
+ this.myChart.destroy();
+ this.initChart();
+ }
+
+ // get data for graph based on active keys
+ async getData() {
+ let nameList: string[] = [];
+ let dataList: number[] = [];
+
+ this.keys.forEach(key => {
+ if (key.active) {
+ nameList.push(key.id);
+ dataList.push(key.count);
+ }
+ })
+ return { names: nameList, data: dataList };
+ }
+
+ // draw graph
+ async initChart() {
+ const data = await this.getData();
+
+ const canvas = document.getElementById('myChart') as HTMLCanvasElement;
+ const width = canvas.clientWidth;
+ const height = canvas.clientHeight;
+ const ctx = canvas.getContext('2d');
+
+ var img = new Image(width, height);
+ img.src = "/assets/imgs/supergraphic.svg";
+ img.onload = () => {
+ const fillPattern = ctx.createPattern(img, 'no-repeat');
+
+ this.myChart = new Chart("myChart", {
+ type: 'line',
+ data: {
+ labels: data.names,
+ datasets: [{
+ label: 'Number of samples per group',
+ data: data.data,
+ backgroundColor: fillPattern,
+ borderWidth: 2
+ }]
+ },
+ options: {
+ scales: {
+ yAxes: [{
+ ticks: {
+ beginAtZero: true
+ }
+ }]
+ }
+ }
+ });
+ }
+ }
}
diff --git a/src/app/samples/samples.component.ts b/src/app/samples/samples.component.ts
index 9ec3226..c8f598e 100644
--- a/src/app/samples/samples.component.ts
+++ b/src/app/samples/samples.component.ts
@@ -1,23 +1,22 @@
-import {Component, ElementRef, isDevMode, OnInit, TemplateRef, ViewChild} from '@angular/core';
-import {ApiService} from '../services/api.service';
-import {AutocompleteService} from '../services/autocomplete.service';
+import { Component, ElementRef, isDevMode, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { ApiService } from '../services/api.service';
+import { AutocompleteService } from '../services/autocomplete.service';
import cloneDeep from 'lodash/cloneDeep';
import pick from 'lodash/pick';
import omit from 'lodash/omit';
-import {SampleModel} from '../models/sample.model';
-import {LoginService} from '../services/login.service';
-import {ModalService} from '@inst-iot/bosch-angular-ui-components';
-import {DataService} from '../services/data.service';
-import {LocalStorageService} from 'angular-2-local-storage';
-import {Router} from '@angular/router';
-
-
+import { SampleModel } from '../models/sample.model';
+import { LoginService } from '../services/login.service';
+import { ModalService } from '@inst-iot/bosch-angular-ui-components';
+import { DataService } from '../services/data.service';
+import { LocalStorageService } from 'angular-2-local-storage';
+import { Router } from '@angular/router';
interface LoadSamplesOptions {
toPage?: number;
event?: Event;
firstPage?: boolean;
}
+
interface KeyInterface {
id: string;
label: string;
@@ -43,46 +42,46 @@ export class SamplesComponent implements OnInit {
totalSamples = 0; // total number of samples
csvUrl = ''; // store url separate so it only has to be generated when clicking the download button
filters = {
- status: {new: true, validated: true, deleted: false},
+ status: { new: true, validated: true, deleted: false },
pageSize: 25,
toPage: 0,
sort: 'added-asc',
- no: {condition: false, measurements: false},
+ no: { condition: false, measurements: false },
filters: [
- {field: 'number', label: 'Number', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.name', label: 'Product name', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.supplier', label: 'Supplier', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.group', label: 'Material', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.glass_fiber', label: 'GF', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.carbon_fiber', label: 'CF', active: false, autocomplete: [], mode: 'eq', values: ['']},
- {field: 'material.mineral', label: 'M', 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: 'batch', label: 'Batch', 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: 'number', label: 'Number', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.name', label: 'Product name', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.supplier', label: 'Supplier', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.group', label: 'Material', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.glass_fiber', label: 'GF', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.carbon_fiber', label: 'CF', active: false, autocomplete: [], mode: 'eq', values: [''] },
+ { field: 'material.mineral', label: 'M', 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: 'batch', label: 'Batch', 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: [''] }
]
};
page = 1; // current page
pages = 1; // total number of pages
loadSamplesQueue = []; // arguments of queued up loadSamples() calls
keys: KeyInterface[] = [
- {id: 'number', label: 'Number', active: true, sortable: true},
- {id: 'material.numbers', label: 'Material numbers', active: false, sortable: false},
- {id: 'material.name', label: 'Product name', active: true, sortable: true},
- {id: 'material.supplier', label: 'Supplier', active: false, sortable: true},
- {id: 'material.group', label: 'Material', active: true, sortable: true},
- {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', label: 'Notes', active: false, sortable: false},
- {id: 'status', label: 'Status', active: false, sortable: true},
- {id: 'added', label: 'Added', active: true, sortable: true}
+ { id: 'number', label: 'Number', active: true, sortable: true },
+ { id: 'material.numbers', label: 'Material numbers', active: false, sortable: false },
+ { id: 'material.name', label: 'Product name', active: true, sortable: true },
+ { id: 'material.supplier', label: 'Supplier', active: false, sortable: true },
+ { id: 'material.group', label: 'Material', active: true, sortable: true },
+ { 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', label: 'Notes', active: false, sortable: false },
+ { id: 'status', label: 'Status', active: false, sortable: true },
+ { id: 'added', label: 'Added', active: true, sortable: true }
];
- isActiveKey: {[key: string]: boolean} = {}; // object to check if key is currently active
+ isActiveKey: { [key: string]: boolean } = {}; // object to check if key is currently active
activeKeys: KeyInterface[] = []; // list of active keys
- activeTemplateKeys = {material: [], condition: [], measurements: []};
+ activeTemplateKeys = { material: [], condition: [], measurements: [] };
sampleDetailsSample: any = null; // sample for the sample details dialog
sampleSelect = 0; // modes: 0 - no selection, 1 - sample edit selection, 2 - validation selection
loading = 0; // number of loading instances
@@ -105,7 +104,7 @@ export class SamplesComponent implements OnInit {
const onLoad = () => {
if ((--this.loading) <= 0) {
this.loadSamples();
- }
+ }
};
this.calcFieldSelectKeys();
@@ -164,10 +163,11 @@ export class SamplesComponent implements OnInit {
f();
});
}
-
+
// set toPage to null to reload first page, queues calls
loadSamples(options: LoadSamplesOptions = {}, event = null) {
if (event) { // adjust active keys
+ console.log(event);
this.keys.forEach(key => {
if (event.hasOwnProperty(key.id)) {
key.active = event[key.id];
@@ -179,9 +179,9 @@ export class SamplesComponent implements OnInit {
}
this.updateActiveKeys();
}
- if(options.firstPage){
- this.storage.set('currentPage', 1);
- }
+ if(options.firstPage){
+ this.storage.set('currentPage', 1);
+ }
this.loadSamplesQueue.push(options);
if (this.loadSamplesQueue.length <= 1) { // nothing queued up
this.sampleLoader(this.loadSamplesQueue[0]);
@@ -190,9 +190,9 @@ export class SamplesComponent implements OnInit {
}
private sampleLoader(options: LoadSamplesOptions) { // actual loading of the sample, do not call directly
- this.loading ++;
- this.api.get(this.sampleUrl({paging: true, pagingOptions: options}), (sData, err, headers) => {
- this.loading --;
+ this.loading++;
+ this.api.get(this.sampleUrl({ paging: true, pagingOptions: options }), (sData, err, headers) => {
+ this.loading--;
if (err) { // remove stored options on error to avoid loop
this.storage.remove('samplesPreferences');
this.api.requestError(err);
@@ -209,9 +209,9 @@ export class SamplesComponent implements OnInit {
}
}
});
- if(this.storage.get('currentPage') !== this.page){
- this.loadPage(Number(this.storage.get('currentPage')) - this.page);
- }
+ if(this.storage.get('currentPage') !== this.page){
+ this.loadPage(Number(this.storage.get('currentPage')) - this.page);
+ }
}
sampleUrl(options: {
@@ -272,17 +272,17 @@ export class SamplesComponent implements OnInit {
.map(e => 'filters[]=' + encodeURIComponent(JSON.stringify(pick(e, ['mode', 'field', 'values']))))
);
if (this.filters.no.condition) {
- query.push('filters[]=' + encodeURIComponent( JSON.stringify({mode: 'eq', field: 'condition', values: [{}]})));
+ query.push('filters[]=' + encodeURIComponent(JSON.stringify({ mode: 'eq', field: 'condition', values: [{}] })));
}
if (this.filters.no.measurements) {
query.push('filters[]=' +
- encodeURIComponent( JSON.stringify( {mode: 'eq', field: 'measurements', values: [null]})));
+ encodeURIComponent(JSON.stringify({ mode: 'eq', field: 'measurements', values: [null] })));
}
if (!options.export) {
additionalTableKeys.forEach(key => {
- if (query.indexOf('fields[]=' + key) < 0) { // add key if not already added
- query.push('fields[]=' + key);
- }
+ if (query.indexOf('fields[]=' + key) < 0) { // add key if not already added
+ query.push('fields[]=' + key);
+ }
});
}
else { // export options
@@ -307,10 +307,10 @@ export class SamplesComponent implements OnInit {
loadPage(delta) {
if (!/[0-9]+/.test(delta) || this.page + delta < 1) { // invalid delta
return;
- }
- this.page += delta;
- this.storage.set('currentPage', this.page);
- this.loadSamples({toPage: delta});
+ }
+ this.page += delta;
+ this.storage.set('currentPage', this.page);
+ this.loadSamples({ toPage: delta });
}
storePreferences() {
@@ -327,11 +327,11 @@ export class SamplesComponent implements OnInit {
loadPreferences() {
const store: any = this.storage.get('samplesPreferences');
if (store) {
- this.filters = {...this.filters, ...pick(store.filters, ['status', 'pageSize', 'toPage', 'sort'])};
+ this.filters = { ...this.filters, ...pick(store.filters, ['status', 'pageSize', 'toPage', 'sort']) };
store.filters.filters.forEach(filter => {
const filterIndex = this.filters.filters.findIndex(e => e.field === filter.field);
if (filterIndex >= 0) {
- this.filters.filters[filterIndex] = {...this.filters.filters[filterIndex], ...filter};
+ this.filters.filters[filterIndex] = { ...this.filters.filters[filterIndex], ...filter };
}
});
store.keys.forEach(key => {
@@ -357,7 +357,7 @@ export class SamplesComponent implements OnInit {
setSort(string) {
this.filters.sort = string;
- this.loadSamples({firstPage: true});
+ this.loadSamples({ firstPage: true });
}
updateActiveKeys() { // array with all activeKeys
@@ -399,12 +399,12 @@ export class SamplesComponent implements OnInit {
if (Object.keys(data.condition).length) { // convert condition
this.sampleDetailsSample.condition_entries =
Object.entries(omit(this.sampleDetailsSample.condition, ['condition_template']))
- .map(e => {
- e[0] = `${this.ucFirst(
- this.d.id.conditionTemplates[this.sampleDetailsSample.condition.condition_template].name
- )} ${e[0]}`;
- return e;
- });
+ .map(e => {
+ e[0] = `${this.ucFirst(
+ this.d.id.conditionTemplates[this.sampleDetailsSample.condition.condition_template].name
+ )} ${e[0]}`;
+ return e;
+ });
}
else {
this.sampleDetailsSample.condition_entries = [];
@@ -415,7 +415,7 @@ export class SamplesComponent implements OnInit {
const name = this.d.id.measurementTemplates[measurement.measurement_template].name;
this.sampleDetailsSample.measurement_entries
.push(...Object.entries(measurement.values).filter(e => e[0] !== 'dpt')
- .map(e => ({name: this.ucFirst(name) + ' ' + e[0], value: e[1]})));
+ .map(e => ({ name: this.ucFirst(name) + ' ' + e[0], value: e[1] })));
});
new Promise(resolve => {
if (data.notes.sample_references.length) { // load referenced samples if available
@@ -423,7 +423,7 @@ export class SamplesComponent implements OnInit {
this.sampleDetailsSample.notes.sample_references.forEach(reference => {
this.api.get('/sample/' + reference.sample_id, rData => {
reference.number = rData.number;
- loadingCounter --;
+ loadingCounter--;
if (!loadingCounter) {
resolve();
}
@@ -434,7 +434,7 @@ export class SamplesComponent implements OnInit {
resolve();
}
}).then(() => {
- this.modalService.open(modal).then(() => {});
+ this.modalService.open(modal).then(() => { });
});
});
}