added buttons for resetting to defaults in samples and changed defaults, added loading spinner and added apply filters button (again)
This commit is contained in:
		@@ -1,4 +1,4 @@
 | 
			
		||||
import { Component, isDevMode} from '@angular/core';
 | 
			
		||||
import {Component, isDevMode, OnInit} from '@angular/core';
 | 
			
		||||
import {LoginService} from './services/login.service';
 | 
			
		||||
import {NavigationStart, Router} from '@angular/router';
 | 
			
		||||
 | 
			
		||||
@@ -10,7 +10,7 @@ import {NavigationStart, Router} from '@angular/router';
 | 
			
		||||
  templateUrl: './app.component.html',
 | 
			
		||||
  styleUrls: ['./app.component.scss']
 | 
			
		||||
})
 | 
			
		||||
export class AppComponent {
 | 
			
		||||
export class AppComponent implements OnInit{
 | 
			
		||||
 | 
			
		||||
  bugReport = {do: '', work: ''};
 | 
			
		||||
  isDocumentation = false;
 | 
			
		||||
@@ -29,6 +29,10 @@ export class AppComponent {
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.login.login();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  logout() {
 | 
			
		||||
    this.login.logout();
 | 
			
		||||
    this.router.navigate(['/']);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,10 @@
 | 
			
		||||
<h2>Documentation</h2>
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
  Bosch IoT Cloud space where all applications are hosted:
 | 
			
		||||
  <a href="https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2">
 | 
			
		||||
    https://apps.sys.de1.bosch-iot-cloud.com/organizations/b28baba5-f95f-4ce5-bc9c-3f45acd1dfb2
 | 
			
		||||
  </a><br>
 | 
			
		||||
  Find the API documentation here:
 | 
			
		||||
  <a href="https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/">
 | 
			
		||||
    https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/
 | 
			
		||||
@@ -77,4 +81,13 @@
 | 
			
		||||
  </tr>
 | 
			
		||||
</rb-table>
 | 
			
		||||
 | 
			
		||||
<h4>Architecture</h4>
 | 
			
		||||
 | 
			
		||||
<img src="/assets/imgs/architecture.svg" alt="architecture" class="space-below">
 | 
			
		||||
 | 
			
		||||
<p>
 | 
			
		||||
  All applications are hosted in the bosch IoT Cloud. The API is hosted in a Node.js container, with a bound MongoDB
 | 
			
		||||
  instance. <br>
 | 
			
		||||
  The Angular UI is hosted in a staticfile container, serving the built Angular bundle. <br>
 | 
			
		||||
  Finally any machine learning models are hosted in Python containers.
 | 
			
		||||
</p>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import {ApiService} from '../services/api.service';
 | 
			
		||||
 | 
			
		||||
// TODO: links to BIC
 | 
			
		||||
// TODO: bic structure image
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-documentation',
 | 
			
		||||
 
 | 
			
		||||
@@ -261,5 +261,3 @@
 | 
			
		||||
    </ng-template>
 | 
			
		||||
  </form>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<button (click)="checkFormAfterInit = true">XXX</button>
 | 
			
		||||
 
 | 
			
		||||
@@ -50,11 +50,14 @@
 | 
			
		||||
        <span *rbFormMultiSelectOption="let item" class="load-first-page">{{item.label}}</span>
 | 
			
		||||
      </rb-form-multi-select>
 | 
			
		||||
 | 
			
		||||
      <rb-icon-button icon="reset" mode="secondary" (click)="resetPreferences()" class="reset-preferences">
 | 
			
		||||
        Reset to default
 | 
			
		||||
      </rb-icon-button>
 | 
			
		||||
 | 
			
		||||
      <div class="fieldfilters">
 | 
			
		||||
        <div *ngFor="let filter of filters.filters">
 | 
			
		||||
          <ng-container *ngIf="isActiveKey[filter.field]">
 | 
			
		||||
            <rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active"
 | 
			
		||||
                              (ngModelChange)="loadSamples({firstPage: true})"></rb-form-checkbox>
 | 
			
		||||
            <rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active"></rb-form-checkbox>
 | 
			
		||||
            <rb-form-select [name]="'filtermode-' + filter.field" class="filtermode" [(ngModel)]="filter.mode"
 | 
			
		||||
                            (ngModelChange)="updateFilterFields(filter.field)">
 | 
			
		||||
              <option value="eq" title="field is equal to value">=</option>
 | 
			
		||||
@@ -102,6 +105,10 @@
 | 
			
		||||
          </ng-container>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <rb-icon-button icon="forward-right" mode="primary" (click)="loadSamples({firstPage: true})">
 | 
			
		||||
        Apply filters
 | 
			
		||||
      </rb-icon-button>
 | 
			
		||||
    </form>
 | 
			
		||||
  </rb-accordion-body>
 | 
			
		||||
</rb-accordion>
 | 
			
		||||
@@ -109,6 +116,8 @@
 | 
			
		||||
 | 
			
		||||
<ng-container *ngTemplateOutlet="paging"></ng-container>
 | 
			
		||||
 | 
			
		||||
<rb-loading-spinner class="samples-loading" *ngIf="loading"></rb-loading-spinner>
 | 
			
		||||
 | 
			
		||||
<div class="download space-below" *ngIf="login.isLevel.dev">
 | 
			
		||||
  <rb-icon-button class="space-right" icon="download" mode="secondary" [rbModal]="linkModal">
 | 
			
		||||
    JSON download link
 | 
			
		||||
 
 | 
			
		||||
@@ -53,6 +53,8 @@ rb-table {
 | 
			
		||||
 | 
			
		||||
.paging {
 | 
			
		||||
  height: 50px;
 | 
			
		||||
  float: left;
 | 
			
		||||
 | 
			
		||||
  rb-form-input {
 | 
			
		||||
    max-width: 65px;
 | 
			
		||||
  }
 | 
			
		||||
@@ -232,3 +234,12 @@ textarea.linkmodal {
 | 
			
		||||
    float: right;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.samples-loading {
 | 
			
		||||
  float: left;
 | 
			
		||||
  transform: scale(0.5);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.reset-preferences {
 | 
			
		||||
  float: right;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,11 @@ import {DataService} from '../services/data.service';
 | 
			
		||||
import {LocalStorageService} from 'angular-2-local-storage';
 | 
			
		||||
 | 
			
		||||
// TODO: turn off sort field
 | 
			
		||||
// TODO reset sort when field is excluded
 | 
			
		||||
// TODO: material name to product
 | 
			
		||||
// TODO: Eh DPT
 | 
			
		||||
// TODO: filter button
 | 
			
		||||
// TODO: check if connect-src to model works
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
interface LoadSamplesOptions {
 | 
			
		||||
@@ -58,7 +63,6 @@ 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', label: 'Notes', active: false, autocomplete: [], mode: 'eq', values: ['']},
 | 
			
		||||
      {field: 'added', label: 'Added', active: false, autocomplete: [], mode: 'eq', values: ['']}
 | 
			
		||||
    ]
 | 
			
		||||
  };
 | 
			
		||||
@@ -69,13 +73,13 @@ export class SamplesComponent implements OnInit {
 | 
			
		||||
    {id: 'number', label: 'Number', active: true, sortable: true},
 | 
			
		||||
    {id: 'material.numbers', label: 'Material numbers', active: false, sortable: false},
 | 
			
		||||
    {id: 'material.name', label: 'Material name', active: true, sortable: true},
 | 
			
		||||
    {id: 'material.supplier', label: 'Supplier', active: true, sortable: true},
 | 
			
		||||
    {id: 'material.group', label: 'Material', active: false, 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: true, sortable: true},
 | 
			
		||||
    {id: 'color', label: 'Color', active: false, sortable: true},
 | 
			
		||||
    {id: 'batch', label: 'Batch', active: true, sortable: true},
 | 
			
		||||
    {id: 'notes', label: 'Notes', active: false, sortable: false},
 | 
			
		||||
    {id: 'status', label: 'Status', active: true, sortable: true},
 | 
			
		||||
    {id: 'status', label: 'Status', active: false, sortable: true},
 | 
			
		||||
    {id: 'added', label: 'Added', active: true, sortable: true}
 | 
			
		||||
  ];
 | 
			
		||||
  isActiveKey: {[key: string]: boolean} = {};
 | 
			
		||||
@@ -83,6 +87,7 @@ export class SamplesComponent implements OnInit {
 | 
			
		||||
  activeTemplateKeys = {material: [], condition: [], measurements: []};
 | 
			
		||||
  sampleDetailsSample: any = null;
 | 
			
		||||
  validation = false;  // true to activate validation mode
 | 
			
		||||
  loading = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
@@ -97,9 +102,9 @@ export class SamplesComponent implements OnInit {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
    let loading = 8;
 | 
			
		||||
    this.loading = 8;
 | 
			
		||||
    const onLoad = () => {
 | 
			
		||||
      if ((--loading) <= 0) {
 | 
			
		||||
      if ((--this.loading) <= 0) {
 | 
			
		||||
        this.loadSamples();
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
@@ -178,7 +183,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 --;
 | 
			
		||||
      if (err) {
 | 
			
		||||
        this.storage.remove('samplesPreferences');
 | 
			
		||||
        this.api.requestError(err);
 | 
			
		||||
@@ -317,12 +324,15 @@ export class SamplesComponent implements OnInit {
 | 
			
		||||
    this.updateActiveKeys();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO: avoid reloading
 | 
			
		||||
  resetPreferences() {
 | 
			
		||||
    this.storage.remove('samplesPreferences');
 | 
			
		||||
    this.window.location.reload();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  updateFilterFields(field) {
 | 
			
		||||
    const filter = this.filters.filters.find(e => e.field === field);
 | 
			
		||||
    filter.active = true;
 | 
			
		||||
    if (filter.active) {
 | 
			
		||||
      this.loadSamples({firstPage: true});
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setSort(string) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import {UserModel} from '../models/user.model';
 | 
			
		||||
import {LoginService} from '../services/login.service';
 | 
			
		||||
import {ModalService} from '@inst-iot/bosch-angular-ui-components';
 | 
			
		||||
 | 
			
		||||
// TODO: somehow mail change triggered
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-users',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user