diff --git a/APSIM.POStats.Portal/Pages/Index.cshtml b/APSIM.POStats.Portal/Pages/Index.cshtml index 0d6d0f0..84145c3 100644 --- a/APSIM.POStats.Portal/Pages/Index.cshtml +++ b/APSIM.POStats.Portal/Pages/Index.cshtml @@ -9,16 +9,75 @@

Predicted / Observed Stats

-
- +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + + +
+
+ + @if (PullRequestFunctions.HasExceptionInLogs(@Model.PullRequest)) + { + + } + else if (@Model.PullRequest.Status.Count != @Model.PullRequest.CountTotal) + { + + } + else if (@Model.PullRequest.AcceptedPullRequest == null) + { + + } + else if (PullRequestFunctions.GetStatus(@Model.PullRequest) != VariableComparison.Status.Same) + { + + } + else + { + + } +
@@ -57,186 +116,221 @@ Changes are only considered significant if they differ from the accepted stat by more than 1%.

+ +
+ +
+ + + + +
-
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - - - -
-
- - @if (PullRequestFunctions.HasExceptionInLogs(@Model.PullRequest)) - { - - } - else if (@Model.PullRequest.Status.Count != @Model.PullRequest.CountTotal) - { - - } - else if (@Model.PullRequest.AcceptedPullRequest == null) - { - - } - else if (PullRequestFunctions.GetStatus(@Model.PullRequest) != VariableComparison.Status.Same) - { - - } - else - { - - } -
-
- - @if (Model.ShowLogs) - { - - } - else - { - - } -
+ +
@if (@Model.PullRequest.AcceptedPullRequest != null) { -
- - @if (Model.OnlyShowChangedStats) - { - +
General performance ratings for recommended statistics.
+ @{ + List files = PullRequestFunctions.GetFileStats(Model.PullRequest); + PullRequestFunctions.RemoveSame(files); } - else + @foreach (ApsimFileComparison file in files) { - + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, "", "")) + { + + + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach (var table in file.Tables) + { + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, "")) + { + + + + + + + + + + + + + + @foreach (var variable in table.VariableComparisons) + { + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, variable.Name)) + { + + + + + + + + + + + + + + + + + + + + + + + + + + } + } + } + } + } } - -
- - - -
+
@Html.Raw(IndexModel.EmitFileName(file))   Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  
     @Html.Raw(IndexModel.EmitTableName(@table))  n  RMSE  NSE  RSR
          @Html.Raw(IndexModel.EmitVariableName(@variable))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentN, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedN, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NStatus))   @Html.Raw(IndexModel.EmitNumber(variable.CurrentRMSE, 0, 6, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(variable.AcceptedRMSE, 0, 6, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RMSEStatus))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentNSE, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedNSE, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NSEStatus))@VariableFunctions.NSERating(variable.CurrentNSE)   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentRSR, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedRSR, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RSRStatus))@VariableFunctions.RSRRating(variable.CurrentRSR)
} - - - @if (@Model.PullRequest.AcceptedPullRequest != null) - { - - @{ - List files = PullRequestFunctions.GetFileStats(Model.PullRequest); - if (Model.OnlyShowChangedStats) - PullRequestFunctions.RemoveSame(files); - } - @foreach (var file in files) - { - @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, "", "")) + else + { +
Validation in progress
+ } + + +
+ @if (@Model.PullRequest.AcceptedPullRequest != null) + { +
+ @{ + List files = PullRequestFunctions.GetFileStats(Model.PullRequest); + } + @foreach (var file in files) { - - - - - - + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, "", "")) + { + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - @foreach (var table in file.Tables) - { - @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, "")) + + + + + + @foreach (var table in file.Tables) { - - - - - - - - - - - - - - @foreach (var variable in table.VariableComparisons) + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, "")) { - @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, variable.Name)) + + + + + + + + + + + + + + @foreach (var variable in table.VariableComparisons) { - - - - - - - - - - - - - - - - - - - - - - - - - + @if (IndexModel.FilterVariables(files, Model.Filter, file.Name, table.Name, variable.Name)) + { + + + + + + + + + + + + + + + + + + + + + + + + + + } } } } } } - } -
@Html.Raw(IndexModel.EmitFileName(file))   
@Html.Raw(IndexModel.EmitFileName(file))   Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  Curt(Acpt)  
Curt(Acpt)  
     @Html.Raw(IndexModel.EmitTableName(@table))  n  RMSE  NSE  RSR
     @Html.Raw(IndexModel.EmitTableName(@table))  n  RMSE  NSE  RSR
          @Html.Raw(IndexModel.EmitVariableName(@variable))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentN, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedN, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NStatus))   @Html.Raw(IndexModel.EmitNumber(variable.CurrentRMSE, 0, 6, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(variable.AcceptedRMSE, 0, 6, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RMSEStatus))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentNSE, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedNSE, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NSEStatus))@VariableFunctions.NSERating(variable.CurrentNSE)   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentRSR, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedRSR, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RSRStatus))@VariableFunctions.RSRRating(variable.CurrentRSR)
          @Html.Raw(IndexModel.EmitVariableName(@variable))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentN, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedN, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NStatus))   @Html.Raw(IndexModel.EmitNumber(variable.CurrentRMSE, 0, 6, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(variable.AcceptedRMSE, 0, 6, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RMSEStatus))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentNSE, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedNSE, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NSEStatus))@VariableFunctions.NSERating(variable.CurrentNSE)   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentRSR, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedRSR, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RSRStatus))@VariableFunctions.RSRRating(variable.CurrentRSR)
- - @foreach (ApsimFileComparison file in PullRequestFunctions.GetFileComparisons(Model.PullRequest)) - { - - +
+ } + else + { +
Validation in progress
+ } +
+ +
+ @if (@Model.PullRequest.AcceptedPullRequest != null) + { + + @foreach (ApsimFileComparison file in PullRequestFunctions.GetFileComparisons(Model.PullRequest)) + { + @@ -263,74 +357,69 @@ - - @foreach (var table in file.Tables) - { - - - - - - - - - - - - - - @foreach (var variable in table.VariableComparisons) + @foreach (var table in file.Tables) { - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + @foreach (var variable in table.VariableComparisons) + { + + + + + + + + + + + + + + + + + + + + + + + + + + } } } - } -
@Html.Raw(file.CombinedName)     
     @Html.Raw(IndexModel.EmitTableName(@table))  n  RMSE  NSE  RSR
          @Html.Raw(IndexModel.EmitVariableName(@variable))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentN, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedN, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NStatus))   @Html.Raw(IndexModel.EmitNumber(variable.CurrentRMSE, 0, 6, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(variable.AcceptedRMSE, 0, 6, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RMSEStatus))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentNSE, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedNSE, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NSEStatus))@VariableFunctions.NSERating(variable.CurrentNSE)   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentRSR, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedRSR, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RSRStatus))@VariableFunctions.RSRRating(variable.CurrentRSR)     @Html.Raw(IndexModel.EmitTableName(@table))  n  RMSE  NSE  RSR
          @Html.Raw(IndexModel.EmitVariableName(@variable))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentN, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedN, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NStatus))   @Html.Raw(IndexModel.EmitNumber(variable.CurrentRMSE, 0, 6, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(variable.AcceptedRMSE, 0, 6, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RMSEStatus))   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentNSE, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedNSE, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.NSEStatus))@VariableFunctions.NSERating(variable.CurrentNSE)   @Html.Raw(IndexModel.EmitNumber(@variable.CurrentRSR, 3, 0, isAccepted: false)) @Html.Raw(IndexModel.EmitNumber(@variable.AcceptedRSR, 3, 0, isAccepted: true))@Html.Raw(IndexModel.EmitTickCross(variable.RSRStatus))@VariableFunctions.RSRRating(variable.CurrentRSR)
- } - else - { -
Validation in progress
- } + + } + else + { +
Validation in progress
+ } +
+ +
- Logs: - @if (Model.ShowLogs) + @foreach (string log in Model.PullRequest.Outputs) { - @foreach (string log in Model.PullRequest.Outputs) + @foreach (string line in log.Split("\n")) { - @foreach (string line in log.Split("\n")) - { - @Html.Encode(line)
- } + @Html.Encode(line)
} } - else - { - @Html.Raw("Hidden") - }
+
- + \ No newline at end of file diff --git a/APSIM.POStats.Portal/wwwroot/css/site.css b/APSIM.POStats.Portal/wwwroot/css/site.css index 470bd04..a55c3f8 100644 --- a/APSIM.POStats.Portal/wwwroot/css/site.css +++ b/APSIM.POStats.Portal/wwwroot/css/site.css @@ -137,4 +137,70 @@ body { border: 1px solid black; display: inline-block; overflow: hidden; +} + +/* Styles for the tab container on the main page +-------------------------------------------------- */ + +/* Tab Container */ +.tab-container { + max-width: 600px; + margin: 0 auto; + background: #ffffff; + border-radius: 8px; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +/* Tab Headers */ +.tab-menu { + display: flex; + background-color: #f8fafc; + border-bottom: 2px solid #e2e8f0; + margin: 0; + padding: 0; + list-style: none; +} + +.tab-button { + flex: 1; + padding: 1rem; + border: none; + background: none; + font-size: 1rem; + font-weight: 600; + color: #64748b; + cursor: pointer; + transition: all 0.2s ease; + text-align: center; +} + +.tab-button:hover { + background-color: #f1f5f9; + color: #0f172a; +} + +/* Active Tab Style */ +.tab-button.active { + color: #3b82f6; + border-bottom: 2px solid #3b82f6; + background-color: #ffffff; + margin-bottom: -2px; /* Overlaps container border */ +} + +/* Tab Content Panels */ +.tab-panel { + display: none; + padding: 1.5rem; + animation: fadeIn 0.3s ease; +} + +.tab-panel.active { + display: block; +} + +/* Simple Entry Animation */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(2px); } + to { opacity: 1; transform: translateY(0); } } \ No newline at end of file