summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJongmok Hong <jongmok@google.com>2018-10-02 08:54:47 +0900
committerJongmok Hong <jongmok@google.com>2018-10-12 08:29:33 +0900
commit6cbe628b7c378aa6fd7b59dc06505adecb6b1af2 (patch)
tree2ead007a8bf3d8cd1406a0a755bdc67d58cd72f6
parent29ce9f1172f1debf42ac2b74f96b0483bd88e679 (diff)
downloadtest_serving-6cbe628b7c378aa6fd7b59dc06505adecb6b1af2.tar.gz
Add a Show Details button to list all properties.
Test: go/vtslab-schedule-dev/redirect/20181011t154848-dot-vtslab-schedule-dev Bug: 117531288 Change-Id: If2ae84baf01d64d83e5918e5bd0dfdff1ddc31c8
-rw-r--r--gae/frontend/src/app/app.component.html17
-rw-r--r--gae/frontend/src/app/app.component.scss28
-rw-r--r--gae/frontend/src/app/app.component.ts37
-rw-r--r--gae/frontend/src/app/app.module.ts6
-rw-r--r--gae/frontend/src/app/appservice.ts37
-rw-r--r--gae/frontend/src/app/menu/build/build.component.ts6
-rw-r--r--gae/frontend/src/app/menu/dashboard/dashboard.component.ts6
-rw-r--r--gae/frontend/src/app/menu/device/device.component.ts6
-rw-r--r--gae/frontend/src/app/menu/job/job.component.html3
-rw-r--r--gae/frontend/src/app/menu/job/job.component.scss17
-rw-r--r--gae/frontend/src/app/menu/job/job.component.ts6
-rw-r--r--gae/frontend/src/app/menu/lab/lab.component.ts6
-rw-r--r--gae/frontend/src/app/menu/menu_base.ts10
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.html3
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.scss4
-rw-r--r--gae/frontend/src/app/menu/schedule/schedule.component.ts6
-rw-r--r--gae/frontend/src/styles.scss6
17 files changed, 185 insertions, 19 deletions
diff --git a/gae/frontend/src/app/app.component.html b/gae/frontend/src/app/app.component.html
index a4df15a..8f21391 100644
--- a/gae/frontend/src/app/app.component.html
+++ b/gae/frontend/src/app/app.component.html
@@ -17,4 +17,19 @@
<app-nav-bar id="nav-bar"></app-nav-bar>
</div>
</header>
-<router-outlet id="router-outlet"></router-outlet>
+<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
index e69de29..d818d0e 100644
--- a/gae/frontend/src/app/app.component.scss
+++ b/gae/frontend/src/app/app.component.scss
@@ -0,0 +1,28 @@
+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.ts b/gae/frontend/src/app/app.component.ts
index 9e83762..68b7e6d 100644
--- a/gae/frontend/src/app/app.component.ts
+++ b/gae/frontend/src/app/app.component.ts
@@ -16,10 +16,47 @@
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) => {
+ 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
index c70fd52..ec940db 100644
--- a/gae/frontend/src/app/app.module.ts
+++ b/gae/frontend/src/app/app.module.ts
@@ -29,10 +29,12 @@ 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';
@@ -77,10 +79,12 @@ const appRoutes: Routes = [
MatFormFieldModule,
MatIconModule,
MatInputModule,
+ MatListModule,
MatPaginatorModule,
MatProgressSpinnerModule,
MatSnackBarModule,
MatSelectModule,
+ MatSidenavModule,
MatSortModule,
MatTableModule,
MatTabsModule,
@@ -93,10 +97,12 @@ const appRoutes: Routes = [
MatFormFieldModule,
MatIconModule,
MatInputModule,
+ MatListModule,
MatPaginatorModule,
MatProgressSpinnerModule,
MatSnackBarModule,
MatSelectModule,
+ MatSidenavModule,
MatSortModule,
MatTableModule,
MatTabsModule,
diff --git a/gae/frontend/src/app/appservice.ts b/gae/frontend/src/app/appservice.ts
new file mode 100644
index 0000000..6b303f0
--- /dev/null
+++ b/gae/frontend/src/app/appservice.ts
@@ -0,0 +1,37 @@
+/**
+ * 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.ts b/gae/frontend/src/app/menu/build/build.component.ts
index e149f87..e4c7325 100644
--- a/gae/frontend/src/app/menu/build/build.component.ts
+++ b/gae/frontend/src/app/menu/build/build.component.ts
@@ -16,6 +16,7 @@
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';
@@ -46,8 +47,9 @@ export class BuildComponent extends MenuBaseClass implements OnInit {
@ViewChild(FilterComponent) filterComponent: FilterComponent;
constructor(private buildService: BuildService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
ngOnInit(): void {
diff --git a/gae/frontend/src/app/menu/dashboard/dashboard.component.ts b/gae/frontend/src/app/menu/dashboard/dashboard.component.ts
index 79d85a0..0157ea8 100644
--- a/gae/frontend/src/app/menu/dashboard/dashboard.component.ts
+++ b/gae/frontend/src/app/menu/dashboard/dashboard.component.ts
@@ -16,6 +16,7 @@
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";
@@ -33,8 +34,9 @@ export class DashboardComponent extends MenuBaseClass implements OnInit {
constructor(private buildService: BuildService,
private scheduleService: ScheduleService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
ngOnInit(): void {
diff --git a/gae/frontend/src/app/menu/device/device.component.ts b/gae/frontend/src/app/menu/device/device.component.ts
index 31407d5..2fc9a72 100644
--- a/gae/frontend/src/app/menu/device/device.component.ts
+++ b/gae/frontend/src/app/menu/device/device.component.ts
@@ -16,6 +16,7 @@
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';
@@ -53,8 +54,9 @@ export class DeviceComponent extends MenuBaseClass implements OnInit {
@ViewChild(FilterComponent) filterComponent: FilterComponent;
constructor(private deviceService: DeviceService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
ngOnInit(): void {
diff --git a/gae/frontend/src/app/menu/job/job.component.html b/gae/frontend/src/app/menu/job/job.component.html
index 5151783..634402d 100644
--- a/gae/frontend/src/app/menu/job/job.component.html
+++ b/gae/frontend/src/app/menu/job/job.component.html
@@ -182,6 +182,9 @@
<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">
diff --git a/gae/frontend/src/app/menu/job/job.component.scss b/gae/frontend/src/app/menu/job/job.component.scss
index 165de43..c8aee00 100644
--- a/gae/frontend/src/app/menu/job/job.component.scss
+++ b/gae/frontend/src/app/menu/job/job.component.scss
@@ -5,3 +5,20 @@
.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
index 383ae19..4375581 100644
--- a/gae/frontend/src/app/menu/job/job.component.ts
+++ b/gae/frontend/src/app/menu/job/job.component.ts
@@ -17,6 +17,7 @@ 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';
@@ -84,8 +85,9 @@ export class JobComponent extends MenuBaseClass implements OnInit {
sortDirection = '';
constructor(private jobService: JobService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
ngOnInit(): void {
diff --git a/gae/frontend/src/app/menu/lab/lab.component.ts b/gae/frontend/src/app/menu/lab/lab.component.ts
index 83fe3a1..bb7543b 100644
--- a/gae/frontend/src/app/menu/lab/lab.component.ts
+++ b/gae/frontend/src/app/menu/lab/lab.component.ts
@@ -16,6 +16,7 @@
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';
@@ -48,8 +49,9 @@ export class LabComponent extends MenuBaseClass implements OnInit {
labPageIndex = 0;
constructor(private labService: LabService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
labDataSource = new MatTableDataSource<Lab>();
diff --git a/gae/frontend/src/app/menu/menu_base.ts b/gae/frontend/src/app/menu/menu_base.ts
index 316923e..9282fe5 100644
--- a/gae/frontend/src/app/menu/menu_base.ts
+++ b/gae/frontend/src/app/menu/menu_base.ts
@@ -17,6 +17,7 @@
/** 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';
@@ -29,7 +30,9 @@ export abstract class MenuBaseClass {
pageSize = 100;
pageIndex = 0;
- protected constructor(public snackBar: MatSnackBar) {
+ protected constructor(private appService: AppService,
+ public snackBar: MatSnackBar) {
+ this.appService.closeSideNav();
this.snackBar.dismiss();
}
@@ -58,4 +61,9 @@ export abstract class MenuBaseClass {
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.component.html b/gae/frontend/src/app/menu/schedule/schedule.component.html
index c567639..e260325 100644
--- a/gae/frontend/src/app/menu/schedule/schedule.component.html
+++ b/gae/frontend/src/app/menu/schedule/schedule.component.html
@@ -102,6 +102,9 @@
<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">
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.scss b/gae/frontend/src/app/menu/schedule/schedule.component.scss
index a1e3e98..c8aee00 100644
--- a/gae/frontend/src/app/menu/schedule/schedule.component.scss
+++ b/gae/frontend/src/app/menu/schedule/schedule.component.scss
@@ -22,7 +22,3 @@
.element-row.expanded {
border-bottom-color: transparent;
}
-
-.div-expandable {
- padding: 10px 20px 30px 20px;
-}
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.ts b/gae/frontend/src/app/menu/schedule/schedule.component.ts
index 57ebd7b..6c72343 100644
--- a/gae/frontend/src/app/menu/schedule/schedule.component.ts
+++ b/gae/frontend/src/app/menu/schedule/schedule.component.ts
@@ -17,6 +17,7 @@ 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';
@@ -59,8 +60,9 @@ export class ScheduleComponent extends MenuBaseClass implements OnInit {
@ViewChild(FilterComponent) filterComponent: FilterComponent;
constructor(private scheduleService: ScheduleService,
- public snackBar: MatSnackBar) {
- super(snackBar);
+ appService: AppService,
+ snackBar: MatSnackBar) {
+ super(appService, snackBar);
}
ngOnInit(): void {
diff --git a/gae/frontend/src/styles.scss b/gae/frontend/src/styles.scss
index 7505757..574f294 100644
--- a/gae/frontend/src/styles.scss
+++ b/gae/frontend/src/styles.scss
@@ -46,5 +46,9 @@ body {
}
.div-expandable {
- padding: 10px;
+ padding: 10px 20px 30px 20px;
+
+ button {
+ margin-right: 20px;
+ }
}