diff --git a/FMS/Pages/Dashboard/Index.cshtml b/FMS/Pages/Dashboard/Index.cshtml index 332687d0..28e0e68c 100644 --- a/FMS/Pages/Dashboard/Index.cshtml +++ b/FMS/Pages/Dashboard/Index.cshtml @@ -42,7 +42,7 @@ @if (Model.UserEvents.Where(f => f.CompletionDate == null && f.StartDate == null).Count() > 0) { - + @@ -116,7 +116,7 @@ @if (Model.UserEvents.Where(f => f.CompletionDate == null && f.StartDate != null).Count() > 0) {
Facility Number Facility Name
- + @@ -190,7 +190,7 @@ @if (Model.UserEvents.Where(f => f.CompletionDate != null).Count() > 0) {
Facility Number Facility Name
- + @@ -312,7 +312,7 @@ @if (Model.UnitEvents.Where(f => f.CompletionDate == null && f.StartDate == null && f.ComplianceOfficer?.Name == co).Count() > 0) {
Facility Number Facility Name
- + @@ -386,7 +386,7 @@ @if (Model.UnitEvents.Where(f => f.CompletionDate == null && f.StartDate != null && f.ComplianceOfficer?.Name == co).Count() > 0) {
Facility Number Facility Name
- + @@ -460,7 +460,7 @@ @if (Model.UnitEvents.Where(e => e.CompletionDate != null && e.ComplianceOfficer?.Name == co).Count() > 0) {
Facility Number Facility Name
- + @@ -609,7 +609,7 @@
Facility Number Facility Name
- + @@ -692,7 +692,7 @@
Facility Number Facility Name
- + @@ -775,7 +775,7 @@
Facility Number Facility Name
- + @@ -905,7 +905,7 @@ @if (Model.UserFacilities.Where(f => f.FacilityStatus.Name.Equals("Active")).Count() > 0) {
Facility Number Facility Name
- + @@ -963,7 +963,7 @@ @if (Model.UserFacilities.Where(f => f.FacilityStatus.Name.Equals("DELISTED")).Count() > 0) {
Number Name
- + @@ -1021,7 +1021,7 @@ @if (Model.UserFacilities.Where(f => !f.FacilityStatus.Name.Equals("DELISTED") && !f.FacilityStatus.Name.Equals("Active")).Count() > 0) {
Number Name
- + @@ -1127,7 +1127,7 @@
Number Name
- + @@ -1185,7 +1185,7 @@
Number Name
- + @@ -1243,7 +1243,7 @@
Number Name
- + @@ -1354,7 +1354,7 @@
Number Name
- + @@ -1412,7 +1412,7 @@
Number Name
- + @@ -1471,7 +1471,7 @@
Number Name
- + diff --git a/FMS/Pages/Event/Edit.cshtml b/FMS/Pages/Event/Edit.cshtml index 37d94a92..97b71682 100644 --- a/FMS/Pages/Event/Edit.cshtml +++ b/FMS/Pages/Event/Edit.cshtml @@ -116,14 +116,14 @@ - +
- +
@@ -132,12 +132,12 @@ - +
- diff --git a/FMS/Pages/Facilities/Details.cshtml b/FMS/Pages/Facilities/Details.cshtml index 96e0f9db..fd4d6310 100644 --- a/FMS/Pages/Facilities/Details.cshtml +++ b/FMS/Pages/Facilities/Details.cshtml @@ -1128,6 +1128,7 @@ { Add Substance } + See Chemical List
diff --git a/FMS/Pages/Maintenance/Chemical/Detail.cshtml b/FMS/Pages/Maintenance/Chemical/Detail.cshtml new file mode 100644 index 00000000..98ebc107 --- /dev/null +++ b/FMS/Pages/Maintenance/Chemical/Detail.cshtml @@ -0,0 +1,163 @@ +@page +@using FMS.Pages.Maintenance +@model FMS.Pages.Maintenance.Chemical.DetailModel +@{ +} +@section Scripts { + + +} + +@{ + ViewData["Title"] = $"Site Maintenance: {MaintenanceOptions.Chemical}"; +} + +

+ @MaintenanceOptions.Chemical +

+ + +
+
+
+ +
+ + + (@(Model.Chemicals.Count > 0 ? Model.Chemicals.Count.ToString() : "none") found) + +
+ +
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
+
+ +
    +
    +
    \ No newline at end of file diff --git a/FMS/Pages/Maintenance/Chemical/Detail.cshtml.cs b/FMS/Pages/Maintenance/Chemical/Detail.cshtml.cs new file mode 100644 index 00000000..22eece2b --- /dev/null +++ b/FMS/Pages/Maintenance/Chemical/Detail.cshtml.cs @@ -0,0 +1,71 @@ +using FMS.Domain.Dto; +using FMS.Domain.Repositories; +using FMS.Platform.Extensions; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; + +namespace FMS.Pages.Maintenance.Chemical +{ + public class DetailModel : PageModel + { + private readonly IChemicalRepository _repository; + public DetailModel(IChemicalRepository repository) => _repository = repository; + + public IReadOnlyList Chemicals { get; private set; } + + public ChemicalSummaryDto Chemical { get; } + + public DisplayMessage DisplayMessage { get; private set; } + + public async Task OnGetAsync() + { + Chemicals = await _repository.GetChemicalListAsync(); + DisplayMessage = TempData?.GetDisplayMessage(); + return Page(); + } + + public async Task OnPostAsync(Guid? itemId) + { + if (itemId == null) + { + return BadRequest(); + } + + if (!ModelState.IsValid) + { + return Page(); + } + + var chemical = await _repository.GetChemicalByIdAsync(itemId.Value); + + if (chemical == null) + { + return NotFound(); + } + + try + { + await _repository.UpdateChemicalStatusAsync(itemId.Value, !chemical.Active); + } + catch (DbUpdateConcurrencyException) + { + if (!await _repository.ChemicalExistsAsync(itemId.Value)) + { + return NotFound(); + } + + throw; + } + + Chemicals = await _repository.GetChemicalListAsync(); + + TempData?.SetDisplayMessage(Context.Success, + chemical.Active + ? $"{MaintenanceOptions.Chemical} \"{chemical.ChemicalName}\" successfully removed from list." + : $"{MaintenanceOptions.Chemical} \"{chemical.ChemicalName}\" successfully restored."); + + return RedirectToPage("./Index"); + } + } +} diff --git a/FMS/wwwroot/css/site.css b/FMS/wwwroot/css/site.css index 418bf432..b604fb9a 100644 --- a/FMS/wwwroot/css/site.css +++ b/FMS/wwwroot/css/site.css @@ -93,9 +93,9 @@ a:focus { text-decoration: underline; } -a:focus:not(.btn) { - text-decoration: none; -} + a:focus:not(.btn) { + text-decoration: none; + } .btn-primary:focus { color: #fff; @@ -159,7 +159,7 @@ a:focus:not(.btn) { .btn-outline-info { color: #fff; - background-color: #17a2b8; /*#5BAFD1;*/ /*#507033;*/ + background-color: #17a2b8; /*#5BAFD1;*/ /*#507033;*/ } .btn-outline-warning:focus { @@ -208,17 +208,17 @@ body { color: #008000; } -.footer a:hover, .footer a:focus { - color: #106717; -} + .footer a:hover, .footer a:focus { + color: #106717; + } .footer .bg-brand a { color: #ffff00; } -.footer .bg-brand a:hover, .footer .bg-brand a:focus { - color: #d9d900; -} + .footer .bg-brand a:hover, .footer .bg-brand a:focus { + color: #d9d900; + } /* Skip to content link -------------------------------------------------- */ @@ -234,15 +234,15 @@ body { z-index: 100; } -.skipnav:focus { - background: #fff; - left: 0; - outline: 0; - box-shadow: 0 0 3px #1B98CA, 0 0 7px #1B98CA; - position: absolute; - top: 0; - transition: all 0.2s ease-in-out; -} + .skipnav:focus { + background: #fff; + left: 0; + outline: 0; + box-shadow: 0 0 3px #1B98CA, 0 0 7px #1B98CA; + position: absolute; + top: 0; + transition: all 0.2s ease-in-out; + } /* Button with image -------------------------------------------------- */ @@ -250,9 +250,9 @@ body { line-height: 1; } -.btn-img img { - height: 35px; -} + .btn-img img { + height: 35px; + } .btn-img-bg { background: white; @@ -344,17 +344,17 @@ a[target]::after { border-left: 0.25rem solid var(--callout-border, var(--bs-gray-400)); } -.callout > :last-child { - margin-bottom: 0; -} + .callout > :last-child { + margin-bottom: 0; + } -.callout + .callout { - margin-top: -.25rem; -} + .callout + .callout { + margin-top: -.25rem; + } -.callout .highlight { - background-color: rgba(0, 0, 0, 0.05); -} + .callout .highlight { + background-color: rgba(0, 0, 0, 0.05); + } .callout-info { --callout-color: var(--bs-info-text-emphasis); @@ -384,9 +384,9 @@ a[target]::after { border: 1px solid; } - .banner-test-site::after { - content: "—Not for public distribution"; - } + .banner-test-site::after { + content: "—Not for public distribution"; + } } /* Chemical select box -------------------------------------------------- */ @@ -412,7 +412,17 @@ a[target]::after { /* Apply directly to your custom accordion or override globally */ .accordion { --bs-accordion-bg: #c8f8d5; /* Body background */ - /*--bs-accordion-color: #0d5f06;*/ /* Body text color */ + /*--bs-accordion-color: #013901;*/ /* Body text color */ + --bs-accordion-btn-bg: #c8f8d5; /* Collapsed button background */ + --bs-accordion-btn-color: #212529; /* Collapsed button text */ + --bs-accordion-active-bg: #013901; /* Expanded button background */ + --bs-accordion-active-color: #fff; /* Expanded button text */ + --bs-accordion-border-color: #09601d; /* Border color */ +} + +[data-bs-theme="dark"] .accordion { + --bs-accordion-bg: #c8f8d5; /* Body background */ + --bs-accordion-color: #c8f8d5; /* Body text color */ --bs-accordion-btn-bg: #c8f8d5; /* Collapsed button background */ --bs-accordion-btn-color: #212529; /* Collapsed button text */ --bs-accordion-active-bg: #013901; /* Expanded button background */ @@ -420,20 +430,29 @@ a[target]::after { --bs-accordion-border-color: #09601d; /* Border color */ } - /*1. Header Button when EXPANDED (Active)*/ +/*1. Header Button when EXPANDED (Active)*/ .accordion-button:not(.collapsed) { - background-color: #013901; /*Custom active background */ - color: #c8f8d5; /*Custom active text color */ + background-color: #013901; /*Custom active background */ + color: #c8f8d5; /*Custom active text color */ } - /*2. Remove or change the blue focus halo outline*/ +/*2. Remove or change the blue focus halo outline*/ .accordion-button:focus { box-shadow: initial; border-color: #09601d; } - /*3. The inner body background */ +/*3. The inner body background */ .accordion-body { background-color: #013901; } +/* Valid form control styles for flashing boxes*/ +.form-control.is-valid, .was-validated .form-control:valid { + border-color: var(--bs-form-valid-border-color); + padding-right: calc(1.5em + .75rem); + background-image: url("data:image/svg+xml,"); + background-repeat: no-repeat; + background-position: right calc(.375em + .1875rem) center; + background-size: calc(.75em + .375rem) calc(.75em + .375rem); +} diff --git a/FMS/wwwroot/js/dateControlBorderFlash.js b/FMS/wwwroot/js/dateControlBorderFlash.js new file mode 100644 index 00000000..18316174 --- /dev/null +++ b/FMS/wwwroot/js/dateControlBorderFlash.js @@ -0,0 +1,82 @@ +document.addEventListener('DOMContentLoaded', () => { + const reportingPeriodType = document.getElementById('Item_ReportingPeriodType'); + const reportingPeriodStart = document.getElementById('Item_ReportingPeriodStart'); + const reportingPeriodEnd = document.getElementById('Item_ReportingPeriodEnd'); + + if (!reportingPeriodType || !reportingPeriodStart || !reportingPeriodEnd) return; + + reportingPeriodType.addEventListener('change', () => { + const today = new Date(); + const currentYear = today.getFullYear(); + const currentMonth = today.getMonth(); // 0-indexed + + let startDate, endDate; + + switch (reportingPeriodType.value) { + case '1': // Monthly + // Last month + startDate = new Date(currentYear, currentMonth - 1, 1); + endDate = new Date(currentYear, currentMonth, 0); + break; + + case '2': // First Quarter + startDate = new Date(currentYear - (currentMonth < 3 ? 1 : 0), 0, 1); + endDate = new Date(currentYear - (currentMonth < 3 ? 1 : 0), 3, 0); + break; + + case '3': // Second Quarter + startDate = new Date(currentYear - (currentMonth < 6 ? 1 : 0), 3, 1); + endDate = new Date(currentYear - (currentMonth < 6 ? 1 : 0), 6, 0); + break; + + case '4': // Third Quarter + startDate = new Date(currentYear - (currentMonth < 9 ? 1 : 0), 6, 1); + endDate = new Date(currentYear - (currentMonth < 9 ? 1 : 0), 9, 0); + break; + + case '5': // Fourth Quarter + startDate = new Date(currentYear - 1, 9, 1); + endDate = new Date(currentYear, 0, 0); + break; + + case '6': // First Semiannual + startDate = new Date(currentYear - (currentMonth < 6 ? 1 : 0), 0, 1); + endDate = new Date(currentYear - (currentMonth < 6 ? 1 : 0), 6, 0); + break; + + case '7': // Second Semiannual + startDate = new Date(currentYear - 1, 6, 1); + endDate = new Date(currentYear, 0, 0); + break; + + case '8': // Annual + startDate = new Date(currentYear - 1, 0, 1); + endDate = new Date(currentYear, 0, 0); + break; + + default: + return; + } + + if (startDate && endDate) { + reportingPeriodStart.value = FormatDate(startDate); + reportingPeriodEnd.value = FormatDate(endDate); + reportingPeriodStart.classList.remove('flashOutline'); + reportingPeriodEnd.classList.remove('flashOutline'); + // `offsetWidth` is only referenced here to trigger a layout reflow, so that adding back the class restarts the CSS animation. + // See: https://css-tricks.com/restart-css-animation/#aa-update-another-javascript-method-to-restart-a-css-animation + reportingPeriodStart.offsetWidth; //NOSONAR triggers reflow + reportingPeriodEnd.offsetWidth; //NOSONAR triggers reflow + reportingPeriodStart.classList.add('flashOutline'); + reportingPeriodEnd.classList.add('flashOutline'); + } + }); +}); + +function FormatDate(date) { + return [ + date.getFullYear(), + String(date.getMonth() + 1).padStart(2, '0'), + String(date.getDate()).padStart(2, '0'), + ].join('-'); +}
    Number Name