Initial commit
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
@model PowderCoating.Web.ViewModels.Reports.JobCycleTimeViewModel
|
||||
@{ ViewData["Title"] = "Job Cycle Time"; }
|
||||
|
||||
<partial name="_ReportHeader" model="Model" />
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-sm-4">
|
||||
<div class="card text-bg-primary">
|
||||
<div class="card-body py-2">
|
||||
<div class="small">Overall Avg Cycle Time</div>
|
||||
<div class="fs-5 fw-bold">@Model.OverallAvgCycleDays.ToString("N1") days</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-body py-2 text-center">
|
||||
<div class="small text-muted">Stages Tracked</div>
|
||||
<div class="fs-5 fw-bold">@Model.Items.Count</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="card border-secondary">
|
||||
<div class="card-body py-2 text-center">
|
||||
<div class="small text-muted">Slowest Stage</div>
|
||||
@if (Model.Items.Any())
|
||||
{
|
||||
var slowest = Model.Items.OrderByDescending(i => i.AvgDays).First();
|
||||
<div class="fs-6 fw-bold text-warning">@slowest.StatusName (@slowest.AvgDays.ToString("N1") d)</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-6">
|
||||
<div class="card h-100">
|
||||
<div class="card-header fw-semibold">Average Days per Stage</div>
|
||||
<div class="card-body">
|
||||
<canvas id="cycleChart" height="300"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card h-100">
|
||||
<div class="card-header fw-semibold">Stage Detail</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-sm table-hover mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Stage</th>
|
||||
<th class="text-end">Avg Days</th>
|
||||
<th class="text-end">Min</th>
|
||||
<th class="text-end">Max</th>
|
||||
<th class="text-end">Jobs</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in Model.Items)
|
||||
{
|
||||
<tr>
|
||||
<td>@item.StatusName</td>
|
||||
<td class="text-end fw-semibold">@item.AvgDays.ToString("N1")</td>
|
||||
<td class="text-end text-success">@item.MinDays.ToString("N1")</td>
|
||||
<td class="text-end text-danger">@item.MaxDays.ToString("N1")</td>
|
||||
<td class="text-end text-muted">@item.JobCount</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section Scripts {
|
||||
<script src="~/lib/chartjs/chart.umd.min.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
const labels = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Items.Select(i => i.StatusName)));
|
||||
const avgDays = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Items.Select(i => i.AvgDays)));
|
||||
const minDays = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Items.Select(i => i.MinDays)));
|
||||
const maxDays = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Items.Select(i => i.MaxDays)));
|
||||
|
||||
new Chart(document.getElementById('cycleChart'), {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels,
|
||||
datasets: [
|
||||
{ label: 'Avg Days', data: avgDays, backgroundColor: 'rgba(13,110,253,0.7)' },
|
||||
{ label: 'Min Days', data: minDays, backgroundColor: 'rgba(25,135,84,0.5)' },
|
||||
{ label: 'Max Days', data: maxDays, backgroundColor: 'rgba(220,53,69,0.4)' }
|
||||
]
|
||||
},
|
||||
options: {
|
||||
indexAxis: 'y',
|
||||
responsive: true,
|
||||
plugins: { legend: { position: 'top' } },
|
||||
scales: { x: { beginAtZero: true, title: { display: true, text: 'Days' } } }
|
||||
}
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
}
|
||||
Reference in New Issue
Block a user