add filter service and enable chart states to filter lists

This commit is contained in:
Jesse Lucas 2020-04-01 20:43:54 -04:00
parent cce8b60515
commit 3bdceb1d6b
15 changed files with 144 additions and 48 deletions

View File

@ -1,5 +1,5 @@
<div fxLayout="row" fxLayoutAlign="space-between start"> <div fxLayout="row" fxLayoutAlign="space-between start">
<div></div> <div></div>
<div>{{state}}: &nbsp;</div> <div><a href="#">{{state}}</a>: &nbsp;</div>
<div>{{count}}</div> <div>{{count}}</div>
</div> </div>

View File

@ -1,16 +1,13 @@
import { Component, OnInit, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
@Component({ @Component({
selector: 'app-chart-item', selector: 'app-chart-item',
templateUrl: './chart-item.component.html', templateUrl: './chart-item.component.html',
styleUrls: ['./chart-item.component.scss'] styleUrls: ['./chart-item.component.scss']
}) })
export class ChartItemComponent implements OnInit { export class ChartItemComponent {
@Input() state: string; @Input() state: string;
@Input() count: number; @Input() count: number;
constructor() { } constructor() { }
ngOnInit(): void {
}
} }

View File

@ -4,7 +4,8 @@
<div fxLayout="row" fxLayoutAlign="space-between stretch"> <div fxLayout="row" fxLayoutAlign="space-between stretch">
<app-donut-chart [elementID]="chartID" fxFlex="30" [title]="title"></app-donut-chart> <app-donut-chart [elementID]="chartID" fxFlex="30" [title]="title"></app-donut-chart>
<div class="items" fxLayout="column" fxLayoutAlign="start end" fxFlex="70"> <div class="items" fxLayout="column" fxLayoutAlign="start end" fxFlex="70">
<app-chart-item *ngFor="let state of states" [state]="state.label" [count]="state.count"> <app-chart-item *ngFor="let state of states" (click)="onItemSelect(state.label)" [state]="state.label"
[count]="state.count">
</app-chart-item> </app-chart-item>
</div> </div>
</div> </div>

View File

@ -5,7 +5,8 @@ import { FolderService } from 'src/app/services/folder.service';
import { DonutChartComponent } from '../donut-chart/donut-chart.component'; import { DonutChartComponent } from '../donut-chart/donut-chart.component';
import { DeviceService } from 'src/app/services/device.service'; import { DeviceService } from 'src/app/services/device.service';
import Device from 'src/app/device'; import Device from 'src/app/device';
import { Type } from '../../type'; import { StType } from '../../type';
import { FilterService } from 'src/app/services/filter.service';
@ -17,7 +18,7 @@ import { Type } from '../../type';
export class ChartComponent implements OnInit { export class ChartComponent implements OnInit {
@ViewChild(DonutChartComponent) donutChart: DonutChartComponent; @ViewChild(DonutChartComponent) donutChart: DonutChartComponent;
@Input() type: Type; @Input() type: StType;
title: string; title: string;
chartID: string; chartID: string;
states: { label: string, count: number, color: string }[] = []; states: { label: string, count: number, color: string }[] = [];
@ -25,16 +26,25 @@ export class ChartComponent implements OnInit {
service: any; service: any;
namespace: any; namespace: any;
constructor(private folderService: FolderService, private deviceServce: DeviceService) { } constructor(
private folderService: FolderService,
private deviceServce: DeviceService,
private filterService: FilterService,
) { }
onItemSelect(state: string) {
// Send chart item state to filter
this.filterService.changeFilter({ type: this.type, text: state });
}
ngOnInit(): void { ngOnInit(): void {
switch (this.type) { switch (this.type) {
case Type.Folder: case StType.Folder:
this.title = "Folders"; this.title = "Folders";
this.chartID = 'foldersChart'; this.chartID = 'foldersChart';
this.service = this.folderService; this.service = this.folderService;
break; break;
case Type.Device: case StType.Device:
this.title = "Devices"; this.title = "Devices";
this.chartID = 'devicesChart'; this.chartID = 'devicesChart';
this.service = this.deviceServce; this.service = this.deviceServce;
@ -55,10 +65,10 @@ export class ChartComponent implements OnInit {
const state = t.state; const state = t.state;
let color; let color;
switch (this.type) { switch (this.type) {
case Type.Folder: case StType.Folder:
color = Folder.stateTypeToColor(t.stateType); color = Folder.stateTypeToColor(t.stateType);
break; break;
case Type.Device: case StType.Device:
color = Device.stateTypeToColor(stateType); color = Device.stateTypeToColor(stateType);
break; break;
} }
@ -73,7 +83,6 @@ export class ChartComponent implements OnInit {
}); });
if (!found) { if (!found) {
console.log(color, "look!!!")
this.states.push({ label: state, count: 1, color: color }); this.states.push({ label: state, count: 1, color: color });
} }

View File

@ -1,15 +1,17 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { SystemConfigService } from '../services/system-config.service'; import { SystemConfigService } from '../services/system-config.service';
import { Type } from '../type'; import { StType } from '../type';
import { FilterService } from '../services/filter.service';
@Component({ @Component({
selector: 'app-dashboard', selector: 'app-dashboard',
templateUrl: './dashboard.component.html', templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss'] styleUrls: ['./dashboard.component.scss'],
providers: [FilterService]
}) })
export class DashboardComponent { export class DashboardComponent {
folderChart: Type = Type.Folder; folderChart: StType = StType.Folder;
deviceChart: Type = Type.Device; deviceChart: StType = StType.Device;
constructor(private systemConfigService: SystemConfigService) { } constructor(private systemConfigService: SystemConfigService) { }

View File

@ -1,4 +1,4 @@
<mat-button-toggle-group class="tui-button-toggle" name="fontStyle" aria-label="Font Style" value="folders"> <mat-button-toggle-group class="tui-button-toggle" name="fontStyle" aria-label="Font Style" value="{{toggleValue}}">
<mat-button-toggle value="folders" (click)="onSelect(listType.Folder)">Folders</mat-button-toggle> <mat-button-toggle value="folders" (click)="onSelect(listType.Folder)">Folders</mat-button-toggle>
<mat-button-toggle value="devices" (click)="onSelect(listType.Device)">Devices</mat-button-toggle> <mat-button-toggle value="devices" (click)="onSelect(listType.Device)">Devices</mat-button-toggle>
</mat-button-toggle-group> </mat-button-toggle-group>

View File

@ -1,5 +1,5 @@
import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { Type } from '../type'; import { StType } from '../type';
@ -10,22 +10,15 @@ import { Type } from '../type';
}) })
export class ListToggleComponent implements OnInit { export class ListToggleComponent implements OnInit {
public listType = Type; public listType = StType;
@Output() listTypeEvent = new EventEmitter<Type>(); public toggleValue: string = "folders";
@Output() listTypeEvent = new EventEmitter<StType>();
constructor() { } constructor() { }
ngOnInit(): void { ngOnInit(): void {
} }
onSelect(t: Type): void { onSelect(t: StType): void {
this.listTypeEvent.emit(t); this.listTypeEvent.emit(t);
switch (t) {
case Type.Folder:
console.log("folder action");
break;
case Type.Device:
console.log("Device action");
break;
}
} }
} }

View File

@ -1,6 +1,6 @@
<mat-form-field> <mat-form-field>
<mat-label>Filter</mat-label> <mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date"> <input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date" value="{{filterValue}}">
</mat-form-field> </mat-form-field>
<table mat-table class="full-width-table" matSort aria-label="Elements"> <table mat-table class="full-width-table" matSort aria-label="Elements">
<!-- Id Column --> <!-- Id Column -->

View File

@ -1,10 +1,12 @@
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core'; import { AfterViewInit, Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTable, MatTableDataSource } from '@angular/material/table'; import { MatTable, MatTableDataSource } from '@angular/material/table';
import Device from '../../device'; import Device from '../../device';
import { SystemConfigService } from '../../services/system-config.service'; import { SystemConfigService } from '../../services/system-config.service';
import { FilterService } from 'src/app/services/filter.service';
import { StType } from 'src/app/type';
@Component({ @Component({
selector: 'app-device-list', selector: 'app-device-list',
@ -16,11 +18,16 @@ export class DeviceListComponent implements AfterViewInit, OnInit {
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
@ViewChild(MatTable) table: MatTable<Device>; @ViewChild(MatTable) table: MatTable<Device>;
dataSource: MatTableDataSource<Device>; dataSource: MatTableDataSource<Device>;
filterValue: string = "";
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['id', 'name', 'state']; displayedColumns = ['id', 'name', 'state'];
constructor(private systemConfigService: SystemConfigService) { }; constructor(
private systemConfigService: SystemConfigService,
private filterService: FilterService,
private cdr: ChangeDetectorRef,
) { };
applyFilter(event: Event) { applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value; const filterValue = (event.target as HTMLInputElement).value;
@ -42,5 +49,15 @@ export class DeviceListComponent implements AfterViewInit, OnInit {
this.dataSource.sort = this.sort; this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
this.table.dataSource = this.dataSource; this.table.dataSource = this.dataSource;
// Listen for filter changes from other components
this.filterService.filterChanged$.subscribe(
input => {
if (input.type === StType.Device) {
this.dataSource.filter = input.text.trim().toLowerCase();
this.filterValue = input.text;
this.cdr.detectChanges();
}
});
} }
} }

View File

@ -1,6 +1,6 @@
<mat-form-field> <mat-form-field>
<mat-label>Filter</mat-label> <mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date"> <input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date" value="{{filterValue}}">
</mat-form-field> </mat-form-field>
<table mat-table class="full-width-table" matSort aria-label="Elements"> <table mat-table class="full-width-table" matSort aria-label="Elements">
<!-- Id Column --> <!-- Id Column -->

View File

@ -1,10 +1,12 @@
import { AfterViewInit, Component, OnInit, ViewChild, Input } from '@angular/core'; import { AfterViewInit, Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator'; import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort'; import { MatSort } from '@angular/material/sort';
import { MatTable, MatTableDataSource } from '@angular/material/table'; import { MatTable, MatTableDataSource } from '@angular/material/table';
import Folder from '../../folder'; import Folder from '../../folder';
import { SystemConfigService } from '../../services/system-config.service'; import { SystemConfigService } from '../../services/system-config.service';
import { FilterService } from 'src/app/services/filter.service';
import { StType } from 'src/app/type';
@Component({ @Component({
selector: 'app-folder-list', selector: 'app-folder-list',
@ -16,11 +18,17 @@ export class FolderListComponent implements AfterViewInit, OnInit {
@ViewChild(MatSort) sort: MatSort; @ViewChild(MatSort) sort: MatSort;
@ViewChild(MatTable) table: MatTable<Folder>; @ViewChild(MatTable) table: MatTable<Folder>;
dataSource: MatTableDataSource<Folder>; dataSource: MatTableDataSource<Folder>;
filterValue: string = "";
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['id', 'label', 'path', 'state']; displayedColumns = ['id', 'label', 'path', 'state'];
constructor(private systemConfigService: SystemConfigService) { }; constructor(
private systemConfigService: SystemConfigService,
private filterService: FilterService,
private cdr: ChangeDetectorRef,
) {
};
applyFilter(event: Event) { applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value; const filterValue = (event.target as HTMLInputElement).value;
@ -42,5 +50,16 @@ export class FolderListComponent implements AfterViewInit, OnInit {
this.dataSource.sort = this.sort; this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator; this.dataSource.paginator = this.paginator;
this.table.dataSource = this.dataSource; this.table.dataSource = this.dataSource;
// Listen for filter changes from other components
this.filterService.filterChanged$
.subscribe(
input => {
if (input.type === StType.Folder) {
this.dataSource.filter = input.text.trim().toLowerCase();
this.filterValue = input.text;
this.cdr.detectChanges();
}
});
} }
} }

View File

@ -1,6 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { Type } from '../../type'; import { StType } from '../../type';
import { cardElevation } from '../../style'; import { cardElevation } from '../../style';
import { FilterService } from 'src/app/services/filter.service';
import { ListToggleComponent } from 'src/app/list-toggle/list-toggle.component';
@Component({ @Component({
@ -8,18 +10,33 @@ import { cardElevation } from '../../style';
templateUrl: './status-list.component.html', templateUrl: './status-list.component.html',
styleUrls: ['./status-list.component.scss'] styleUrls: ['./status-list.component.scss']
}) })
export class StatusListComponent implements OnInit { export class StatusListComponent {
currentListType: Type = Type.Folder; @ViewChild(ListToggleComponent) toggle: ListToggleComponent;
listType = Type; // used in html currentListType: StType = StType.Folder;
listType = StType; // used in html
elevation: string = cardElevation; elevation: string = cardElevation;
title: string = 'Status'; title: string = 'Status';
constructor() { } constructor(private filterService: FilterService) { }
ngOnInit(): void { ngAfterViewInit() {
// Listen for filter changes from other components
this.filterService.filterChanged$.subscribe(
input => {
this.currentListType = input.type;
switch (input.type) {
case StType.Folder:
this.toggle.toggleValue = "folders";
break;
case StType.Device:
this.toggle.toggleValue = "devices";
break;
}
});
} }
onToggle(t: Type) { onToggle(t: StType) {
this.currentListType = t; this.currentListType = t;
} }
} }

View File

@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { FilterService } from './filter.service';
describe('FilterService', () => {
let service: FilterService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(FilterService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { StType } from '../type';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export interface FilterInput {
type: StType;
text: string
}
export class FilterService {
constructor() { }
private filterChangeSource = new BehaviorSubject<FilterInput>({ type: StType.Folder, text: "" });
filterChanged$ = this.filterChangeSource.asObservable();
changeFilter(input: FilterInput) {
this.filterChangeSource.next(input);
}
}

View File

@ -1,4 +1,4 @@
export enum Type { export enum StType {
Folder = 1, Folder = 1,
Device, Device,
} }