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 @@
 | 
				
			|||||||
add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; connect-src https://definma-api.apps.de1.bosch-iot-cloud.com; form-action 'none'; frame-ancestors 'none'; base-uri 'self'";
 | 
					add_header Content-Security-Policy "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; font-src 'self'; connect-src https://*.apps.de1.bosch-iot-cloud.com; form-action 'none'; frame-ancestors 'none'; base-uri 'self'";
 | 
				
			||||||
add_header X-Frame-Options DENY;
 | 
					add_header X-Frame-Options DENY;
 | 
				
			||||||
add_header X-DNS-Prefetch-Control off;
 | 
					add_header X-DNS-Prefetch-Control off;
 | 
				
			||||||
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
 | 
					add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Component, isDevMode} from '@angular/core';
 | 
					import {Component, isDevMode, OnInit} from '@angular/core';
 | 
				
			||||||
import {LoginService} from './services/login.service';
 | 
					import {LoginService} from './services/login.service';
 | 
				
			||||||
import {NavigationStart, Router} from '@angular/router';
 | 
					import {NavigationStart, Router} from '@angular/router';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,7 +10,7 @@ import {NavigationStart, Router} from '@angular/router';
 | 
				
			|||||||
  templateUrl: './app.component.html',
 | 
					  templateUrl: './app.component.html',
 | 
				
			||||||
  styleUrls: ['./app.component.scss']
 | 
					  styleUrls: ['./app.component.scss']
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class AppComponent {
 | 
					export class AppComponent implements OnInit{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bugReport = {do: '', work: ''};
 | 
					  bugReport = {do: '', work: ''};
 | 
				
			||||||
  isDocumentation = false;
 | 
					  isDocumentation = false;
 | 
				
			||||||
@@ -29,6 +29,10 @@ export class AppComponent {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit() {
 | 
				
			||||||
 | 
					    this.login.login();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  logout() {
 | 
					  logout() {
 | 
				
			||||||
    this.login.logout();
 | 
					    this.login.logout();
 | 
				
			||||||
    this.router.navigate(['/']);
 | 
					    this.router.navigate(['/']);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,10 @@
 | 
				
			|||||||
<h2>Documentation</h2>
 | 
					<h2>Documentation</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p>
 | 
					<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:
 | 
					  Find the API documentation here:
 | 
				
			||||||
  <a href="https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/">
 | 
					  <a href="https://definma-api.apps.de1.bosch-iot-cloud.com/api-doc/">
 | 
				
			||||||
    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>
 | 
					  </tr>
 | 
				
			||||||
</rb-table>
 | 
					</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 { Component, OnInit } from '@angular/core';
 | 
				
			||||||
import {ApiService} from '../services/api.service';
 | 
					import {ApiService} from '../services/api.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: links to BIC
 | 
					 | 
				
			||||||
// TODO: bic structure image
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-documentation',
 | 
					  selector: 'app-documentation',
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -261,5 +261,3 @@
 | 
				
			|||||||
    </ng-template>
 | 
					    </ng-template>
 | 
				
			||||||
  </form>
 | 
					  </form>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
<button (click)="checkFormAfterInit = true">XXX</button>
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -50,11 +50,14 @@
 | 
				
			|||||||
        <span *rbFormMultiSelectOption="let item" class="load-first-page">{{item.label}}</span>
 | 
					        <span *rbFormMultiSelectOption="let item" class="load-first-page">{{item.label}}</span>
 | 
				
			||||||
      </rb-form-multi-select>
 | 
					      </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 class="fieldfilters">
 | 
				
			||||||
        <div *ngFor="let filter of filters.filters">
 | 
					        <div *ngFor="let filter of filters.filters">
 | 
				
			||||||
          <ng-container *ngIf="isActiveKey[filter.field]">
 | 
					          <ng-container *ngIf="isActiveKey[filter.field]">
 | 
				
			||||||
            <rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active"
 | 
					            <rb-form-checkbox [name]="'filteractive-' + filter.field" [(ngModel)]="filter.active"></rb-form-checkbox>
 | 
				
			||||||
                              (ngModelChange)="loadSamples({firstPage: true})"></rb-form-checkbox>
 | 
					 | 
				
			||||||
            <rb-form-select [name]="'filtermode-' + filter.field" class="filtermode" [(ngModel)]="filter.mode"
 | 
					            <rb-form-select [name]="'filtermode-' + filter.field" class="filtermode" [(ngModel)]="filter.mode"
 | 
				
			||||||
                            (ngModelChange)="updateFilterFields(filter.field)">
 | 
					                            (ngModelChange)="updateFilterFields(filter.field)">
 | 
				
			||||||
              <option value="eq" title="field is equal to value">=</option>
 | 
					              <option value="eq" title="field is equal to value">=</option>
 | 
				
			||||||
@@ -102,6 +105,10 @@
 | 
				
			|||||||
          </ng-container>
 | 
					          </ng-container>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <rb-icon-button icon="forward-right" mode="primary" (click)="loadSamples({firstPage: true})">
 | 
				
			||||||
 | 
					        Apply filters
 | 
				
			||||||
 | 
					      </rb-icon-button>
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
  </rb-accordion-body>
 | 
					  </rb-accordion-body>
 | 
				
			||||||
</rb-accordion>
 | 
					</rb-accordion>
 | 
				
			||||||
@@ -109,6 +116,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<ng-container *ngTemplateOutlet="paging"></ng-container>
 | 
					<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">
 | 
					<div class="download space-below" *ngIf="login.isLevel.dev">
 | 
				
			||||||
  <rb-icon-button class="space-right" icon="download" mode="secondary" [rbModal]="linkModal">
 | 
					  <rb-icon-button class="space-right" icon="download" mode="secondary" [rbModal]="linkModal">
 | 
				
			||||||
    JSON download link
 | 
					    JSON download link
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,6 +53,8 @@ rb-table {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.paging {
 | 
					.paging {
 | 
				
			||||||
  height: 50px;
 | 
					  height: 50px;
 | 
				
			||||||
 | 
					  float: left;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rb-form-input {
 | 
					  rb-form-input {
 | 
				
			||||||
    max-width: 65px;
 | 
					    max-width: 65px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -232,3 +234,12 @@ textarea.linkmodal {
 | 
				
			|||||||
    float: right;
 | 
					    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';
 | 
					import {LocalStorageService} from 'angular-2-local-storage';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: turn off sort field
 | 
					// 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 {
 | 
					interface LoadSamplesOptions {
 | 
				
			||||||
@@ -58,7 +63,6 @@ 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', label: 'Notes', 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: ['']}
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
@@ -69,13 +73,13 @@ export class SamplesComponent implements OnInit {
 | 
				
			|||||||
    {id: 'number', label: 'Number', active: true, sortable: true},
 | 
					    {id: 'number', label: 'Number', active: true, sortable: true},
 | 
				
			||||||
    {id: 'material.numbers', label: 'Material numbers', active: false, sortable: false},
 | 
					    {id: 'material.numbers', label: 'Material numbers', active: false, sortable: false},
 | 
				
			||||||
    {id: 'material.name', label: 'Material name', active: true, sortable: true},
 | 
					    {id: 'material.name', label: 'Material name', active: true, sortable: true},
 | 
				
			||||||
    {id: 'material.supplier', label: 'Supplier', active: true, sortable: true},
 | 
					    {id: 'material.supplier', label: 'Supplier', active: false, sortable: true},
 | 
				
			||||||
    {id: 'material.group', label: 'Material', active: false, sortable: true},
 | 
					    {id: 'material.group', label: 'Material', active: true, sortable: true},
 | 
				
			||||||
    {id: 'type', label: 'Type', 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: 'batch', label: 'Batch', active: true, sortable: true},
 | 
				
			||||||
    {id: 'notes', label: 'Notes', active: false, sortable: false},
 | 
					    {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}
 | 
					    {id: 'added', label: 'Added', active: true, sortable: true}
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
  isActiveKey: {[key: string]: boolean} = {};
 | 
					  isActiveKey: {[key: string]: boolean} = {};
 | 
				
			||||||
@@ -83,6 +87,7 @@ export class SamplesComponent implements OnInit {
 | 
				
			|||||||
  activeTemplateKeys = {material: [], condition: [], measurements: []};
 | 
					  activeTemplateKeys = {material: [], condition: [], measurements: []};
 | 
				
			||||||
  sampleDetailsSample: any = null;
 | 
					  sampleDetailsSample: any = null;
 | 
				
			||||||
  validation = false;  // true to activate validation mode
 | 
					  validation = false;  // true to activate validation mode
 | 
				
			||||||
 | 
					  loading = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
@@ -97,9 +102,9 @@ export class SamplesComponent implements OnInit {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    let loading = 8;
 | 
					    this.loading = 8;
 | 
				
			||||||
    const onLoad = () => {
 | 
					    const onLoad = () => {
 | 
				
			||||||
      if ((--loading) <= 0) {
 | 
					      if ((--this.loading) <= 0) {
 | 
				
			||||||
        this.loadSamples();
 | 
					        this.loadSamples();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
@@ -178,7 +183,9 @@ export class SamplesComponent implements OnInit {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private sampleLoader(options: LoadSamplesOptions) {  // actual loading of the sample, do not call directly
 | 
					  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.api.get(this.sampleUrl({paging: true, pagingOptions: options}), (sData, err, headers) => {
 | 
				
			||||||
 | 
					      this.loading --;
 | 
				
			||||||
      if (err) {
 | 
					      if (err) {
 | 
				
			||||||
        this.storage.remove('samplesPreferences');
 | 
					        this.storage.remove('samplesPreferences');
 | 
				
			||||||
        this.api.requestError(err);
 | 
					        this.api.requestError(err);
 | 
				
			||||||
@@ -317,12 +324,15 @@ export class SamplesComponent implements OnInit {
 | 
				
			|||||||
    this.updateActiveKeys();
 | 
					    this.updateActiveKeys();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // TODO: avoid reloading
 | 
				
			||||||
 | 
					  resetPreferences() {
 | 
				
			||||||
 | 
					    this.storage.remove('samplesPreferences');
 | 
				
			||||||
 | 
					    this.window.location.reload();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateFilterFields(field) {
 | 
					  updateFilterFields(field) {
 | 
				
			||||||
    const filter = this.filters.filters.find(e => e.field === field);
 | 
					    const filter = this.filters.filters.find(e => e.field === field);
 | 
				
			||||||
    filter.active = true;
 | 
					    filter.active = true;
 | 
				
			||||||
    if (filter.active) {
 | 
					 | 
				
			||||||
      this.loadSamples({firstPage: true});
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setSort(string) {
 | 
					  setSort(string) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import {UserModel} from '../models/user.model';
 | 
				
			|||||||
import {LoginService} from '../services/login.service';
 | 
					import {LoginService} from '../services/login.service';
 | 
				
			||||||
import {ModalService} from '@inst-iot/bosch-angular-ui-components';
 | 
					import {ModalService} from '@inst-iot/bosch-angular-ui-components';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// TODO: somehow mail change triggered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-users',
 | 
					  selector: 'app-users',
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user