web/app/dashboard/dashboard.component.html
<div class="fci-dashboard-header">
<div fci-grid class="fci-dashboard-welcome">
<div fci-cell="12">
<div class="fci-dashboard-title">Welcome to fastlane.ci!</div>
<div class="fci-dashboard-subtitle">
Open source, self-hosted, mobile-optimized CI powered by fastlane brought to you by the fastlane team.
</div>
<button mat-raised-button color="primary" (click)="openAddProjectDialog()">Add New Project</button>
</div>
</div>
</div>
<div fci-grid>
<div fci-cell="12">
<mat-table #projectsTable class="fci-project-table" [dataSource]="projects">
<!-- Name Column -->
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef>Project Name</mat-header-cell>
<mat-cell *matCellDef="let project">
<fci-status-icon [status]="project.latestStatus"></fci-status-icon>
<span>{{project.name}}</span>
</mat-cell>
</ng-container>
<!-- Latest Build Column -->
<ng-container matColumnDef="latestBuild">
<mat-header-cell *matHeaderCellDef>Latest Build</mat-header-cell>
<mat-cell *matCellDef="let project">{{project.latestDate ? (project.latestDate | amTimeAgo) : "-" }}</mat-cell>
</ng-container>
<!-- Repo Column -->
<ng-container matColumnDef="repo">
<mat-header-cell *matHeaderCellDef>Repo</mat-header-cell>
<mat-cell *matCellDef="let project">{{project.repoName}}</mat-cell>
</ng-container>
<!-- Lane Column -->
<ng-container matColumnDef="lane">
<mat-header-cell *matHeaderCellDef>Lane</mat-header-cell>
<mat-cell *matCellDef="let project">{{project.lane}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="DISPLAYED_COLUMNS"></mat-header-row>
<mat-row *matRowDef="let row; columns: DISPLAYED_COLUMNS; let project" [routerLink]="['/project', project.id]"></mat-row>
</mat-table>
<mat-progress-spinner mode="indeterminate" *ngIf="isLoading" class="fci-loading-spinner" diameter="30"></mat-progress-spinner>
</div>
</div>