Merge "Clear a previous entity before showing an entity."
diff --git a/gae/frontend/src/app/menu/menu_base.ts b/gae/frontend/src/app/menu/menu_base.ts
index 9282fe5..4d68f03 100644
--- a/gae/frontend/src/app/menu/menu_base.ts
+++ b/gae/frontend/src/app/menu/menu_base.ts
@@ -56,6 +56,16 @@
       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;
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.html b/gae/frontend/src/app/menu/schedule/schedule.component.html
index e260325..910d45b 100644
--- a/gae/frontend/src/app/menu/schedule/schedule.component.html
+++ b/gae/frontend/src/app/menu/schedule/schedule.component.html
@@ -77,6 +77,15 @@
       <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>
diff --git a/gae/frontend/src/app/menu/schedule/schedule.component.ts b/gae/frontend/src/app/menu/schedule/schedule.component.ts
index 6c72343..5c1740e 100644
--- a/gae/frontend/src/app/menu/schedule/schedule.component.ts
+++ b/gae/frontend/src/app/menu/schedule/schedule.component.ts
@@ -51,6 +51,7 @@
     'test_branch',
     'test_build_target',
     'period',
+    'status',
     'timestamp',
   ];
   dataSource = new MatTableDataSource<Schedule>();
diff --git a/gae/frontend/src/app/model/schedule.ts b/gae/frontend/src/app/model/schedule.ts
index 5046f2f..9115a97 100644
--- a/gae/frontend/src/app/model/schedule.ts
+++ b/gae/frontend/src/app/model/schedule.ts
@@ -60,6 +60,7 @@
   timestamp = void 0;
   owner: string[] = void 0;
 
+  error_count: number = void 0;
   suspended: boolean = void 0;
   urlsafe_key: string = void 0;
 }
diff --git a/gae/webapp/src/proto/model.py b/gae/webapp/src/proto/model.py
index 4541e68..1b24154 100644
--- a/gae/webapp/src/proto/model.py
+++ b/gae/webapp/src/proto/model.py
@@ -115,7 +115,7 @@
 
 class ScheduleInfoMessage(messages.Message):
     """A message for representing an individual schedule entry."""
-    # Next ID = 38
+    # Next ID = 39
     # schedule name for green build schedule, optional.
     name = messages.StringField(16)
     schedule_type = messages.StringField(19)
@@ -165,6 +165,7 @@
 
     suspended = messages.BooleanField(36)
     urlsafe_key = messages.StringField(37)
+    error_count = messages.IntegerField(38)
 
 
 class LabModel(ndb.Model):