build: Add build process for newgui (#7351)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user