summaryrefslogtreecommitdiff
path: root/gae/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'gae/frontend/src')
-rw-r--r--gae/frontend/src/app/app.component.html35
-rw-r--r--gae/frontend/src/app/app.component.scss28
-rw-r--r--gae/frontend/src/app/app.component.spec.ts0
-rw-r--r--gae/frontend/src/app/app.component.ts63
-rw-r--r--gae/frontend/src/app/app.module.ts141
-rw-r--r--gae/frontend/src/app/appservice.ts37
-rw-r--r--gae/frontend/src/app/menu/build/build.component.html75
-rw-r--r--gae/frontend/src/app/menu/build/build.component.scss0
-rw-r--r--gae/frontend/src/app/menu/build/build.component.ts127
-rw-r--r--gae/frontend/src/app/menu/build/build.service.ts43
-rw-r--r--gae/frontend/src/app/menu/cdk-detail-row.directive.ts72
-rw-r--r--gae/frontend/src/app/menu/dashboard/dashboard.component.html30
-rw-r--r--gae/frontend/src/app/menu/dashboard/dashboard.component.scss17
-rw-r--r--gae/frontend/src/app/menu/dashboard/dashboard.component.ts74
-rw-r--r--gae/frontend/src/app/menu/device/device.component.html80
-rw-r--r--gae/frontend/src/app/menu/device/device.component.scss7
-rw-r--r--gae/frontend/src/app/menu/device/device.component.ts138
-rw-r--r--gae/frontend/src/app/menu/device/device.service.ts43
-rw-r--r--gae/frontend/src/app/menu/job/_job-theme.scss7
-rw-r--r--gae/frontend/src/app/menu/job/job.component.html192
-rw-r--r--gae/frontend/src/app/menu/job/job.component.scss24
-rw-r--r--gae/frontend/src/app/menu/job/job.component.ts221
-rw-r--r--gae/frontend/src/app/menu/job/job.service.ts44
-rw-r--r--gae/frontend/src/app/menu/lab/lab.component.html109
-rw-r--r--gae/frontend/src/app/menu/lab/lab.component.scss41
-rw-r--r--gae/frontend/src/app/menu/lab/lab.component.ts104
-rw-r--r--gae/frontend/src/app/menu/lab/lab.service.ts44
-rw-r--r--gae/frontend/src/app/menu/menu-items.ts23
-rw-r--r--gae/frontend/src/app/menu/menu_base.ts79
-rw-r--r--gae/frontend/src/app/menu/schedule/_schedule-theme.scss7
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.html121
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.scss24
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.ts160
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.service.ts51
-rw-r--r--gae/frontend/src/app/model/build.ts25
-rw-r--r--gae/frontend/src/app/model/build_wrapper.ts21
-rw-r--r--gae/frontend/src/app/model/device.ts24
-rw-r--r--gae/frontend/src/app/model/device_wrapper.ts21
-rw-r--r--gae/frontend/src/app/model/filter_condition.ts24
-rw-r--r--gae/frontend/src/app/model/filter_item.ts22
-rw-r--r--gae/frontend/src/app/model/host.ts25
-rw-r--r--gae/frontend/src/app/model/host_wrapper.ts23
-rw-r--r--gae/frontend/src/app/model/job.ts66
-rw-r--r--gae/frontend/src/app/model/job_wrapper.ts21
-rw-r--r--gae/frontend/src/app/model/lab.ts23
-rw-r--r--gae/frontend/src/app/model/schedule.ts75
-rw-r--r--gae/frontend/src/app/model/schedule_wrapper.ts21
-rw-r--r--gae/frontend/src/app/model/tslint.json9
-rw-r--r--gae/frontend/src/app/shared/dict.pipe.ts29
-rw-r--r--gae/frontend/src/app/shared/filter/filter.component.html66
-rw-r--r--gae/frontend/src/app/shared/filter/filter.component.scss35
-rw-r--r--gae/frontend/src/app/shared/filter/filter.component.ts107
-rw-r--r--gae/frontend/src/app/shared/navbar/_navbar-theme.scss13
-rw-r--r--gae/frontend/src/app/shared/navbar/navbar.component.html20
-rw-r--r--gae/frontend/src/app/shared/navbar/navbar.component.scss10
-rw-r--r--gae/frontend/src/app/shared/navbar/navbar.component.ts29
-rw-r--r--gae/frontend/src/app/shared/navbar/navbar.ts47
-rw-r--r--gae/frontend/src/app/shared/servicebase.ts41
-rw-r--r--gae/frontend/src/app/shared/vtslab_status.ts58
-rw-r--r--gae/frontend/src/browserslist5
-rw-r--r--gae/frontend/src/environments/environment.prod.ts4
-rw-r--r--gae/frontend/src/environments/environment.ts4
-rw-r--r--gae/frontend/src/favicon.icobin5430 -> 0 bytes
-rw-r--r--gae/frontend/src/index.html15
-rw-r--r--gae/frontend/src/karma.conf.js31
-rw-r--r--gae/frontend/src/main.ts12
-rw-r--r--gae/frontend/src/polyfills.ts5
-rw-r--r--gae/frontend/src/styles.scss54
-rw-r--r--gae/frontend/src/styles/_app-theme.scss14
-rw-r--r--gae/frontend/src/styles/_apply-theme.scss5
-rw-r--r--gae/frontend/src/styles/_blue-theme.scss34
-rw-r--r--gae/frontend/src/test.ts20
-rw-r--r--gae/frontend/src/tsconfig.app.json12
-rw-r--r--gae/frontend/src/tsconfig.spec.json19
-rw-r--r--gae/frontend/src/tslint.json17
75 files changed, 0 insertions, 3367 deletions
diff --git a/gae/frontend/src/app/app.component.html b/gae/frontend/src/app/app.component.html
deleted file mode 100644
index 8f21391..0000000
--- a/gae/frontend/src/app/app.component.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<header>
- <div>
- <app-nav-bar id="nav-bar"></app-nav-bar>
- </div>
-</header>
-<mat-sidenav-container>
- <mat-sidenav-content>
- <router-outlet id="router-outlet"></router-outlet>
- </mat-sidenav-content>
- <mat-sidenav #sidenav mode="over" position="end" [(opened)]="sideNavOpened">
- <button mat-button (click)="sidenav.toggle()">
- <mat-icon>clear</mat-icon>
- </button>
- <mat-list>
- <mat-list-item *ngFor="let property of selectedEntity">
- <h4 id="property-name" mat-line>{{property.name}}</h4>
- <p id="property-value" mat-line *ngFor="let each of property.value">{{each}}</p>
- </mat-list-item>
- </mat-list>
- </mat-sidenav>
-</mat-sidenav-container>
diff --git a/gae/frontend/src/app/app.component.scss b/gae/frontend/src/app/app.component.scss
deleted file mode 100644
index d818d0e..0000000
--- a/gae/frontend/src/app/app.component.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-mat-sidenav {
- width: 400px;
- padding: 30px 10px;
-}
-
-#property-name {
- color: rgba(0, 0, 0, 0.66);
- font-size: 12px;
- margin-bottom: 2px;
-}
-
-#property-value {
- font-size: 12px;
-}
-
-.mat-button {
- position: absolute;
- top: 10px;
- right: 10px;
- min-width: 28px;
- width: 28px;
- height: 28px;
- padding: 0;
- .mat-icon {
- width: 24px;
- height: 24px;
- }
-}
diff --git a/gae/frontend/src/app/app.component.spec.ts b/gae/frontend/src/app/app.component.spec.ts
deleted file mode 100644
index e69de29..0000000
--- a/gae/frontend/src/app/app.component.spec.ts
+++ /dev/null
diff --git a/gae/frontend/src/app/app.component.ts b/gae/frontend/src/app/app.component.ts
deleted file mode 100644
index 1a2ef06..0000000
--- a/gae/frontend/src/app/app.component.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { Component } from '@angular/core';
-
-import { AppService } from "./appservice";
-
-
-@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.scss']
-})
-export class AppComponent {
- _sideNavOpened = false;
- get sideNavOpened(): boolean {
- return this._sideNavOpened;
- }
- set sideNavOpened(value: boolean) {
- this._sideNavOpened = value;
- if (!value) {
- this.selectedEntity = this.selectedEntity.slice();
- }
- }
- selectedEntity: {name: string; value: any[]}[] = [];
-
- constructor(private appService: AppService) {
- appService.closeSideNavEmitter.subscribe(() => {this.sideNavOpened = false});
- appService.showDetailsEmitter.subscribe(
- (entity) => {
- this.selectedEntity.length = 0;
- if (entity) {
- let self = this;
- Object.keys(entity).forEach(function(value){
- if (value !== 'urlsafe_key') {
- self.selectedEntity.push({
- name: value,
- value: (entity[value] instanceof Array) ? entity[value] : [entity[value]]
- });
- }
- });
- }
- this.sideNavOpened = !this.sideNavOpened;
- },
- (error) => {
- console.log(error);
- }
- )
- }
-}
diff --git a/gae/frontend/src/app/app.module.ts b/gae/frontend/src/app/app.module.ts
deleted file mode 100644
index ec940db..0000000
--- a/gae/frontend/src/app/app.module.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Angular modules.
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
-import { BrowserModule } from '@angular/platform-browser';
-import { FormsModule } from '@angular/forms';
-import { HttpClientModule } from '@angular/common/http';
-import { NgModule } from '@angular/core';
-import { RouterModule, Routes } from '@angular/router';
-
-// Angular Material modules
-import { MatButtonModule } from '@angular/material/button';
-import { MatCardModule } from '@angular/material/card';
-import { MatChipsModule } from '@angular/material/chips';
-import { MatExpansionModule } from '@angular/material/expansion';
-import { MatFormFieldModule } from '@angular/material/form-field';
-import { MatIconModule } from '@angular/material';
-import { MatInputModule } from '@angular/material/input';
-import { MatListModule } from '@angular/material/list';
-import { MatPaginatorModule } from '@angular/material/paginator';
-import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
-import { MatSnackBarModule } from '@angular/material/snack-bar';
-import { MatSelectModule } from '@angular/material/select';
-import { MatSidenavModule } from '@angular/material/sidenav';
-import { MatSortModule } from '@angular/material/sort';
-import { MatTableModule } from '@angular/material/table';
-import { MatTabsModule } from '@angular/material/tabs';
-
-// User components.
-import { AppComponent } from './app.component';
-import { BuildComponent } from './menu/build/build.component';
-import { DashboardComponent } from './menu/dashboard/dashboard.component';
-import { DeviceComponent } from './menu/device/device.component';
-import { FilterComponent } from './shared/filter/filter.component';
-import { JobComponent } from './menu/job/job.component';
-import { LabComponent } from './menu/lab/lab.component';
-import { ScheduleComponent } from './menu/schedule/schedule.component';
-
-// User modules.
-import { NavModule } from './shared/navbar/navbar';
-
-// Other dependencies.
-import { FlexLayoutModule } from '@angular/flex-layout';
-
-// User directives for CDK (Component Development Kit).
-import { CdkDetailRowDirective } from './menu/cdk-detail-row.directive';
-
-
-const appRoutes: Routes = [
- { path: 'device', component: DeviceComponent },
- { path: 'build', component: BuildComponent },
- { path: 'job', component: JobComponent },
- { path: 'lab', component: LabComponent },
- { path: 'schedule', component: ScheduleComponent },
- { path: '', component: DashboardComponent },
- { path: '**', redirectTo: '/', pathMatch: 'full' }
-];
-
-
-@NgModule({
- imports: [
- MatButtonModule,
- MatCardModule,
- MatChipsModule,
- MatExpansionModule,
- MatFormFieldModule,
- MatIconModule,
- MatInputModule,
- MatListModule,
- MatPaginatorModule,
- MatProgressSpinnerModule,
- MatSnackBarModule,
- MatSelectModule,
- MatSidenavModule,
- MatSortModule,
- MatTableModule,
- MatTabsModule,
- ],
- exports: [
- MatButtonModule,
- MatCardModule,
- MatChipsModule,
- MatExpansionModule,
- MatFormFieldModule,
- MatIconModule,
- MatInputModule,
- MatListModule,
- MatPaginatorModule,
- MatProgressSpinnerModule,
- MatSnackBarModule,
- MatSelectModule,
- MatSidenavModule,
- MatSortModule,
- MatTableModule,
- MatTabsModule,
- ]
-})
-export class MaterialModule {}
-
-
-@NgModule({
- declarations: [
- AppComponent,
- BuildComponent,
- CdkDetailRowDirective,
- DashboardComponent,
- DeviceComponent,
- FilterComponent,
- JobComponent,
- LabComponent,
- ScheduleComponent,
- ],
- imports: [
- BrowserAnimationsModule,
- BrowserModule,
- FlexLayoutModule,
- FormsModule,
- HttpClientModule,
- MaterialModule,
- NavModule,
- RouterModule.forRoot(
- appRoutes
- ),
- ],
- providers: [],
- bootstrap: [AppComponent]
-})
-export class AppModule { }
diff --git a/gae/frontend/src/app/appservice.ts b/gae/frontend/src/app/appservice.ts
deleted file mode 100644
index 6b303f0..0000000
--- a/gae/frontend/src/app/appservice.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {EventEmitter, Injectable, Output} from '@angular/core';
-
-
-@Injectable({
- providedIn: 'root',
-})
-export class AppService {
- @Output() closeSideNavEmitter = new EventEmitter();
- @Output() showDetailsEmitter = new EventEmitter();
- constructor() {
- }
-
- /** Emits an EventEmitter to display entity in the side nav window. */
- showDetails(entity) {
- this.showDetailsEmitter.emit(entity);
- }
-
- /** Emits an EventEmitter to close the side nav window. */
- closeSideNav() {
- this.closeSideNavEmitter.emit();
- }
-}
diff --git a/gae/frontend/src/app/menu/build/build.component.html b/gae/frontend/src/app/menu/build/build.component.html
deleted file mode 100644
index d8ae525..0000000
--- a/gae/frontend/src/app/menu/build/build.component.html
+++ /dev/null
@@ -1,75 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div class="entity-filter">
- <app-filter (applyFilters)="applyFilters($event)" [disabled]="loading"></app-filter>
-</div>
-<div class="mat-elevation-z2 entity-table" [ngStyle]="{'opacity': (loading) ? 0.2 : 1 }">
- <mat-table #table [dataSource]="dataSource">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef>No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index"> {{i+1+pageSize*pageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Manifest Branch Column -->
- <ng-container matColumnDef="artifact_type">
- <mat-header-cell *matHeaderCellDef>Artifact Type</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.artifact_type}} </mat-cell>
- </ng-container>
-
- <!-- Manifest Branch Column -->
- <ng-container matColumnDef="manifest_branch">
- <mat-header-cell *matHeaderCellDef>Manifest Branch</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.manifest_branch}} </mat-cell>
- </ng-container>
-
- <!-- Build ID Column -->
- <ng-container matColumnDef="build_id">
- <mat-header-cell *matHeaderCellDef>Build ID</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.build_id}} </mat-cell>
- </ng-container>
-
- <!-- Build Target Column -->
- <ng-container matColumnDef="build_target">
- <mat-header-cell *matHeaderCellDef>Build Target</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.build_target}} </mat-cell>
- </ng-container>
-
- <!-- Build Type Column -->
- <ng-container matColumnDef="build_type">
- <mat-header-cell *matHeaderCellDef>Build Type</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.build_type}} </mat-cell>
- </ng-container>
-
- <!-- Signed Column -->
- <ng-container matColumnDef="signed">
- <mat-header-cell *matHeaderCellDef>Signed</mat-header-cell>
- <mat-cell *matCellDef="let build"> {{build.signed}} </mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="columnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: columnTitles;"></mat-row>
- </mat-table>
-
- <mat-paginator [length]="count"
- [pageSize]="pageSize"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="pageIndex"
- (page)="pageEvent = onPageEvent($event)">
- </mat-paginator>
-</div>
-<div class="loading-spinner" *ngIf="loading">
- <mat-spinner color="primary"></mat-spinner>
-</div>
diff --git a/gae/frontend/src/app/menu/build/build.component.scss b/gae/frontend/src/app/menu/build/build.component.scss
deleted file mode 100644
index e69de29..0000000
--- a/gae/frontend/src/app/menu/build/build.component.scss
+++ /dev/null
diff --git a/gae/frontend/src/app/menu/build/build.component.ts b/gae/frontend/src/app/menu/build/build.component.ts
deleted file mode 100644
index e4c7325..0000000
--- a/gae/frontend/src/app/menu/build/build.component.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
-
-import { AppService } from '../../appservice';
-import { Build } from '../../model/build';
-import { BuildService } from './build.service';
-import { FilterComponent } from '../../shared/filter/filter.component';
-import { FilterItem } from '../../model/filter_item';
-import { MenuBaseClass } from '../menu_base';
-
-
-/** Component that handles build menu. */
-@Component({
- selector: 'app-build',
- templateUrl: './build.component.html',
- providers: [ BuildService ],
- styleUrls: ['./build.component.scss'],
-})
-export class BuildComponent extends MenuBaseClass implements OnInit {
- columnTitles = [
- '_index',
- 'artifact_type',
- 'manifest_branch',
- 'build_id',
- 'build_target',
- 'build_type',
- 'signed'];
- dataSource = new MatTableDataSource<Build>();
- pageEvent: PageEvent;
- appliedFilters: FilterItem[];
-
- @ViewChild(FilterComponent) filterComponent: FilterComponent;
-
- constructor(private buildService: BuildService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- ngOnInit(): void {
- this.filterComponent.setSelectorList(Build);
- this.getCount();
- this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
- }
-
- /** Gets a total count of builds. */
- getCount(observer = this.getDefaultCountObservable()) {
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.buildService.getCount(filterJSON).subscribe(observer);
- }
-
- /** Gets builds.
- * @param size A number, at most this many results will be returned.
- * @param offset A Number of results to skip.
- */
- getBuilds(size = 0, offset = 0) {
- this.loading = true;
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.buildService.getBuilds(size, offset, filterJSON, '', '')
- .subscribe(
- (response) => {
- this.loading = false;
- if (this.count >= 0) {
- let length = 0;
- if (response.builds) {
- length = response.builds.length;
- }
- const total = length + offset;
- if (response.has_next) {
- if (length !== this.pageSize) {
- this.showSnackbar('Received unexpected number of entities.');
- } else if (this.count <= total) {
- this.getCount();
- }
- } else {
- if (this.count !== total) {
- if (length !== this.count) {
- this.getCount();
- } else if (this.count > total) {
- const countObservable = this.getDefaultCountObservable([
- () => {
- this.pageIndex = Math.floor(this.count / this.pageSize);
- this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
- }
- ]);
- this.getCount(countObservable);
- }
- }
- }
- }
- this.dataSource.data = response.builds;
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Hooks a page event and handles properly. */
- onPageEvent(event: PageEvent) {
- this.pageSize = event.pageSize;
- this.pageIndex = event.pageIndex;
- this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
- return event;
- }
-
- /** Applies a filter and get entities with it. */
- applyFilters(filters) {
- this.pageIndex = 0;
- this.appliedFilters = filters;
- this.getCount();
- this.getBuilds(this.pageSize, this.pageSize * this.pageIndex);
- }
-}
diff --git a/gae/frontend/src/app/menu/build/build.service.ts b/gae/frontend/src/app/menu/build/build.service.ts
deleted file mode 100644
index d60f790..0000000
--- a/gae/frontend/src/app/menu/build/build.service.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { catchError } from 'rxjs/operators';
-import { Observable } from 'rxjs';
-
-import { BuildWrapper } from '../../model/build_wrapper';
-import { environment } from '../../../environments/environment';
-import { ServiceBase } from '../../shared/servicebase';
-
-
-@Injectable()
-export class BuildService extends ServiceBase {
- constructor(public httpClient: HttpClient) {
- super(httpClient);
- this.url = environment['baseURL'] + '/build/v1/';
- }
-
- getBuilds(size: number,
- offset: number,
- filterInfo: string,
- sort: string,
- direction: string): Observable<BuildWrapper> {
- const url = this.url + 'get';
- return this.httpClient.post<BuildWrapper>(url, {size: size, offset: offset, filter: filterInfo, sort: sort, direction: direction})
- .pipe(catchError(this.handleError));
- }
-}
diff --git a/gae/frontend/src/app/menu/cdk-detail-row.directive.ts b/gae/frontend/src/app/menu/cdk-detail-row.directive.ts
deleted file mode 100644
index 60b490a..0000000
--- a/gae/frontend/src/app/menu/cdk-detail-row.directive.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Directive, EventEmitter, HostBinding, HostListener, Input, Output, TemplateRef, ViewContainerRef} from '@angular/core';
-
-
-@Directive({
- selector: '[appCdkDetailRow]'
-})
-export class CdkDetailRowDirective {
- private row: any;
- private tRef: TemplateRef<any>;
- private opened: boolean;
-
- @HostBinding('class.expanded')
- get expended(): boolean {
- return this.opened;
- }
-
- @Input()
- set appCdkDetailRow(value: any) {
- if (value !== this.row) {
- this.row = value;
- // this.render();
- }
- }
-
- @Input('appCdkDetailRowTpl')
- set template(value: TemplateRef<any>) {
- if (value !== this.tRef) {
- this.tRef = value;
- }
- }
-
- @Output() toggleChange = new EventEmitter<CdkDetailRowDirective>();
-
- constructor(public vcRef: ViewContainerRef) { }
-
- @HostListener('click')
- onClick(): void {
- this.toggle();
- }
-
- toggle(): void {
- if (this.opened) {
- this.vcRef.clear();
- } else {
- this.render();
- }
- this.opened = this.vcRef.length > 0;
- this.toggleChange.emit(this);
- }
-
- private render(): void {
- this.vcRef.clear();
- if (this.tRef && this.row) {
- this.vcRef.createEmbeddedView(this.tRef, { $implicit: this.row });
- }
- }
-}
diff --git a/gae/frontend/src/app/menu/dashboard/dashboard.component.html b/gae/frontend/src/app/menu/dashboard/dashboard.component.html
deleted file mode 100644
index b91e80c..0000000
--- a/gae/frontend/src/app/menu/dashboard/dashboard.component.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div fxLayout="row">
- <mat-card>
- <mat-card-title>Build</mat-card-title>
- <mat-card-subtitle>Last updated: {{getRelativeTime(lastBuildUpdateTime)}}</mat-card-subtitle>
- <button mat-raised-button (click)="getLatestBuild()">
- <mat-icon>refresh</mat-icon>
- </button>
- </mat-card>
- <mat-card>
- <mat-card-title>Schedule</mat-card-title>
- <mat-card-subtitle>Last updated: {{getRelativeTime(lastScheduleUpdateTime)}}</mat-card-subtitle>
- <button mat-raised-button (click)="getLastestSchedule()">
- <mat-icon>refresh</mat-icon>
- </button>
- </mat-card>
-</div>
diff --git a/gae/frontend/src/app/menu/dashboard/dashboard.component.scss b/gae/frontend/src/app/menu/dashboard/dashboard.component.scss
deleted file mode 100644
index a17cb36..0000000
--- a/gae/frontend/src/app/menu/dashboard/dashboard.component.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-.mat-card {
- width: 50%;
-
- .mat-raised-button {
- position: absolute;
- top: 10px;
- right: 10px;
- min-width: 28px;
- width: 28px;
- height: 28px;
- padding: 0;
- .mat-icon {
- width: 24px;
- height: 24px;
- }
- }
-}
diff --git a/gae/frontend/src/app/menu/dashboard/dashboard.component.ts b/gae/frontend/src/app/menu/dashboard/dashboard.component.ts
deleted file mode 100644
index 0157ea8..0000000
--- a/gae/frontend/src/app/menu/dashboard/dashboard.component.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit } from '@angular/core';
-import { MatSnackBar } from '@angular/material';
-
-import { AppService } from '../../appservice';
-import { BuildService } from "../build/build.service";
-import { MenuBaseClass } from "../menu_base";
-import { ScheduleService } from "../schedule/schedule.service";
-
-/** Component that handles dashboard. */
-@Component({
- selector: 'app-dashboard',
- templateUrl: './dashboard.component.html',
- providers: [ BuildService, ScheduleService ],
- styleUrls: ['./dashboard.component.scss']
-})
-export class DashboardComponent extends MenuBaseClass implements OnInit {
- lastBuildUpdateTime: any = '---';
- lastScheduleUpdateTime: any = '---';
-
- constructor(private buildService: BuildService,
- private scheduleService: ScheduleService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- ngOnInit(): void {
- this.getLatestBuild();
- this.getLastestSchedule();
- }
-
- /** Fetches the most recently updated build and gets timestamp from it. */
- getLatestBuild() {
- this.lastBuildUpdateTime = '---';
- this.buildService.getBuilds(1, 0, '', 'timestamp', 'desc')
- .subscribe(
- (response) => {
- if (response.builds) {
- this.lastBuildUpdateTime = response.builds[0].timestamp;
- }
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Fetches the most recently updated schedule and gets timestamp from it. */
- getLastestSchedule() {
- this.lastScheduleUpdateTime = '---';
- this.scheduleService.getSchedules(1, 0, '', 'timestamp', 'desc')
- .subscribe(
- (response) => {
- if (response.schedules) {
- this.lastScheduleUpdateTime = response.schedules[0].timestamp;
- }
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-}
diff --git a/gae/frontend/src/app/menu/device/device.component.html b/gae/frontend/src/app/menu/device/device.component.html
deleted file mode 100644
index b36491e..0000000
--- a/gae/frontend/src/app/menu/device/device.component.html
+++ /dev/null
@@ -1,80 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div class="entity-filter">
- <app-filter (applyFilters)="applyFilters($event)" [disabled]="loading"></app-filter>
-</div>
-<div class="mat-elevation-z2 entity-table" [ngStyle]="{'opacity': (loading) ? 0.2 : 1 }">
- <mat-table [dataSource]="dataSource" matSort matSortActive="hostname" matSortDirection="asc">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef>No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index"> {{i+1+pageSize*pageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Host Name Column -->
- <ng-container matColumnDef="hostname">
- <mat-header-cell *matHeaderCellDef mat-sort-header disabled>Host Name</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{device.hostname}} </mat-cell>
- </ng-container>
-
- <!-- Product Column -->
- <ng-container matColumnDef="product">
- <mat-header-cell *matHeaderCellDef>Product</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{device.product}} </mat-cell>
- </ng-container>
-
- <!-- Serial Column -->
- <ng-container matColumnDef="serial">
- <mat-header-cell *matHeaderCellDef>Serial</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{device.serial}} </mat-cell>
- </ng-container>
-
- <!-- Status Column -->
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{deviceStatusEnum[device.status]}} </mat-cell>
- </ng-container>
-
- <!-- Scheduling Status Column -->
- <ng-container matColumnDef="scheduling_status">
- <mat-header-cell *matHeaderCellDef>Scheduling Status</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{schedulingStatusEnum[device.scheduling_status]}} </mat-cell>
- </ng-container>
-
- <!-- Equipment Column -->
- <ng-container matColumnDef="device_equipment">
- <mat-header-cell *matHeaderCellDef>Equipment</mat-header-cell>
- <mat-cell *matCellDef="let device"> {{device.device_equipment ? device.device_equipment.join(", ") : "None"}} </mat-cell>
- </ng-container>
-
- <!-- Timestamp Column -->
- <ng-container matColumnDef="timestamp">
- <mat-header-cell *matHeaderCellDef>Timestamp</mat-header-cell>
- <mat-cell *matCellDef="let device">{{getRelativeTime(device.timestamp)}}</mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="columnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: columnTitles;"></mat-row>
- </mat-table>
- <mat-paginator [length]="count"
- [pageSize]="pageSize"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="pageIndex"
- (page)="pageEvent = onPageEvent($event)">
- </mat-paginator>
-</div>
-<div class="loading-spinner" *ngIf="loading">
- <mat-spinner color="primary"></mat-spinner>
-</div>
diff --git a/gae/frontend/src/app/menu/device/device.component.scss b/gae/frontend/src/app/menu/device/device.component.scss
deleted file mode 100644
index 165de43..0000000
--- a/gae/frontend/src/app/menu/device/device.component.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-.mat-header-cell {
- padding: 0 10px 0 10px;
-}
-
-.mat-cell {
- padding: 0 10px 0 10px;
-}
diff --git a/gae/frontend/src/app/menu/device/device.component.ts b/gae/frontend/src/app/menu/device/device.component.ts
deleted file mode 100644
index 6258aed..0000000
--- a/gae/frontend/src/app/menu/device/device.component.ts
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
-
-import { AppService } from '../../appservice';
-import { Device } from '../../model/device';
-import { DeviceService } from './device.service';
-import { DeviceStatus, SchedulingStatus } from '../../shared/vtslab_status';
-import { FilterComponent } from '../../shared/filter/filter.component';
-import { FilterItem } from '../../model/filter_item';
-import { MenuBaseClass } from '../menu_base';
-
-
-/** Component that handles device menu. */
-@Component({
- selector: 'app-device',
- templateUrl: './device.component.html',
- providers: [ DeviceService ],
- styleUrls: ['./device.component.scss'],
-})
-export class DeviceComponent extends MenuBaseClass implements OnInit {
- columnTitles = [
- '_index',
- 'hostname',
- 'product',
- 'serial',
- 'status',
- 'scheduling_status',
- 'device_equipment',
- 'timestamp',
- ];
- dataSource = new MatTableDataSource<Device>();
- pageEvent: PageEvent;
- deviceStatusEnum = DeviceStatus;
- schedulingStatusEnum = SchedulingStatus;
- appliedFilters: FilterItem[];
-
- sort = '';
- sortDirection = '';
-
- @ViewChild(FilterComponent) filterComponent: FilterComponent;
-
- constructor(private deviceService: DeviceService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- ngOnInit(): void {
- this.sort = 'hostname';
- this.sortDirection = 'asc';
-
- this.filterComponent.setSelectorList(Device);
- this.getCount();
- this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
- }
-
- /** Gets a total count of devices. */
- getCount(observer = this.getDefaultCountObservable()) {
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.deviceService.getCount(filterJSON).subscribe(observer);
- }
-
- /** Gets devices.
- * @param size A number, at most this many results will be returned.
- * @param offset A Number of results to skip.
- */
- getDevices(size = 0, offset = 0) {
- this.loading = true;
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.deviceService.getDevices(size, offset, filterJSON, this.sort, this.sortDirection)
- .subscribe(
- (response) => {
- this.loading = false;
- if (this.count >= 0) {
- let length = 0;
- if (response.devices) {
- length = response.devices.length;
- }
- const total = length + offset;
- if (response.has_next) {
- if (length !== this.pageSize) {
- this.showSnackbar('Received unexpected number of entities.');
- } else if (this.count <= total) {
- this.getCount();
- }
- } else {
- if (this.count !== total) {
- if (length !== this.count) {
- this.getCount();
- } else if (this.count > total) {
- const countObservable = this.getDefaultCountObservable([
- () => {
- this.pageIndex = Math.floor(this.count / this.pageSize);
- this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
- }
- ]);
- this.getCount(countObservable);
- }
- }
- }
- }
- this.dataSource.data = response.devices;
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Hooks a page event and handles properly. */
- onPageEvent(event: PageEvent) {
- this.pageSize = event.pageSize;
- this.pageIndex = event.pageIndex;
- this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
- return event;
- }
-
- /** Applies a filter and get entities with it. */
- applyFilters(filters) {
- this.pageIndex = 0;
- this.appliedFilters = filters;
- this.getCount();
- this.getDevices(this.pageSize, this.pageSize * this.pageIndex);
- }
-}
diff --git a/gae/frontend/src/app/menu/device/device.service.ts b/gae/frontend/src/app/menu/device/device.service.ts
deleted file mode 100644
index 2a465ff..0000000
--- a/gae/frontend/src/app/menu/device/device.service.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { catchError } from 'rxjs/operators';
-import { Observable } from 'rxjs';
-
-import { environment } from '../../../environments/environment';
-import { DeviceWrapper } from '../../model/device_wrapper';
-import { ServiceBase } from '../../shared/servicebase';
-
-
-@Injectable()
-export class DeviceService extends ServiceBase {
- constructor(public httpClient: HttpClient) {
- super(httpClient);
- this.url = environment['baseURL'] + '/host/v1/';
- }
-
- getDevices(size: number,
- offset: number,
- filterInfo: string,
- sort: string,
- direction: string): Observable<DeviceWrapper> {
- const url = this.url + 'get';
- return this.httpClient.post<DeviceWrapper>(url, {size: size, offset: offset, filter: filterInfo, sort: sort, direction: direction})
- .pipe(catchError(this.handleError));
- }
-}
diff --git a/gae/frontend/src/app/menu/job/_job-theme.scss b/gae/frontend/src/app/menu/job/_job-theme.scss
deleted file mode 100644
index 084f1fb..0000000
--- a/gae/frontend/src/app/menu/job/_job-theme.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@mixin schedule-theme($theme) {
- $primary: map-get($theme, primary);
- $accent: map-get($theme, accent);
- $warn: map-get($theme, warn);
- $background: map-get($theme, background);
- $foreground: map-get($theme, foreground);
-}
diff --git a/gae/frontend/src/app/menu/job/job.component.html b/gae/frontend/src/app/menu/job/job.component.html
deleted file mode 100644
index 634402d..0000000
--- a/gae/frontend/src/app/menu/job/job.component.html
+++ /dev/null
@@ -1,192 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div class="statistics-table" [ngStyle]="{'opacity': (loading) ? 0.2 : 1 }">
- <mat-table [dataSource]="statDataSource">
- <ng-container matColumnDef="hours">
- <mat-header-cell *matHeaderCellDef>Stats</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.hours}} </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="created">
- <mat-header-cell *matHeaderCellDef>Created</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.created}} </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="completed">
- <mat-header-cell *matHeaderCellDef>Completed</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.completed}} ({{stat.created > 0 ? (stat.completed/stat.created*100 | number:'1.0-2') : 0}})% </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="running">
- <mat-header-cell *matHeaderCellDef>Running/Ready</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.running}} ({{stat.created > 0 ? (stat.running/stat.created*100 | number:'1.0-2') : 0}})% </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="bootup_err">
- <mat-header-cell *matHeaderCellDef>Boot-up Error</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.bootup_err}} ({{stat.created > 0 ? (stat.bootup_err/stat.created*100 | number:'1.0-2') : 0}})% </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="infra_err">
- <mat-header-cell *matHeaderCellDef>Infra Error</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.infra_err}} ({{stat.created > 0 ? (stat.infra_err/stat.created*100 | number:'1.0-2') : 0}})% </mat-cell>
- </ng-container>
-
- <ng-container matColumnDef="expired">
- <mat-header-cell *matHeaderCellDef>Expired</mat-header-cell>
- <mat-cell *matCellDef="let stat"> {{stat.expired}} ({{stat.created > 0 ? (stat.expired/stat.created*100 | number:'1.0-2') : 0}})% </mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="statColumnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: statColumnTitles;"></mat-row>
- </mat-table>
-</div>
-<div class="entity-filter">
- <app-filter (applyFilters)="applyFilters($event)" [disabled]="loading"></app-filter>
-</div>
-<div class="mat-elevation-z2 entity-table" [ngStyle]="{'opacity': (loading) ? 0.2 : 1 }">
- <mat-table [dataSource]="dataSource" matSort matSortActive="timestamp" matSortDirection="desc">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef>No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index"> {{i+1+pageSize*pageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Test Type Column -->
- <ng-container matColumnDef="test_type">
- <mat-header-cell *matHeaderCellDef>Test Type</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{getTestTypeText(job.test_type)}} </mat-cell>
- </ng-container>
-
- <!-- Test Name Column -->
- <ng-container matColumnDef="test_name">
- <mat-header-cell *matHeaderCellDef>Test Name</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.test_name}} </mat-cell>
- </ng-container>
-
- <!-- Host Name Column -->
- <ng-container matColumnDef="hostname">
- <mat-header-cell *matHeaderCellDef>Hostname</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.hostname}} </mat-cell>
- </ng-container>
-
- <!-- Device Column -->
- <ng-container matColumnDef="device">
- <mat-header-cell *matHeaderCellDef>Device</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.device}} </mat-cell>
- </ng-container>
-
- <!-- Serial Column -->
- <ng-container matColumnDef="serial">
- <mat-header-cell *matHeaderCellDef>Serial</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.serial ? job.serial.join('\n') : ""}} </mat-cell>
- </ng-container>
-
- <!-- Device Branch Column -->
- <ng-container matColumnDef="manifest_branch">
- <mat-header-cell *matHeaderCellDef>Device Branch</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.manifest_branch}} </mat-cell>
- </ng-container>
-
- <!-- Device Build Target Column -->
- <ng-container matColumnDef="build_target">
- <mat-header-cell *matHeaderCellDef>Device Build Target</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.build_target}} </mat-cell>
- </ng-container>
-
- <!-- Device Build ID Column -->
- <ng-container matColumnDef="build_id">
- <mat-header-cell *matHeaderCellDef>Device Build ID</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.build_id}} </mat-cell>
- </ng-container>
-
- <!-- GSI Branch Column -->
- <ng-container matColumnDef="gsi_branch">
- <mat-header-cell *matHeaderCellDef>GSI Branch</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.gsi_branch}} </mat-cell>
- </ng-container>
-
- <!-- GSI Build Target Column -->
- <ng-container matColumnDef="gsi_build_target">
- <mat-header-cell *matHeaderCellDef>GSI Build Target</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.gsi_build_target}} </mat-cell>
- </ng-container>
-
- <!-- Device Build ID Column -->
- <ng-container matColumnDef="gsi_build_id">
- <mat-header-cell *matHeaderCellDef>GSI Build ID</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.gsi_build_id}} </mat-cell>
- </ng-container>
-
- <!-- Test Branch Column -->
- <ng-container matColumnDef="test_branch">
- <mat-header-cell *matHeaderCellDef>Test Branch</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.test_branch}} </mat-cell>
- </ng-container>
-
- <!-- Test Build Target Column -->
- <ng-container matColumnDef="test_build_target">
- <mat-header-cell *matHeaderCellDef>Test Build Target</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.test_build_target}} </mat-cell>
- </ng-container>
-
- <!-- Test Build ID Column -->
- <ng-container matColumnDef="test_build_id">
- <mat-header-cell *matHeaderCellDef>Test Build ID</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{job.test_build_id}} </mat-cell>
- </ng-container>
-
- <!-- Status Column -->
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{jobStatusEnum[job.status]}} </mat-cell>
- </ng-container>
-
- <!-- Timestamp Column -->
- <ng-container matColumnDef="timestamp">
- <mat-header-cell *matHeaderCellDef mat-sort-header disabled>Timestamp</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{getRelativeTime(job.timestamp)}} </mat-cell>
- </ng-container>
-
- <!-- Heartbeat stamp Column -->
- <ng-container matColumnDef="heartbeat_stamp">
- <mat-header-cell *matHeaderCellDef>Heartbeat</mat-header-cell>
- <mat-cell *matCellDef="let job"> {{getRelativeTime(job.heartbeat_stamp)}} </mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="columnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: columnTitles;"
- matRipple
- class="element-row"
- [appCdkDetailRow]="row" [appCdkDetailRowTpl]="job_detail"></mat-row>
- </mat-table>
- <mat-paginator [length]="count"
- [pageSize]="pageSize"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="pageIndex"
- (page)="pageEvent = onPageEvent($event)">
- </mat-paginator>
-</div>
-<ng-template #job_detail let-job>
- <div class="mat-row div-expandable" [@detailExpand] style="overflow: hidden">
- <a href="{{job.infra_log_url}}" download><button mat-raised-button [disabled]="(!job.infra_log_url)">Download Infra Log</button></a>
- <button mat-raised-button (click)="onShowDetailsClicked(job)">
- Show Details
- </button>
- </div>
-</ng-template>
-<div class="loading-spinner" *ngIf="loading">
- <mat-spinner color="primary"></mat-spinner>
-</div>
diff --git a/gae/frontend/src/app/menu/job/job.component.scss b/gae/frontend/src/app/menu/job/job.component.scss
deleted file mode 100644
index c8aee00..0000000
--- a/gae/frontend/src/app/menu/job/job.component.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-.mat-header-cell {
- padding: 0 10px 0 10px;
-}
-
-.mat-cell {
- padding: 0 10px 0 10px;
-}
-
-.element-row {
- position: relative;
- overflow: hidden;
-}
-
-.element-row:not(.expanded) {
- cursor: pointer;
-}
-
-.element-row:not(.expanded):hover {
- background: #f5f5f5;
-}
-
-.element-row.expanded {
- border-bottom-color: transparent;
-}
diff --git a/gae/frontend/src/app/menu/job/job.component.ts b/gae/frontend/src/app/menu/job/job.component.ts
deleted file mode 100644
index 4375581..0000000
--- a/gae/frontend/src/app/menu/job/job.component.ts
+++ /dev/null
@@ -1,221 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
-import { animate, state, style, transition, trigger } from '@angular/animations';
-
-import { AppService } from '../../appservice';
-import { FilterComponent } from '../../shared/filter/filter.component';
-import { FilterCondition } from '../../model/filter_condition';
-import { FilterItem } from '../../model/filter_item';
-import { MenuBaseClass } from '../menu_base';
-import { Job } from '../../model/job';
-import { JobService } from './job.service';
-import { JobStatus, TestType } from '../../shared/vtslab_status';
-
-import * as moment from 'moment-timezone';
-
-
-/** Component that handles job menu. */
-@Component({
- selector: 'app-job',
- templateUrl: './job.component.html',
- providers: [ JobService ],
- styleUrls: ['./job.component.scss'],
- animations: [
- trigger('detailExpand', [
- state('void', style({height: '0px', minHeight: '0', visibility: 'hidden'})),
- state('*', style({height: '*', visibility: 'visible'})),
- transition('void <=> *', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
- ]),
- ],
-})
-export class JobComponent extends MenuBaseClass implements OnInit {
- columnTitles = [
- '_index',
- 'test_type',
- 'test_name',
- 'hostname',
- 'device',
- 'serial',
- 'manifest_branch',
- 'build_target',
- 'build_id',
- 'gsi_branch',
- 'gsi_build_target',
- 'gsi_build_id',
- 'test_branch',
- 'test_build_target',
- 'test_build_id',
- 'status',
- 'timestamp',
- 'heartbeat_stamp',
- ];
- statColumnTitles = [
- 'hours',
- 'created',
- 'completed',
- 'running',
- 'bootup_err',
- 'infra_err',
- 'expired',
- ];
- dataSource = new MatTableDataSource<Job>();
- statDataSource = new MatTableDataSource();
- pageEvent: PageEvent;
- jobStatusEnum = JobStatus;
- appliedFilters: FilterItem[];
-
- @ViewChild(FilterComponent) filterComponent: FilterComponent;
-
- sort = '';
- sortDirection = '';
-
- constructor(private jobService: JobService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- ngOnInit(): void {
- // By default, job page requires list in desc order by timestamp.
- this.sort = 'timestamp';
- this.sortDirection = 'desc';
-
- this.filterComponent.setSelectorList(Job);
- this.getCount();
- this.getStatistics();
- this.getJobs(this.pageSize, this.pageSize * this.pageIndex);
- }
-
- /** Gets a total count of jobs. */
- getCount(observer = this.getDefaultCountObservable()) {
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.jobService.getCount(filterJSON).subscribe(observer);
- }
-
- /** Gets jobs.
- * @param size A number, at most this many results will be returned.
- * @param offset A Number of results to skip.
- */
- getJobs(size = 0, offset = 0) {
- this.loading = true;
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.jobService.getJobs(size, offset, filterJSON, this.sort, this.sortDirection)
- .subscribe(
- (response) => {
- this.loading = false;
- if (this.count >= 0) {
- let length = 0;
- if (response.jobs) {
- length = response.jobs.length;
- }
- const total = length + offset;
- if (response.has_next) {
- if (length !== this.pageSize) {
- this.showSnackbar('Received unexpected number of entities.');
- } else if (this.count <= total) {
- this.getCount();
- }
- } else {
- if (this.count !== total) {
- if (length !== this.count) {
- this.getCount();
- } else if (this.count > total) {
- const countObservable = this.getDefaultCountObservable([
- () => {
- this.pageIndex = Math.floor(this.count / this.pageSize);
- this.getJobs(this.pageSize, this.pageSize * this.pageIndex);
- }
- ]);
- this.getCount(countObservable);
- }
- }
- }
- }
- this.dataSource.data = response.jobs;
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Hooks a page event and handles properly. */
- onPageEvent(event: PageEvent) {
- this.pageSize = event.pageSize;
- this.pageIndex = event.pageIndex;
- this.getJobs(this.pageSize, this.pageSize * this.pageIndex);
- return event;
- }
-
- /** Gets the recent jobs and calculate statistics */
- getStatistics() {
- const timeFilter = new FilterItem();
- timeFilter.key = 'timestamp';
- timeFilter.method = FilterCondition.GreaterThan;
- timeFilter.value = '72';
- const timeFilterString = JSON.stringify([timeFilter]);
- this.jobService.getJobs(0, 0, timeFilterString, '', '')
- .subscribe(
- (response) => {
- const stats_72hrs = this.buildStatisticsData('72 Hours', response.jobs);
- const jobs_24hrs = (response.jobs == null || response.jobs.length === 0) ? undefined : response.jobs.filter(
- job => (moment() - moment.tz(job.timestamp, 'YYYY-MM-DDThh:mm:ss', 'UTC')) / 3600000 < 24);
- const stats_24hrs = this.buildStatisticsData('24 Hours', jobs_24hrs);
- this.statDataSource.data = [stats_24hrs, stats_72hrs];
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Builds statistics from given jobs list */
- buildStatisticsData(title, jobs) {
- if (jobs == null || jobs.length === 0) {
- return { hours: title, created: 0, completed: 0, running: 0, bootup_err: 0, infra_err: 0, expired: 0 };
- }
- return {
- hours: title,
- created: jobs.length,
- completed: jobs.filter(job => job.status != null && Number(job.status) === JobStatus.Complete).length,
- running: jobs.filter(job => job.status != null &&
- (Number(job.status) === JobStatus.Leased || Number(job.status) === JobStatus.Ready)).length,
- bootup_err: jobs.filter(job => job.status != null && Number(job.status) === JobStatus.Bootup_err).length,
- infra_err: jobs.filter(job => job.status != null && Number(job.status) === JobStatus.Infra_err).length,
- expired: jobs.filter(job => job.status != null && Number(job.status) === JobStatus.Expired).length,
- };
- }
-
- /** Generates text to represent in HTML with given test type. */
- getTestTypeText(status: number) {
- if (status === undefined || status & TestType.Unknown) {
- return TestType[TestType.Unknown];
- }
-
- const text_list = [];
- [TestType.ToT, TestType.OTA, TestType.Signed, TestType.Manual].forEach(function (value) {
- if (status & value) { text_list.push(TestType[value]); }
- });
-
- return text_list.join(', ');
- }
-
- /** Applies a filter and get entities with it. */
- applyFilters(filters) {
- this.pageIndex = 0;
- this.appliedFilters = filters;
- this.getCount();
- this.getJobs(this.pageSize, this.pageSize * this.pageIndex);
- }
-}
diff --git a/gae/frontend/src/app/menu/job/job.service.ts b/gae/frontend/src/app/menu/job/job.service.ts
deleted file mode 100644
index 71b5417..0000000
--- a/gae/frontend/src/app/menu/job/job.service.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { catchError } from 'rxjs/operators';
-import { Observable } from 'rxjs';
-
-import { environment } from '../../../environments/environment';
-import { JobWrapper } from '../../model/job_wrapper';
-import { ServiceBase } from '../../shared/servicebase';
-
-
-@Injectable()
-export class JobService extends ServiceBase {
- // url: string;
- constructor(public httpClient: HttpClient) {
- super(httpClient);
- this.url = environment['baseURL'] + '/job/v1/';
- }
-
- getJobs(size: number,
- offset: number,
- filterInfo: string,
- sort: string,
- direction: string): Observable<JobWrapper> {
- const url = this.url + 'get';
- return this.httpClient.post<JobWrapper>(url, {size: size, offset: offset, filter: filterInfo, sort: sort, direction: direction})
- .pipe(catchError(this.handleError));
- }
-}
diff --git a/gae/frontend/src/app/menu/lab/lab.component.html b/gae/frontend/src/app/menu/lab/lab.component.html
deleted file mode 100644
index 0392e2d..0000000
--- a/gae/frontend/src/app/menu/lab/lab.component.html
+++ /dev/null
@@ -1,109 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<mat-tab-group>
- <mat-tab label="Lab">
- <div class="mat-elevation-z2 entity-table">
- <mat-table #table [dataSource]="labDataSource">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef class="index-column">No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index" class="index-column"> {{i+1+pageSize*labPageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Name Column -->
- <ng-container matColumnDef="name">
- <mat-header-cell *matHeaderCellDef>Name</mat-header-cell>
- <mat-cell *matCellDef="let lab"> {{lab.name}} </mat-cell>
- </ng-container>
-
- <!-- Owner Column -->
- <ng-container matColumnDef="owner">
- <mat-header-cell *matHeaderCellDef>Owner</mat-header-cell>
- <mat-cell *matCellDef="let lab"> {{lab.owner}} </mat-cell>
- </ng-container>
-
- <!-- Admin Column -->
- <ng-container matColumnDef="admin">
- <mat-header-cell *matHeaderCellDef>Admin</mat-header-cell>
- <mat-cell *matCellDef="let lab"> {{lab.admin ? lab.admin.join(", ") : "None"}} </mat-cell>
- </ng-container>
-
- <!-- Host Count Column -->
- <ng-container matColumnDef="hostCount">
- <mat-header-cell *matHeaderCellDef># of Host</mat-header-cell>
- <mat-cell *matCellDef="let lab"> {{ lab.hosts.length }} </mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="labColumnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: labColumnTitles;"></mat-row>
- </mat-table>
- <mat-paginator [length]="labCount"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="labPageIndex">
- </mat-paginator>
- </div>
- </mat-tab>
- <mat-tab label="Host">
- <div class="mat-elevation-z2 entity-table">
- <mat-table #table [dataSource]="hostDataSource">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef class="index-column">No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index" class="index-column"> {{i+1+pageSize*pageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Lab Column -->
- <ng-container matColumnDef="name">
- <mat-header-cell *matHeaderCellDef>Lab</mat-header-cell>
- <mat-cell *matCellDef="let host"> {{host.name}} </mat-cell>
- </ng-container>
-
- <!-- Hostname Column -->
- <ng-container matColumnDef="hostname">
- <mat-header-cell *matHeaderCellDef>Hostname</mat-header-cell>
- <mat-cell *matCellDef="let host"> {{host.hostname}} </mat-cell>
- </ng-container>
-
- <!-- IP Column -->
- <ng-container matColumnDef="ip">
- <mat-header-cell *matHeaderCellDef>IP</mat-header-cell>
- <mat-cell *matCellDef="let host"> {{host.ip}} </mat-cell>
- </ng-container>
-
- <!-- Host Equipment Column -->
- <ng-container matColumnDef="host_equipment">
- <mat-header-cell *matHeaderCellDef>Equipment</mat-header-cell>
- <mat-cell *matCellDef="let host"> {{host.host_equipment}} </mat-cell>
- </ng-container>
-
- <!-- Version Column -->
- <ng-container matColumnDef="vtslab_version">
- <mat-header-cell *matHeaderCellDef>Version</mat-header-cell>
- <mat-cell *matCellDef="let host"> {{host.vtslab_version}} </mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="hostColumnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: hostColumnTitles;"></mat-row>
- </mat-table>
- <mat-paginator [length]="count"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="labPageIndex">
- </mat-paginator>
- </div>
- </mat-tab>
-</mat-tab-group>
-<div class="loading-spinner" *ngIf="loading">
- <mat-spinner color="primary"></mat-spinner>
-</div>
diff --git a/gae/frontend/src/app/menu/lab/lab.component.scss b/gae/frontend/src/app/menu/lab/lab.component.scss
deleted file mode 100644
index fed2fb6..0000000
--- a/gae/frontend/src/app/menu/lab/lab.component.scss
+++ /dev/null
@@ -1,41 +0,0 @@
-.mat-table {
- overflow: auto;
-}
-
-.entity-table {
- display: flex;
- flex-direction: column;
-}
-
-.mat-header-cell {
- padding: 0 10px 0 10px;
-}
-
-.index-column {
- max-width: 40px;
-}
-
-.mat-cell {
- padding: 0 10px 0 10px;
-}
-
-.element-row {
- position: relative;
- overflow: hidden;
-}
-
-.element-row:not(.expanded) {
- cursor: pointer;
-}
-
-.element-row:not(.expanded):hover {
- background: #f5f5f5;
-}
-
-.element-row.expanded {
- border-bottom-color: transparent;
-}
-
-.div-expandable {
- padding: 10px 20px 30px 20px;
-}
diff --git a/gae/frontend/src/app/menu/lab/lab.component.ts b/gae/frontend/src/app/menu/lab/lab.component.ts
deleted file mode 100644
index bb7543b..0000000
--- a/gae/frontend/src/app/menu/lab/lab.component.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit } from '@angular/core';
-import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
-
-import { AppService } from '../../appservice';
-import { Host } from '../../model/host';
-import { Lab } from '../../model/lab';
-import { LabService } from './lab.service';
-import { MenuBaseClass } from '../menu_base';
-
-/** Component that handles lab and host menu. */
-@Component({
- selector: 'app-lab',
- templateUrl: './lab.component.html',
- providers: [ LabService ],
- styleUrls: ['./lab.component.scss'],
-})
-export class LabComponent extends MenuBaseClass implements OnInit {
- labColumnTitles = [
- '_index',
- 'name',
- 'owner',
- 'admin',
- 'hostCount',
- ];
- hostColumnTitles = [
- '_index',
- 'name',
- 'hostname',
- 'ip',
- 'host_equipment',
- 'vtslab_version',
- ];
- labCount = -1;
- labPageIndex = 0;
-
- constructor(private labService: LabService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- labDataSource = new MatTableDataSource<Lab>();
- hostDataSource = new MatTableDataSource<Host>();
-
- ngOnInit(): void {
- // For labs and hosts, it does not use query pagination.
- this.getHosts();
- }
-
- /** Gets hosts.
- * @param size A number, at most this many results will be returned.
- * @param offset A Number of results to skip.
- */
- getHosts(size = 0, offset = 0) {
- this.loading = true;
- // Labs will not use filter for query.
- const filterJSON = '';
- this.labService.getLabs(size, offset, filterJSON, '', '')
- .subscribe(
- (response) => {
- this.loading = false;
- if (response.labs) {
- this.count = response.labs.length;
- this.hostDataSource.data = response.labs;
- this.setLabs(response.labs);
- }
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Sets labs from given hosts.
- * @param hosts A list of Host instances.
- */
- setLabs(hosts: Host[]) {
- if (hosts == null || hosts.length === 0) { return; }
- const labMap = new Map();
- hosts.forEach(function(host) {
- if (labMap.has(host.name)) {
- labMap.get(host.name).hosts.push(host);
- } else {
- labMap.set(host.name, {name: host.name, owner: host.owner, admin: host.admin, hosts: [host]});
- }
- });
- const labs: Lab[] = [];
- labMap.forEach((value) => labs.push(value));
- this.labDataSource.data = labs;
- }
-}
diff --git a/gae/frontend/src/app/menu/lab/lab.service.ts b/gae/frontend/src/app/menu/lab/lab.service.ts
deleted file mode 100644
index 2d677b1..0000000
--- a/gae/frontend/src/app/menu/lab/lab.service.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { catchError } from 'rxjs/operators';
-import { Observable } from 'rxjs';
-
-import { environment } from '../../../environments/environment';
-import { HostWrapper } from '../../model/host_wrapper';
-import { ServiceBase } from '../../shared/servicebase';
-
-
-@Injectable()
-export class LabService extends ServiceBase {
- // url: string;
- constructor(public httpClient: HttpClient) {
- super(httpClient);
- this.url = environment['baseURL'] + '/lab/v1/';
- }
-
- getLabs(size: number,
- offset: number,
- filterInfo: string,
- sort: string,
- direction: string): Observable<HostWrapper> {
- const url = this.url + 'get';
- return this.httpClient.post<HostWrapper>(url, {size: size, offset: offset, filter: filterInfo, sort: sort, direction: direction})
- .pipe(catchError(this.handleError));
- }
-}
diff --git a/gae/frontend/src/app/menu/menu-items.ts b/gae/frontend/src/app/menu/menu-items.ts
deleted file mode 100644
index a544366..0000000
--- a/gae/frontend/src/app/menu/menu-items.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export const MENUS = {
- ['VTSLab Scheduler']: '/',
- ['build']: '/build',
- ['device']: '/device',
- ['lab']: '/lab',
- ['schedule']: '/schedule',
- ['job']: '/job',
-};
diff --git a/gae/frontend/src/app/menu/menu_base.ts b/gae/frontend/src/app/menu/menu_base.ts
deleted file mode 100644
index 4d68f03..0000000
--- a/gae/frontend/src/app/menu/menu_base.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** This class defines and/or implements the common properties and methods
- * used among menus.
- */
-import { AppService } from '../appservice';
-import { MatSnackBar } from '@angular/material';
-import moment from 'moment-timezone';
-
-
-export abstract class MenuBaseClass {
- count = -1;
-
- loading = false;
- pageSizeOptions = [20, 50, 100, 200];
- pageSize = 100;
- pageIndex = 0;
-
- protected constructor(private appService: AppService,
- public snackBar: MatSnackBar) {
- this.appService.closeSideNav();
- this.snackBar.dismiss();
- }
-
- /** Returns an Observable which handles a response of count API.
- * @param additionalOperations A list of lambda functions.
- */
- getDefaultCountObservable(additionalOperations: any[] = []) {
- return {
- next: (response) => {
- this.count = response.count;
- for (const operation of additionalOperations) {
- operation(response);
- }
- },
- error: (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- };
- }
-
- getRelativeTime(timeString) {
- return (moment.tz(timeString, 'YYYY-MM-DDThh:mm:ss', 'UTC').isValid() ?
- moment.tz(timeString, 'YYYY-MM-DDThh:mm:ss', 'UTC').fromNow() : '---');
- }
-
- /** Checks whether timeString is expired from current time. */
- isExpired(timeString, hours=72) {
- let currentTime = moment.tz(timeString, 'YYYY-MM-DDThh:mm:ss', 'UTC');
- if (!currentTime.isValid()) { return false; }
-
- let diff = moment().diff(currentTime);
- let duration = moment.duration(diff);
- return duration.asHours() > hours;
- }
-
- /** Displays a snackbar notification. */
- showSnackbar(message = 'Error', duration = 5000) {
- this.loading = false;
- this.snackBar.open(message, 'DISMISS', {duration});
- }
-
- /** Displays a side nav window and lists all properties of selected entity. */
- onShowDetailsClicked(entity) {
- this.appService.showDetails(entity);
- }
-}
diff --git a/gae/frontend/src/app/menu/schedule/_schedule-theme.scss b/gae/frontend/src/app/menu/schedule/_schedule-theme.scss
deleted file mode 100644
index 084f1fb..0000000
--- a/gae/frontend/src/app/menu/schedule/_schedule-theme.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@mixin schedule-theme($theme) {
- $primary: map-get($theme, primary);
- $accent: map-get($theme, accent);
- $warn: map-get($theme, warn);
- $background: map-get($theme, background);
- $foreground: map-get($theme, foreground);
-}
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.html b/gae/frontend/src/app/menu/schedule/schedule.component.html
deleted file mode 100644
index 910d45b..0000000
--- a/gae/frontend/src/app/menu/schedule/schedule.component.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div class="entity-filter">
- <app-filter (applyFilters)="applyFilters($event)" [disabled]="loading"></app-filter>
-</div>
-<div class="mat-elevation-z2 entity-table" [ngStyle]="{'opacity': (loading) ? 0.2 : 1 }">
- <mat-table [dataSource]="dataSource">
- <!-- Index Column -->
- <ng-container matColumnDef="_index">
- <mat-header-cell *matHeaderCellDef>No.</mat-header-cell>
- <mat-cell *matCellDef="let i = index"> {{i+1+pageSize*pageIndex}} </mat-cell>
- </ng-container>
-
- <!-- Test Name Column -->
- <ng-container matColumnDef="test_name">
- <mat-header-cell *matHeaderCellDef>Test Name</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.test_name}} </mat-cell>
- </ng-container>
-
- <!-- Device Column -->
- <ng-container matColumnDef="device">
- <mat-header-cell *matHeaderCellDef>Device</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.device ? schedule.device.join('\n') : ""}} </mat-cell>
- </ng-container>
-
- <!-- Manifest Branch Column -->
- <ng-container matColumnDef="manifest_branch">
- <mat-header-cell *matHeaderCellDef>Manifest Branch</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.manifest_branch}}</mat-cell>
- </ng-container>
-
- <!-- Build Target Column -->
- <ng-container matColumnDef="build_target">
- <mat-header-cell *matHeaderCellDef>Build Target</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.build_target}} </mat-cell>
- </ng-container>
-
- <!-- GSI Branch Column -->
- <ng-container matColumnDef="gsi_branch">
- <mat-header-cell *matHeaderCellDef>GSI Branch</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.gsi_branch}} </mat-cell>
- </ng-container>
-
- <!-- GSI Build Target Column -->
- <ng-container matColumnDef="gsi_build_target">
- <mat-header-cell *matHeaderCellDef>GSI Build Target</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.gsi_build_target}} </mat-cell>
- </ng-container>
-
- <!-- Test Branch Column -->
- <ng-container matColumnDef="test_branch">
- <mat-header-cell *matHeaderCellDef>Test Branch</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.test_branch}} </mat-cell>
- </ng-container>
-
- <!-- Test Build Target Column -->
- <ng-container matColumnDef="test_build_target">
- <mat-header-cell *matHeaderCellDef>Test Build Target</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.test_build_target}}</mat-cell>
- </ng-container>
-
- <!-- Period Column -->
- <ng-container matColumnDef="period">
- <mat-header-cell *matHeaderCellDef>Period</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{schedule.period}}</mat-cell>
- </ng-container>
-
- <!-- Status Column -->
- <ng-container matColumnDef="status">
- <mat-header-cell *matHeaderCellDef>Status</mat-header-cell>
- <mat-cell *matCellDef="let schedule"
- [ngStyle]="{color: (schedule.suspended || isExpired(schedule.timestamp)) ? '#FF0000' : '#000000'}">
- {{schedule.suspended ? "Suspended" : (isExpired(schedule.timestamp) ? "Expired" : "Active")}}
- </mat-cell>
- </ng-container>
-
- <!-- Timestamp Column -->
- <ng-container matColumnDef="timestamp">
- <mat-header-cell *matHeaderCellDef>Timestamp</mat-header-cell>
- <mat-cell *matCellDef="let schedule"> {{getRelativeTime(schedule.timestamp)}}</mat-cell>
- </ng-container>
-
- <mat-header-row *matHeaderRowDef="columnTitles"></mat-header-row>
- <mat-row *matRowDef="let row; columns: columnTitles;"
- matRipple
- class="element-row"
- [appCdkDetailRow]="row" [appCdkDetailRowTpl]="schedule_detail"></mat-row>
- </mat-table>
-
- <mat-paginator [length]="count"
- [pageSize]="pageSize"
- [pageSizeOptions]="pageSizeOptions"
- [pageIndex]="pageIndex"
- (page)="pageEvent = onPageEvent($event)">
- </mat-paginator>
-</div>
-<ng-template #schedule_detail let-schedule>
- <div class="mat-row div-expandable" [@detailExpand] style="overflow: hidden">
- <button mat-raised-button (click)="suspendSchedule([{urlsafe_key: schedule.urlsafe_key, suspend: !schedule.suspended}])">
- {{(schedule.suspended ? "Resume" : "Suspend")}}
- </button>
- <button mat-raised-button (click)="onShowDetailsClicked(schedule)">
- Show Details
- </button>
- </div>
-</ng-template>
-<div class="loading-spinner" *ngIf="loading">
- <mat-spinner color="primary"></mat-spinner>
-</div>
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.scss b/gae/frontend/src/app/menu/schedule/schedule.component.scss
deleted file mode 100644
index c8aee00..0000000
--- a/gae/frontend/src/app/menu/schedule/schedule.component.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-.mat-header-cell {
- padding: 0 10px 0 10px;
-}
-
-.mat-cell {
- padding: 0 10px 0 10px;
-}
-
-.element-row {
- position: relative;
- overflow: hidden;
-}
-
-.element-row:not(.expanded) {
- cursor: pointer;
-}
-
-.element-row:not(.expanded):hover {
- background: #f5f5f5;
-}
-
-.element-row.expanded {
- border-bottom-color: transparent;
-}
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.ts b/gae/frontend/src/app/menu/schedule/schedule.component.ts
deleted file mode 100644
index 5c1740e..0000000
--- a/gae/frontend/src/app/menu/schedule/schedule.component.ts
+++ /dev/null
@@ -1,160 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { MatSnackBar, MatTableDataSource, PageEvent } from '@angular/material';
-import { animate, state, style, transition, trigger } from "@angular/animations";
-
-import { AppService } from '../../appservice';
-import { FilterComponent } from '../../shared/filter/filter.component';
-import { FilterItem } from '../../model/filter_item';
-import { MenuBaseClass } from '../menu_base';
-import { Schedule, ScheduleSuspendResponse } from '../../model/schedule';
-import { ScheduleService } from './schedule.service';
-
-
-/** Component that handles schedule menu. */
-@Component({
- selector: 'app-schedule',
- templateUrl: './schedule.component.html',
- providers: [ ScheduleService ],
- styleUrls: ['./schedule.component.scss'],
- animations: [
- trigger('detailExpand', [
- state('void', style({height: '0px', minHeight: '0', visibility: 'hidden'})),
- state('*', style({height: '*', visibility: 'visible'})),
- transition('void <=> *', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
- ]),
- ],
-})
-export class ScheduleComponent extends MenuBaseClass implements OnInit {
- columnTitles = [
- '_index',
- 'test_name',
- 'device',
- 'manifest_branch',
- 'build_target',
- 'gsi_branch',
- 'gsi_build_target',
- 'test_branch',
- 'test_build_target',
- 'period',
- 'status',
- 'timestamp',
- ];
- dataSource = new MatTableDataSource<Schedule>();
- pageEvent: PageEvent;
- appliedFilters: FilterItem[];
-
- @ViewChild(FilterComponent) filterComponent: FilterComponent;
-
- constructor(private scheduleService: ScheduleService,
- appService: AppService,
- snackBar: MatSnackBar) {
- super(appService, snackBar);
- }
-
- ngOnInit(): void {
- this.filterComponent.setSelectorList(Schedule);
- this.getCount();
- this.getSchedules(this.pageSize, this.pageSize * this.pageIndex);
- }
-
- /** Gets a total count of schedules. */
- getCount(observer = this.getDefaultCountObservable()) {
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.scheduleService.getCount(filterJSON).subscribe(observer);
- }
-
- /** Gets schedules.
- * @param size A number, at most this many results will be returned.
- * @param offset A Number of results to skip.
- */
- getSchedules(size = 0, offset = 0) {
- this.loading = true;
- const filterJSON = (this.appliedFilters) ? JSON.stringify(this.appliedFilters) : '';
- this.scheduleService.getSchedules(size, offset, filterJSON, '', '')
- .subscribe(
- (response) => {
- this.loading = false;
- if (this.count >= 0) {
- let length = 0;
- if (response.schedules) {
- length = response.schedules.length;
- }
- const total = length + offset;
- if (response.has_next) {
- if (length !== this.pageSize) {
- this.showSnackbar('Received unexpected number of entities.');
- } else if (this.count <= total) {
- this.getCount();
- }
- } else {
- if (this.count !== total) {
- if (length !== this.count) {
- this.getCount();
- } else if (this.count > total) {
- const countObservable = this.getDefaultCountObservable([
- () => {
- this.pageIndex = Math.floor(this.count / this.pageSize);
- this.getSchedules(this.pageSize, this.pageSize * this.pageIndex);
- }
- ]);
- this.getCount(countObservable);
- }
- }
- }
- }
- this.dataSource.data = response.schedules;
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Toggles a schedule from suspend to resume, or vice versa. */
- suspendSchedule(schedules: ScheduleSuspendResponse[]) {
- this.scheduleService.suspendSchedule(schedules)
- .subscribe(
- (response) => {
- if (response.schedules) {
- let self = this;
- response.schedules.forEach(function(schedule) {
- const original = self.dataSource.data.filter(x => x.urlsafe_key === schedule.urlsafe_key);
- if (original) {
- original[0].suspended = schedule.suspend;
- }
- })
- }
- },
- (error) => this.showSnackbar(`[${error.status}] ${error.name}`)
- );
- }
-
- /** Hooks a page event and handles properly. */
- onPageEvent(event: PageEvent) {
- this.pageSize = event.pageSize;
- this.pageIndex = event.pageIndex;
- this.getSchedules(this.pageSize, this.pageSize * this.pageIndex);
- return event;
- }
-
- /** Applies a filter and get entities with it. */
- applyFilters(filters) {
- this.pageIndex = 0;
- this.appliedFilters = filters;
- this.getCount();
- this.getSchedules(this.pageSize, this.pageSize * this.pageIndex);
- }
-}
diff --git a/gae/frontend/src/app/menu/schedule/schedule.service.ts b/gae/frontend/src/app/menu/schedule/schedule.service.ts
deleted file mode 100644
index ae534dd..0000000
--- a/gae/frontend/src/app/menu/schedule/schedule.service.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-
-import { catchError } from 'rxjs/operators';
-import { Observable } from 'rxjs';
-
-import { environment } from '../../../environments/environment';
-import { ScheduleWrapper } from '../../model/schedule_wrapper';
-import { ServiceBase } from '../../shared/servicebase';
-import { ScheduleSuspendResponse, ScheduleSuspendResponseWrapper } from '../../model/schedule';
-
-
-@Injectable()
-export class ScheduleService extends ServiceBase {
- // url: string;
- constructor(public httpClient: HttpClient) {
- super(httpClient);
- this.url = environment['baseURL'] + '/schedule/v1/';
- }
-
- getSchedules(size: number,
- offset: number,
- filterInfo: string,
- sort: string,
- direction: string): Observable<ScheduleWrapper> {
- const url = this.url + 'get';
- return this.httpClient.post<ScheduleWrapper>(url, {size: size, offset: offset, filter: filterInfo, sort: sort, direction: direction})
- .pipe(catchError(this.handleError));
- }
-
- suspendSchedule(schedules: ScheduleSuspendResponse[]): Observable<ScheduleSuspendResponseWrapper> {
- const url = this.url + 'suspend';
- return this.httpClient.post<ScheduleSuspendResponseWrapper>(url, {schedules: schedules})
- .pipe(catchError(this.handleError));
- }
-}
diff --git a/gae/frontend/src/app/model/build.ts b/gae/frontend/src/app/model/build.ts
deleted file mode 100644
index bf32a4a..0000000
--- a/gae/frontend/src/app/model/build.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export class Build {
- manifest_branch: string = void 0;
- build_id: string = void 0;
- build_target: string = void 0;
- build_type: string = void 0;
- artifact_type: string = void 0;
- artifacts: string[] = void 0;
- signed: boolean = void 0;
- timestamp: any = void 0;
-}
diff --git a/gae/frontend/src/app/model/build_wrapper.ts b/gae/frontend/src/app/model/build_wrapper.ts
deleted file mode 100644
index 797d097..0000000
--- a/gae/frontend/src/app/model/build_wrapper.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Build} from './build';
-
-export interface BuildWrapper {
- builds: Build[];
- has_next: boolean;
-}
diff --git a/gae/frontend/src/app/model/device.ts b/gae/frontend/src/app/model/device.ts
deleted file mode 100644
index 21fdfb7..0000000
--- a/gae/frontend/src/app/model/device.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export class Device {
- serial: string = void 0;
- product: string = void 0;
- status: number = void 0;
- scheduling_status: number = void 0;
- hostname: string = void 0;
- device_equipment: string[] = void 0;
- timestamp: any = void 0;
-}
diff --git a/gae/frontend/src/app/model/device_wrapper.ts b/gae/frontend/src/app/model/device_wrapper.ts
deleted file mode 100644
index af18dce..0000000
--- a/gae/frontend/src/app/model/device_wrapper.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Device} from './device';
-
-export interface DeviceWrapper {
- devices: Device[];
- has_next: boolean;
-}
diff --git a/gae/frontend/src/app/model/filter_condition.ts b/gae/frontend/src/app/model/filter_condition.ts
deleted file mode 100644
index 9f76de9..0000000
--- a/gae/frontend/src/app/model/filter_condition.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export enum FilterCondition {
- EqualTo = 1,
- LessThan,
- GreaterThan,
- LessThanOrEqualTo,
- GreaterThanOrEqualTo,
- NotEqualTo,
- Has,
-}
diff --git a/gae/frontend/src/app/model/filter_item.ts b/gae/frontend/src/app/model/filter_item.ts
deleted file mode 100644
index de457a1..0000000
--- a/gae/frontend/src/app/model/filter_item.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {FilterCondition} from './filter_condition';
-
-export class FilterItem {
- key: string;
- method: FilterCondition;
- value: string; // back-end should handle type-casting.
-}
diff --git a/gae/frontend/src/app/model/host.ts b/gae/frontend/src/app/model/host.ts
deleted file mode 100644
index 3836c30..0000000
--- a/gae/frontend/src/app/model/host.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export class Host {
- name: string = void 0; // lab name
- owner: string = void 0;
- admin: string[] = void 0;
- hostname: string = void 0;
- ip: string = void 0;
- devices: string = void 0;
- vtslab_version: string = void 0;
- host_equipment: string[] = void 0;
-}
diff --git a/gae/frontend/src/app/model/host_wrapper.ts b/gae/frontend/src/app/model/host_wrapper.ts
deleted file mode 100644
index ae18a04..0000000
--- a/gae/frontend/src/app/model/host_wrapper.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Host} from './host';
-
-export interface HostWrapper {
- // Back-end stores each host information as LabModel entity, so it sends
- // host information as 'labs'.
- labs: Host[];
- has_next: boolean;
-}
diff --git a/gae/frontend/src/app/model/job.ts b/gae/frontend/src/app/model/job.ts
deleted file mode 100644
index 69e45b7..0000000
--- a/gae/frontend/src/app/model/job.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export class Job {
- test_type: number = void 0;
-
- hostname: string = void 0;
- priority: string = void 0;
- test_name: string = void 0;
- require_signed_device_build: boolean = void 0;
- has_bootloader_img: boolean = void 0;
- has_radio_img: boolean = void 0;
- device: string = void 0;
- serial: string = void 0;
-
- // device image information
- build_storage_type: number = void 0;
- manifest_branch: string = void 0;
- build_target: string = void 0;
- build_id: string = void 0;
- pab_account_id: string = void 0;
-
- shards: number = void 0;
- param: string = void 0;
- status: number = void 0;
- period: number = void 0;
-
- // GSI information
- gsi_storage_type: number = void 0;
- gsi_branch: string = void 0;
- gsi_build_target: string = void 0;
- gsi_build_id: string = void 0;
- gsi_pab_account_id: string = void 0;
- gsi_vendor_version: string = void 0;
-
- // test suite information
- test_storage_type: number = void 0;
- test_branch: string = void 0;
- test_build_target: string = void 0;
- test_build_id: string = void 0;
- test_pab_account_id: string = void 0;
-
- retry_count: number = void 0;
-
- infra_log_url: string = void 0;
-
- image_package_repo_base: string = void 0;
-
- report_bucket: string = void 0;
- report_spreadsheet_id: string = void 0;
-
- timestamp = void 0;
- heartbeat_stamp = void 0;
-}
diff --git a/gae/frontend/src/app/model/job_wrapper.ts b/gae/frontend/src/app/model/job_wrapper.ts
deleted file mode 100644
index 5a1f915..0000000
--- a/gae/frontend/src/app/model/job_wrapper.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Job} from './job';
-
-export interface JobWrapper {
- jobs: Job[];
- has_next: boolean;
-}
diff --git a/gae/frontend/src/app/model/lab.ts b/gae/frontend/src/app/model/lab.ts
deleted file mode 100644
index 0f98360..0000000
--- a/gae/frontend/src/app/model/lab.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Host} from './host';
-
-export class Lab {
- name: string = void 0;
- owner: string = void 0;
- admin: string[] = void 0;
- hosts: Host[] = void 0;
-}
diff --git a/gae/frontend/src/app/model/schedule.ts b/gae/frontend/src/app/model/schedule.ts
deleted file mode 100644
index 9115a97..0000000
--- a/gae/frontend/src/app/model/schedule.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export class Schedule {
- name: string = void 0;
- schedule_type: string = void 0;
-
- // device image information
- build_storage_type: number = void 0;
- manifest_branch: string = void 0;
- build_target: string = void 0;
- device_pab_account_id: string = void 0;
- require_signed_device_build: boolean = void 0;
- has_bootloader_img: boolean = void 0;
- has_radio_img: boolean = void 0;
-
- // GSI information
- gsi_storage_type: number = void 0;
- gsi_branch: string = void 0;
- gsi_build_target: string = void 0;
- gsi_pab_account_id: string = void 0;
- gsi_vendor_version: string = void 0;
-
- // test suite information
- test_storage_type: number = void 0;
- test_branch: string = void 0;
- test_build_target: string = void 0;
- test_pab_account_id: string = void 0;
-
- test_name: string = void 0;
- period: number = void 0;
- schedule: string = void 0;
- priority: string = void 0;
- device: string[] = void 0;
- shards: number = void 0;
- param: string[] = void 0;
- retry_count: number = void 0;
-
- required_host_equipment: string[] = void 0;
- required_device_equipment: string[] = void 0;
-
- report_bucket: string[] = void 0;
- report_spreadsheet_id: string[] = void 0;
- report_persistent_url: string[] = void 0;
- report_reference_url: string[] = void 0;
-
- image_package_repo_base: string = void 0;
- timestamp = void 0;
- owner: string[] = void 0;
-
- error_count: number = void 0;
- suspended: boolean = void 0;
- urlsafe_key: string = void 0;
-}
-
-export interface ScheduleSuspendResponseWrapper {
- schedules: ScheduleSuspendResponse[];
-}
-
-export interface ScheduleSuspendResponse {
- urlsafe_key: string;
- suspend: boolean;
-}
diff --git a/gae/frontend/src/app/model/schedule_wrapper.ts b/gae/frontend/src/app/model/schedule_wrapper.ts
deleted file mode 100644
index 2dae800..0000000
--- a/gae/frontend/src/app/model/schedule_wrapper.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Schedule} from './schedule';
-
-export interface ScheduleWrapper {
- schedules: Schedule[];
- has_next: boolean;
-}
diff --git a/gae/frontend/src/app/model/tslint.json b/gae/frontend/src/app/model/tslint.json
deleted file mode 100644
index eb9bcd8..0000000
--- a/gae/frontend/src/app/model/tslint.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "../../tslint.json",
- "rules": {
- "variable-name": [
- true,
- "allow-snake-case"
- ]
- }
-}
diff --git a/gae/frontend/src/app/shared/dict.pipe.ts b/gae/frontend/src/app/shared/dict.pipe.ts
deleted file mode 100644
index 44f5933..0000000
--- a/gae/frontend/src/app/shared/dict.pipe.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Pipe, PipeTransform} from '@angular/core';
-
-@Pipe({name: 'dict'})
-export class DictPipe implements PipeTransform {
- transform(value: Object): any {
- const dict = [];
- for (const key in value) {
- if (value.hasOwnProperty(key)) {
- dict.push({key: key, value: value[key]});
- }
- }
- return dict;
- }
-}
diff --git a/gae/frontend/src/app/shared/filter/filter.component.html b/gae/frontend/src/app/shared/filter/filter.component.html
deleted file mode 100644
index 7381359..0000000
--- a/gae/frontend/src/app/shared/filter/filter.component.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<div fxLayout="column" id="filter-wrapper">
- <mat-expansion-panel id="expansion-panel" (opened)="panelOpenState = true" (closed)="panelOpenState = false" [ngStyle]="{'padding-bottom': (panelOpenState) ? '20px' : '0' }">
- <mat-expansion-panel-header>
- <mat-panel-title>
- Filter
- </mat-panel-title>
- <mat-panel-description>
- {{ panelOpenState ? "" : appliedFilters.length + " filters are applied." }}
- </mat-panel-description>
- </mat-expansion-panel-header>
- <mat-form-field>
- <mat-select placeholder="Key" [(value)]="currentFilter.key">
- <mat-option *ngFor="let key of selectorList" [value]="key">
- {{ key }}
- </mat-option>
- </mat-select>
- </mat-form-field>
- <mat-form-field>
- <mat-select [(value)]="currentFilter.method">
- <mat-option *ngFor="let method of filterMethods" [value]="method.value">
- {{ method.text }}
- </mat-option>
- </mat-select>
- </mat-form-field>
- <mat-form-field>
- <input matInput [(ngModel)]="currentFilter.value">
- </mat-form-field>
- <button mat-icon-button (click)="addFilter()" [disabled]="!currentFilter.key || !currentFilter.method || !currentFilter.value">
- <mat-icon>done</mat-icon>
- </button>
- <button mat-icon-button (click)="clearCurrentFilter()">
- <mat-icon>clear</mat-icon>
- </button>
- <mat-chip-list>
- <mat-chip *ngFor="let filter of applyingFilters" [removable]="true" (removed)="removed(filter)">
- {{ filter.key }} {{ getSign(filter) }} {{ filter.value }}
- <mat-icon matChipRemove>cancel</mat-icon>
- </mat-chip>
- </mat-chip-list>
- <div fxLayout="row" id="row_buttons">
- <button mat-stroked-button (click)="onApplyClicked()" [disabled]="!applyingFilterChanged">
- <span>Apply</span>
- </button>
- <button mat-stroked-button (click)="onCancelChangesClicked()" [disabled]="!applyingFilterChanged">
- <span>Cancel Changes</span>
- </button>
- <button mat-stroked-button (click)="onClearAllClicked()" [disabled]="appliedFilters.length == 0">
- <span>Clear All</span>
- </button>
- </div>
- </mat-expansion-panel>
-</div>
diff --git a/gae/frontend/src/app/shared/filter/filter.component.scss b/gae/frontend/src/app/shared/filter/filter.component.scss
deleted file mode 100644
index 88ae569..0000000
--- a/gae/frontend/src/app/shared/filter/filter.component.scss
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#filter-wrapper {
- position: relative;
-
- mat-form-field {
- margin-right: 20px;
- }
-}
-
-#row_buttons {
- float: right;
-}
-
-.mat-stroked-button {
- min-width: 80px;
- min-height: 15px;
- padding-left: 15px;
- padding-right: 15px;
- font-size: 12px;
- margin-right: 15px;
-}
diff --git a/gae/frontend/src/app/shared/filter/filter.component.ts b/gae/frontend/src/app/shared/filter/filter.component.ts
deleted file mode 100644
index 0ce66fe..0000000
--- a/gae/frontend/src/app/shared/filter/filter.component.ts
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { FilterItem } from '../../model/filter_item';
-import { FilterCondition } from '../../model/filter_condition';
-
-@Component({
- selector: 'app-filter',
- templateUrl: './filter.component.html',
- styleUrls: ['./filter.component.scss']
-})
-export class FilterComponent implements OnInit {
- currentFilter: FilterItem;
- applyingFilters: FilterItem[] = [];
- applyingFilterChanged = false;
- appliedFilters: FilterItem[] = [];
- selectorList: string[];
-
- filterMethods = [
- {value: FilterCondition.EqualTo, text: 'is equal to', sign: '='},
- {value: FilterCondition.LessThan, text: 'is less than', sign: '<'},
- {value: FilterCondition.GreaterThan, text: 'is greater than', sign: '>'},
- {value: FilterCondition.LessThanOrEqualTo, text: 'is less than or equal to', sign: '<='},
- {value: FilterCondition.GreaterThanOrEqualTo, text: 'is greater than or equal to', sign: '>='},
- {value: FilterCondition.NotEqualTo, text: 'is not equal to', sign: '!='},
- {value: FilterCondition.Has, text: 'has', sign: 'has'},
- ];
-
- @Output() applyFilters = new EventEmitter();
- @Input() disabled: boolean;
-
- panelOpenState = false;
-
- ngOnInit(): void {
- this.currentFilter = new FilterItem();
- this.currentFilter.value = '';
- }
-
- /** Sets a filter key list with the given class. */
- setSelectorList(typeOfClass: any) {
- const instance = new typeOfClass();
- this.selectorList = Object.getOwnPropertyNames(instance);
- }
-
- /** Adds the current filter to the list of filters to be applied. */
- addFilter() {
- this.applyingFilters.push(this.currentFilter);
- this.currentFilter = new FilterItem();
- this.currentFilter.value = '';
- this.applyingFilterChanged = true;
- }
-
- /** Clears the current filter. */
- clearCurrentFilter() {
- this.currentFilter.key = undefined;
- this.currentFilter.method = undefined;
- this.currentFilter.value = '';
- }
-
- /** Removes the selected filter from the list of filters to be applied. */
- removed(filter: FilterItem) {
- const index = this.applyingFilters.indexOf(filter);
- if (index >= 0) {
- this.applyingFilters.splice(index, 1);
- this.applyingFilterChanged = true;
- }
- }
-
- /** Gets a filter sign with method value. */
- getSign(filter: FilterItem) {
- return this.filterMethods.find((x) => x.value === filter.method).sign;
- }
-
- /** Applies the list of filters. */
- onApplyClicked() {
- this.applyFilters.emit(this.applyingFilters);
- this.appliedFilters = this.applyingFilters.slice();
- this.applyingFilterChanged = false;
- }
-
- /** Cancels the current changes and roll back to the last applied filters. */
- onCancelChangesClicked() {
- this.applyingFilters = this.appliedFilters.slice();
- this.applyingFilterChanged = false;
- }
-
- /** Reset all filters. */
- onClearAllClicked() {
- this.applyingFilters = [];
- this.appliedFilters = [];
- this.applyFilters.emit(this.appliedFilters);
- this.applyingFilterChanged = false;
- }
-}
diff --git a/gae/frontend/src/app/shared/navbar/_navbar-theme.scss b/gae/frontend/src/app/shared/navbar/_navbar-theme.scss
deleted file mode 100644
index bba0989..0000000
--- a/gae/frontend/src/app/shared/navbar/_navbar-theme.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-@mixin nav-bar-theme($theme) {
- $primary: map-get($theme, primary);
- $accent: map-get($theme, accent);
- $warn: map-get($theme, warn);
- $background: map-get($theme, background);
- $foreground: map-get($theme, foreground);
-
- mat-toolbar.main-toolbar {
- .mat-list-item {
- color: mat-color($primary, '600-contrast') !important;
- }
- }
-}
diff --git a/gae/frontend/src/app/shared/navbar/navbar.component.html b/gae/frontend/src/app/shared/navbar/navbar.component.html
deleted file mode 100644
index 7719d56..0000000
--- a/gae/frontend/src/app/shared/navbar/navbar.component.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<mat-toolbar class="mat-elevation-z6 main-toolbar" color="primary">
- <mat-nav-list>
- <a mat-list-item *ngFor="let menu of (menus | dict)" [routerLink]="menu.value">{{ menu.key }}</a>
- </mat-nav-list>
- <span class="flex-spacer"></span>
-</mat-toolbar>
diff --git a/gae/frontend/src/app/shared/navbar/navbar.component.scss b/gae/frontend/src/app/shared/navbar/navbar.component.scss
deleted file mode 100644
index 5b6dc86..0000000
--- a/gae/frontend/src/app/shared/navbar/navbar.component.scss
+++ /dev/null
@@ -1,10 +0,0 @@
-mat-toolbar {
- .mat-list-item {
- font-family: 'Google Sans', Roboto, sans-serif;
- text-transform: capitalize;
- }
-}
-
-.mat-list-item {
- float: left;
-}
diff --git a/gae/frontend/src/app/shared/navbar/navbar.component.ts b/gae/frontend/src/app/shared/navbar/navbar.component.ts
deleted file mode 100644
index 3efe93f..0000000
--- a/gae/frontend/src/app/shared/navbar/navbar.component.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { Component } from '@angular/core';
-
-import { MENUS } from '../../menu/menu-items';
-
-@Component({
- selector: 'app-nav-bar',
- templateUrl: './navbar.component.html',
- styleUrls: ['./navbar.component.scss']
-})
-export class NavBarComponent {
- get menus() {
- return MENUS;
- }
-}
diff --git a/gae/frontend/src/app/shared/navbar/navbar.ts b/gae/frontend/src/app/shared/navbar/navbar.ts
deleted file mode 100644
index 805dcc5..0000000
--- a/gae/frontend/src/app/shared/navbar/navbar.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-// Angular modules.
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-import { RouterModule } from '@angular/router';
-
-// Angular Material modules.
-import { MatButtonModule } from '@angular/material/button';
-import { MatListModule } from '@angular/material/list';
-import { MatToolbarModule } from '@angular/material/toolbar';
-
-// User modules.
-import { DictPipe } from '../dict.pipe';
-import { NavBarComponent } from './navbar.component';
-
-@NgModule({
- declarations: [
- DictPipe,
- NavBarComponent,
- ],
- imports: [
- BrowserModule,
- MatButtonModule,
- MatToolbarModule,
- MatListModule,
- RouterModule,
- ],
- exports: [
- NavBarComponent,
- ],
- providers: [],
-})
-export class NavModule { }
diff --git a/gae/frontend/src/app/shared/servicebase.ts b/gae/frontend/src/app/shared/servicebase.ts
deleted file mode 100644
index 9eaecf8..0000000
--- a/gae/frontend/src/app/shared/servicebase.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { HttpClient, HttpErrorResponse, HttpParams, HttpResponse } from '@angular/common/http';
-import { Observable, throwError } from 'rxjs';
-
-export class ServiceBase {
- url: string;
- protected constructor(public httpClient: HttpClient) {
- }
- protected handleError(error: HttpErrorResponse) {
- if (error.error instanceof ErrorEvent) {
- // A client-side or network error occurred. Handle it accordingly.
- console.error('An error occurred:', error.error.message);
- } else {
- // The backend returned an unsuccessful response code.
- // The response body may contain clues as to what went wrong,
- console.error(
- `Backend returned code ${error.status}, ` +
- `body was: ${error.error}`);
- }
- // return an observable with a user-facing error message
- return throwError(error);
- }
- public getCount(filterInfo: string): Observable<number> {
- const url = this.url + 'count';
- return this.httpClient.post<number>(url, {filter: filterInfo});
- }
-}
diff --git a/gae/frontend/src/app/shared/vtslab_status.ts b/gae/frontend/src/app/shared/vtslab_status.ts
deleted file mode 100644
index 2836f97..0000000
--- a/gae/frontend/src/app/shared/vtslab_status.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-export enum JobStatus {
- Ready = 0,
- Leased,
- Complete,
- Infra_err,
- Expired,
- Bootup_err,
-}
-
-export enum DeviceStatus {
- Unknown = 0,
- Fastboot,
- Online,
- Ready,
- Use,
- Error,
- No_response,
-}
-
-export enum SchedulingStatus {
- Free = 0,
- Reserved,
- Use,
-}
-
-/**
- * bit 0-1 : version related test type
- * 00 - Unknown
- * 01 - ToT
- * 10 - OTA
- * bit 2 : device signed build
- * bit 3-4 : reserved for gerrit related test type
- * 01 - pre-submit
- * bit 5 : manually created test job
- */
-export enum TestType {
- Unknown = 0,
- ToT = 1,
- OTA = 1 << 1,
- Signed = 1 << 2,
- Presubmit = 1 << 3,
- Manual = 1 << 5,
-}
diff --git a/gae/frontend/src/browserslist b/gae/frontend/src/browserslist
deleted file mode 100644
index 3206b4e..0000000
--- a/gae/frontend/src/browserslist
+++ /dev/null
@@ -1,5 +0,0 @@
-# For autoprefixer to adjust CSS to support the below specified browsers
-> 0.5%
-last 2 versions
-Firefox ESR
-not dead
diff --git a/gae/frontend/src/environments/environment.prod.ts b/gae/frontend/src/environments/environment.prod.ts
deleted file mode 100644
index 8b051e6..0000000
--- a/gae/frontend/src/environments/environment.prod.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const environment = {
- production: true,
- baseURL: '/_ah/api',
-};
diff --git a/gae/frontend/src/environments/environment.ts b/gae/frontend/src/environments/environment.ts
deleted file mode 100644
index 387543e..0000000
--- a/gae/frontend/src/environments/environment.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const environment = {
- production: false,
- baseURL: 'http://localhost:8080/_ah/api',
-};
diff --git a/gae/frontend/src/favicon.ico b/gae/frontend/src/favicon.ico
deleted file mode 100644
index 8081c7c..0000000
--- a/gae/frontend/src/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/gae/frontend/src/index.html b/gae/frontend/src/index.html
deleted file mode 100644
index 3234be2..0000000
--- a/gae/frontend/src/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<html lang="en">
-<head>
- <meta charset="utf-8">
- <title>VTSLab Scheduler</title>
- <base href="/">
-
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <link rel="icon" type="image/x-icon" href="favicon.ico">
- <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
- <link href="https://fonts.googleapis.com/css?family=Google+Sans" rel="stylesheet">
-</head>
-<body>
- <app-root>Loading...</app-root>
-</body>
-</html>
diff --git a/gae/frontend/src/karma.conf.js b/gae/frontend/src/karma.conf.js
deleted file mode 100644
index b6e0042..0000000
--- a/gae/frontend/src/karma.conf.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Karma configuration file, see link for more information
-// https://karma-runner.github.io/1.0/config/configuration-file.html
-
-module.exports = function (config) {
- config.set({
- basePath: '',
- frameworks: ['jasmine', '@angular-devkit/build-angular'],
- plugins: [
- require('karma-jasmine'),
- require('karma-chrome-launcher'),
- require('karma-jasmine-html-reporter'),
- require('karma-coverage-istanbul-reporter'),
- require('@angular-devkit/build-angular/plugins/karma')
- ],
- client: {
- clearContext: false // leave Jasmine Spec Runner output visible in browser
- },
- coverageIstanbulReporter: {
- dir: require('path').join(__dirname, '../coverage'),
- reports: ['html', 'lcovonly'],
- fixWebpackSourcePaths: true
- },
- reporters: ['progress', 'kjhtml'],
- port: 9876,
- colors: true,
- logLevel: config.LOG_INFO,
- autoWatch: true,
- browsers: ['Chrome'],
- singleRun: false
- });
-}; \ No newline at end of file
diff --git a/gae/frontend/src/main.ts b/gae/frontend/src/main.ts
deleted file mode 100644
index 91ec6da..0000000
--- a/gae/frontend/src/main.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { enableProdMode } from '@angular/core';
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-
-import { AppModule } from './app/app.module';
-import { environment } from './environments/environment';
-
-if (environment.production) {
- enableProdMode();
-}
-
-platformBrowserDynamic().bootstrapModule(AppModule)
- .catch(err => console.log(err));
diff --git a/gae/frontend/src/polyfills.ts b/gae/frontend/src/polyfills.ts
deleted file mode 100644
index 25a0787..0000000
--- a/gae/frontend/src/polyfills.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-// Evergreen browsers require these.
-import 'core-js/es7/reflect';
-
-// Zone JS is required by default for Angular itself.
-import 'zone.js/dist/zone';
diff --git a/gae/frontend/src/styles.scss b/gae/frontend/src/styles.scss
deleted file mode 100644
index 574f294..0000000
--- a/gae/frontend/src/styles.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-@import '~@angular/material/theming';
-@import 'styles/app-theme';
-
-body {
- margin: 0;
- font-family: Roboto, sans-serif;
-}
-
-.entity-filter {
- margin: 20px 20px 0 20px;
-
- filter {
- width: 100%;
- }
-}
-
-.statistics-table {
- margin: 10px 20px 20px 20px;
-
- table {
- width: 100%;
- }
-}
-
-.mat-card {
- margin: 20px;
-}
-
-.entity-table {
- margin: 10px 20px 20px 20px;
-
- table {
- width: 100%;
- }
-}
-
-.loading-spinner {
- display: flex;
- align-items: center;
- justify-content: center;
- top: 0;
- left: 0;
- bottom: 0;
- right: 0;
- position: fixed;
-}
-
-.div-expandable {
- padding: 10px 20px 30px 20px;
-
- button {
- margin-right: 20px;
- }
-}
diff --git a/gae/frontend/src/styles/_app-theme.scss b/gae/frontend/src/styles/_app-theme.scss
deleted file mode 100644
index 6c18f48..0000000
--- a/gae/frontend/src/styles/_app-theme.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@import '~@angular/material/theming';
-@import 'apply-theme';
-@import 'blue-theme';
-
-@include mat-core();
-
-$main-theme: $blue-theme;
-
-$primary: mat-palette($main-theme, 600, 100, 900);
-$accent: mat-palette($main-theme, A200, A100, A400);
-$app-theme: mat-light-theme($primary, $accent);
-
-@include angular-material-theme($app-theme);
-@include apply-theme($app-theme);
diff --git a/gae/frontend/src/styles/_apply-theme.scss b/gae/frontend/src/styles/_apply-theme.scss
deleted file mode 100644
index fd5173f..0000000
--- a/gae/frontend/src/styles/_apply-theme.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-@import '../app/shared/navbar/navbar-theme';
-
-@mixin apply-theme($theme) {
- @include nav-bar-theme($theme);
-}
diff --git a/gae/frontend/src/styles/_blue-theme.scss b/gae/frontend/src/styles/_blue-theme.scss
deleted file mode 100644
index 53fd744..0000000
--- a/gae/frontend/src/styles/_blue-theme.scss
+++ /dev/null
@@ -1,34 +0,0 @@
-@import '~@angular/material/theming';
-
-$blue-theme: (
- 50: #e8f0fe,
- 100: #d2e3fc,
- 200: #a1c2fa,
- 300: #7baaf7,
- 400: #5e97f6,
- 500: #4285f4,
- 600: #1a73e8,
- 700: #1967d2,
- 800: #185abc,
- 900: #174ea6,
- A100: #82b1ff,
- A200: #448aff,
- A400: #2979ff,
- A700: #2962ff,
- contrast: (
- 50: #1a73e8,
- 100: #1a73e8,
- 200: $black-87-opacity,
- 300: $black-87-opacity,
- 400: $black-87-opacity,
- 500: white,
- 600: white,
- 700: white,
- 800: white,
- 900: white,
- A100: $black-87-opacity,
- A200: white,
- A400: white,
- A700: white,
- )
-);
diff --git a/gae/frontend/src/test.ts b/gae/frontend/src/test.ts
deleted file mode 100644
index 1631789..0000000
--- a/gae/frontend/src/test.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-
-import 'zone.js/dist/zone-testing';
-import { getTestBed } from '@angular/core/testing';
-import {
- BrowserDynamicTestingModule,
- platformBrowserDynamicTesting
-} from '@angular/platform-browser-dynamic/testing';
-
-declare const require: any;
-
-// First, initialize the Angular testing environment.
-getTestBed().initTestEnvironment(
- BrowserDynamicTestingModule,
- platformBrowserDynamicTesting()
-);
-// Then we find all the tests.
-const context = require.context('./', true, /\.spec\.ts$/);
-// And load the modules.
-context.keys().map(context);
diff --git a/gae/frontend/src/tsconfig.app.json b/gae/frontend/src/tsconfig.app.json
deleted file mode 100644
index 722c370..0000000
--- a/gae/frontend/src/tsconfig.app.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/app",
- "module": "es2015",
- "types": []
- },
- "exclude": [
- "src/test.ts",
- "**/*.spec.ts"
- ]
-}
diff --git a/gae/frontend/src/tsconfig.spec.json b/gae/frontend/src/tsconfig.spec.json
deleted file mode 100644
index 8f7cede..0000000
--- a/gae/frontend/src/tsconfig.spec.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "extends": "../tsconfig.json",
- "compilerOptions": {
- "outDir": "../out-tsc/spec",
- "module": "commonjs",
- "types": [
- "jasmine",
- "node"
- ]
- },
- "files": [
- "test.ts",
- "polyfills.ts"
- ],
- "include": [
- "**/*.spec.ts",
- "**/*.d.ts"
- ]
-}
diff --git a/gae/frontend/src/tslint.json b/gae/frontend/src/tslint.json
deleted file mode 100644
index 52e2c1a..0000000
--- a/gae/frontend/src/tslint.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "../tslint.json",
- "rules": {
- "directive-selector": [
- true,
- "attribute",
- "app",
- "camelCase"
- ],
- "component-selector": [
- true,
- "element",
- "app",
- "kebab-case"
- ]
- }
-}