build: Add build process for newgui (#7351)

This commit is contained in:
Jakob Borg
2021-02-15 14:52:28 +01:00
parent d117b4b570
commit b2c9e7b07b
123 changed files with 38050 additions and 17178 deletions
@@ -0,0 +1,31 @@
<mat-form-field>
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date">
</mat-form-field>
<table mat-table class="full-width-table" matSort aria-label="Devices" multiTemplateDataRows>
<ng-container matColumnDef="{{column}}" *ngFor="let column of displayedColumns">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let device"> {{device[column]}} </td>
</ng-container>
<ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let device" [attr.colspan]="displayedColumns.length">
<div class="table-detail" [@detailExpand]="device == expandedDevice ? 'expanded' : 'collapsed'">
<div class="detail-items">
<span>Folders: </span>
<span class="item-name" *ngFor="let folder of device.folders">{{folder.label | trim}}</span>
</div>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let device; columns: displayedColumns;" class="table-row"
[class.expanded-row]="expandedDevice === device"
(click)="expandedDevice = expandedDevice === device ? null : device">
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
</table>
<mat-paginator #paginator [length]="dataSource?.data.length" [pageIndex]="0" [pageSize]="25"
[pageSizeOptions]="[25, 50, 100, 250]">
</mat-paginator>
@@ -0,0 +1,28 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { DeviceListComponent } from './device-list.component';
import { HttpClientModule } from '@angular/common/http';
import { ChangeDetectorRef } from '@angular/core';
describe('DeviceListComponent', () => {
let component: DeviceListComponent;
let fixture: ComponentFixture<DeviceListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DeviceListComponent],
imports: [HttpClientModule],
providers: [DeviceListComponent, ChangeDetectorRef]
}).compileComponents();
component = TestBed.inject(DeviceListComponent);
}));
it('should compile', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,96 @@
import { AfterViewInit, Component, OnInit, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import Device from '../../device';
import { SystemConfigService } from '../../services/system-config.service';
import { FilterService } from 'src/app/services/filter.service';
import { StType } from 'src/app/type';
import { MatInput } from '@angular/material/input';
import { DeviceService } from 'src/app/services/device.service';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
selector: 'app-device-list',
templateUrl: './device-list.component.html',
styleUrls: ['../status-list/status-list.component.scss'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class DeviceListComponent implements AfterViewInit, OnInit, OnDestroy {
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatTable) table: MatTable<Device>;
@ViewChild(MatInput) input: MatInput;
dataSource: MatTableDataSource<Device>;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['deviceID', 'name', 'state'];
expandedDevice: Device | null;
constructor(
private deviceService: DeviceService,
private filterService: FilterService,
private cdr: ChangeDetectorRef,
) { };
applyFilter(event: Event) {
// Set previous filter value
const filterValue = (event.target as HTMLInputElement).value;
this.filterService.previousInputs.set(StType.Device, filterValue);
this.dataSource.filter = filterValue.trim().toLowerCase();
}
ngOnInit() {
this.dataSource = new MatTableDataSource();
this.dataSource.data = [];
// Replace all data when requests are finished
this.deviceService.devicesUpdated$.subscribe(
devices => {
this.dataSource.data = devices;
}
);
// Add device as they come in
let devices: Device[] = [];
this.deviceService.deviceAdded$.subscribe(
device => {
devices.push(device);
this.dataSource.data = devices;
}
);
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.table.dataSource = this.dataSource;
const changeText = (text: string) => {
this.dataSource.filter = text.trim().toLowerCase();
this.input.value = text;
this.cdr.detectChanges();
}
// Set previous value
changeText(this.filterService.previousInputs.get(StType.Device));
// Listen for filter changes from other components
this.filterService.filterChanged$
.subscribe(
input => {
if (input.type === StType.Device) {
changeText(input.text);
}
});
}
ngOnDestroy() { }
}
@@ -0,0 +1,32 @@
<mat-form-field>
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Up to Date">
</mat-form-field>
<table mat-table class="full-width-table" matSort aria-label="Folders" multiTemplateDataRows>
<ng-container matColumnDef="{{column}}" *ngFor="let column of displayedColumns">
<th mat-header-cell *matHeaderCellDef> {{column}} </th>
<td mat-cell *matCellDef="let folder"> {{folder[column]}} </td>
</ng-container>
<!-- Expanded Content Column - The detail row is made up of this one column that spans across all columns -->
<ng-container matColumnDef="expandedDetail">
<td mat-cell *matCellDef="let folder" [attr.colspan]="displayedColumns.length">
<div class="table-detail" [@detailExpand]="folder == expandedFolder ? 'expanded' : 'collapsed'">
<div class="detail-items">
<span>Shared with: </span>
<span class="item-name" *ngFor="let device of folder.devices">{{device.name}}</span>
</div>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let folder; columns: displayedColumns;" class="table-row"
[class.expanded-row]="expandedFolder === folder"
(click)="expandedFolder = expandedFolder === folder ? null : folder">
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
</table>
<mat-paginator #paginator [length]="dataSource?.data.length" [pageIndex]="0" [pageSize]="25"
[pageSizeOptions]="[25, 50, 100, 250]">
</mat-paginator>
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FolderListComponent } from './folder-list.component';
import { HttpClientModule } from '@angular/common/http';
import { ChangeDetectorRef } from '@angular/core';
describe('FolderListComponent', () => {
let component: FolderListComponent;
let fixture: ComponentFixture<FolderListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FolderListComponent],
imports: [HttpClientModule],
providers: [FolderListComponent, ChangeDetectorRef]
})
.compileComponents();
component = TestBed.inject(FolderListComponent);
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,102 @@
import { AfterViewInit, Component, OnInit, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
import { MatPaginator } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTable, MatTableDataSource } from '@angular/material/table';
import Folder from '../../folder';
import { SystemConfigService } from '../../services/system-config.service';
import { FilterService } from 'src/app/services/filter.service';
import { StType } from 'src/app/type';
import { MatInput } from '@angular/material/input';
import { FolderService } from 'src/app/services/folder.service';
import { trigger, state, style, transition, animate } from '@angular/animations';
@Component({
selector: 'app-folder-list',
templateUrl: './folder-list.component.html',
styleUrls: ['../status-list/status-list.component.scss'],
animations: [
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
]),
],
})
export class FolderListComponent implements AfterViewInit, OnInit, OnDestroy {
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatTable) table: MatTable<Folder>;
@ViewChild(MatInput) input: MatInput;
dataSource: MatTableDataSource<Folder>;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = [
"id",
"label",
"path",
"state"
];
expandedFolder: Folder | null;
constructor(
private folderService: FolderService,
private filterService: FilterService,
private cdr: ChangeDetectorRef,
) {
};
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.filterService.previousInputs.set(StType.Folder, filterValue);
this.dataSource.filter = filterValue.trim().toLowerCase();
}
ngOnInit() {
this.dataSource = new MatTableDataSource();
this.dataSource.data = [];
// Replace all data when requests are finished
this.folderService.foldersUpdated$.subscribe(
folders => {
this.dataSource.data = folders;
}
);
// Add device as they come in
let folders: Folder[] = [];
this.folderService.folderAdded$.subscribe(
folder => {
folders.push(folder);
this.dataSource.data = folders;
}
);;
}
ngAfterViewInit() {
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.table.dataSource = this.dataSource;
const changeText = (text: string) => {
this.dataSource.filter = text.trim().toLowerCase();
this.input.value = text;
this.cdr.detectChanges();
}
// Set previous value
changeText(this.filterService.previousInputs.get(StType.Folder));
// Listen for filter changes from other components
this.filterService.filterChanged$
.subscribe(
input => {
if (input.type === StType.Folder) {
changeText(input.text);
}
});
}
ngOnDestroy() { }
}
@@ -0,0 +1,10 @@
<app-card class="status-list">
<div fxLayout="row" fxLayoutAlign="space-between start">
<app-card-title>{{title | uppercase}}</app-card-title>
<app-list-toggle (listTypeEvent)="onToggle($event)" class="tui-card-toggle"></app-list-toggle>
</div>
<app-card-content>
<app-folder-list *ngIf="currentListType===listType.Folder"></app-folder-list>
<app-device-list *ngIf="currentListType===listType.Device"> </app-device-list>
</app-card-content>
</app-card>
@@ -0,0 +1,70 @@
.status-list .tui-card-toggle {
padding: 16px 16px 0 16px;
}
.full-width-table {
width: 100%;
}
.mat-form-field {
font-size: 14px;
width: 100%;
}
tr.detail-row {
height: 0;
}
tr.table-row:not(.expanded-row):hover {
background: whitesmoke;
color: #303030;
}
tr.table-row:not(.expanded-row):active {
background: #DDDDDD;
color: #303030;
}
.expanded-row {
background: #DDDDDD;
color: #303030;
}
.table-row td {
border-bottom-width: 0;
}
.table-detail {
overflow: hidden;
display: flex;
}
.detail-items {
padding: 16px;
}
// Hide empty name
.item-name:empty {
display: none;
}
.item-name:not(:last-child):after {
content: ", ";
}
@media (prefers-color-scheme: dark) {
tr.table-row:not(.expanded-row):hover {
background: #212121;
color: white;
}
tr.table-row:not(.expanded-row):active {
background: #212121;
color: white;
}
.expanded-row {
background: #212121;
color: white;
}
}
@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { StatusListComponent } from './status-list.component';
describe('StatusListComponent', () => {
let component: StatusListComponent;
let fixture: ComponentFixture<StatusListComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [StatusListComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(StatusListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,47 @@
import { Component, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core';
import { StType } from '../../type';
import { cardElevation } from '../../style';
import { FilterService } from 'src/app/services/filter.service';
import { ListToggleComponent } from 'src/app/list-toggle/list-toggle.component';
@Component({
selector: 'app-status-list',
templateUrl: './status-list.component.html',
styleUrls: ['./status-list.component.scss']
})
export class StatusListComponent {
@ViewChild(ListToggleComponent) toggle: ListToggleComponent;
currentListType: StType = StType.Folder;
listType = StType; // used in html
elevation: string = cardElevation;
title: string = 'Status';
constructor(
private filterService: FilterService,
private cdr: ChangeDetectorRef,
) { }
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.group.value = "folders";
break;
case StType.Device:
this.toggle.group.value = "devices";
break;
}
});
this.cdr.detectChanges(); // manually detect changes
}
onToggle(t: StType) {
this.currentListType = t;
}
}