| <div id="job-query-form" class="px-2 my-3"> |
| <p><b>Fetch job by ID:</b></p> |
| <div class="flex flex-row items-center gap-2"> |
| <div class="w-40 input-box-container without-border"> |
| <mat-form-field class="full-width"> |
| <mat-label>Enter Job ID:</mat-label> |
| <input id="job-query-input" matInput [formControl]="jobQuery" /> |
| <mat-error *ngIf="this.jobQuery.errors"> |
| ID must be a non-negative integer. |
| </mat-error> |
| </mat-form-field> |
| </div> |
| <button id="job-query-button" mat-raised-button color="primary" |
| [disabled]="!this.jobQuery.value || this.jobQuery.errors" (click)="fetchJobDetails()"> |
| Go |
| </button> |
| |
| <button id="dut-refresh-button" matTooltip="Refresh" mat-icon-button [disabled]="isJobQueryEmpty()" |
| (click)="fetchJobDetails()"> |
| <mat-icon>refresh</mat-icon> |
| </button> |
| </div> |
| </div> |
| |
| <div id="job-detail-table-wrapper" class="detail-wrapper"> |
| <div id="loading-overlay" *ngIf="isJobInfoTableEmpty()"></div> |
| <div id="job-not-found-label" *ngIf="isJobInfoTableEmpty()"> |
| <p>No job data fetched.</p> |
| </div> |
| <app-keyval-table #job_info_table></app-keyval-table> |
| <mat-accordion> |
| <mat-expansion-panel> |
| <mat-expansion-panel-header> |
| <mat-panel-title> |
| <b>Server control file</b> |
| </mat-panel-title> |
| </mat-expansion-panel-header> |
| <p id="control-file-view">{{ serverControlFile }}</p> |
| </mat-expansion-panel> |
| </mat-accordion> |
| <mat-divider></mat-divider> |
| <mat-accordion> |
| <mat-expansion-panel> |
| <mat-expansion-panel-header> |
| <mat-panel-title> |
| <b>Job History</b> |
| </mat-panel-title> |
| </mat-expansion-panel-header> |
| <table id="job-execution-history-table" class="expansion-panel-content" mat-table [dataSource]="jobHistoryTable"> |
| <ng-container matColumnDef="job_id"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">ID</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ jobHistoryRow.getJobId() }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="name"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">Name</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ jobHistoryRow.getName() }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="dut"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">DUT</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ jobHistoryRow.getDut() }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="start_time"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">Start</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ normalizeTimestamp(jobHistoryRow.getStartTimeUtc()) }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="end_time"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">End</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ normalizeTimestamp(jobHistoryRow.getEndTimeUtc()) }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="time_used"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div class="text-base">Time Used</div> |
| </th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ jobHistoryRow.getUsedTime() | msecFormatter }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="status"> |
| <th mat-header-cell *matHeaderCellDef>Status</th> |
| <td mat-cell *matCellDef="let jobHistoryRow"> |
| {{ this.getStatusFromInt(jobHistoryRow.getStatus()) }} |
| </td> |
| </ng-container> |
| <tr mat-header-row *matHeaderRowDef="jobHistoryTableColumns"></tr> |
| <tr mat-row *matRowDef="let row; columns: jobHistoryTableColumns"></tr> |
| </table> |
| </mat-expansion-panel> |
| </mat-accordion> |
| <mat-divider></mat-divider> |
| <mat-accordion> |
| <mat-expansion-panel> |
| <mat-expansion-panel-header> |
| <mat-panel-title> |
| <b>Child Jobs</b> |
| </mat-panel-title> |
| </mat-expansion-panel-header> |
| <app-view-jobs #child_view_jobs_table manualPopulate="true" hideActionBar="true" hideFilters="true" |
| hideSelectors="true"> |
| </app-view-jobs> |
| </mat-expansion-panel> |
| </mat-accordion> |
| <mat-divider></mat-divider> |
| <mat-accordion> |
| <mat-expansion-panel> |
| <mat-expansion-panel-header> |
| <mat-panel-title> |
| <b>DUTS</b> |
| </mat-panel-title> |
| <mat-panel-description>DUTs that were used for this test.</mat-panel-description> |
| </mat-expansion-panel-header> |
| <table id="associated-duts-table" class="expansion-panel-content" mat-table [dataSource]="associatedDutsTable"> |
| <ng-container matColumnDef="dut"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div>Name</div> |
| </th> |
| <td mat-cell *matCellDef="let associatedDutsRow"> |
| {{ associatedDutsRow.getDut() }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="dut_status"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div>DUT Status</div> |
| </th> |
| <td mat-cell *matCellDef="let associatedDutsRow"> |
| {{ associatedDutsRow.getDutStatus() }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="status"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div>Status</div> |
| </th> |
| <td mat-cell *matCellDef="let associatedDutsRow"> |
| {{ this.getStatusFromInt(associatedDutsRow.getStatus()) }} |
| </td> |
| </ng-container> |
| <ng-container matColumnDef="logs"> |
| <th mat-header-cell *matHeaderCellDef> |
| <div>Logs</div> |
| </th> |
| <td mat-cell *matCellDef="let associatedDutsRow" (click)="$event.stopPropagation()"> |
| <span><a class="logbutton" mat-button target="_blank" |
| href="{{ this.getLogsLink(associatedDutsRow) }}">logs</a></span> |
| </td> |
| </ng-container> |
| <tr mat-header-row *matHeaderRowDef="associatedDutsTableColumns"></tr> |
| <tr mat-row *matRowDef="let row; columns: associatedDutsTableColumns"></tr> |
| </table> |
| </mat-expansion-panel> |
| </mat-accordion> |
| <mat-divider></mat-divider> |
| </div> |