diff --git a/applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/AIReporting/Index.cshtml b/applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/AIReporting/Index.cshtml
index a7ffb565fb..6e4fd0b435 100644
--- a/applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/AIReporting/Index.cshtml
+++ b/applications/Unity.GrantManager/modules/Unity.AI/src/Unity.AI.Web/Pages/AIReporting/Index.cshtml
@@ -1,18 +1,9 @@
@page
@model Unity.AI.Web.Pages.AIReporting.IndexModel
-@section styles {
- @if (Model.CanViewAiReporting)
- {
-
- }
-}
-
@section scripts {
@if (Model.CanViewAiReporting)
{
-
-
diff --git a/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/Domain/Services/PaymentRequestQueryManager.cs b/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/Domain/Services/PaymentRequestQueryManager.cs
index cbf5075072..7f07112a4b 100644
--- a/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/Domain/Services/PaymentRequestQueryManager.cs
+++ b/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/Domain/Services/PaymentRequestQueryManager.cs
@@ -152,7 +152,7 @@ public async Task> GetPagedPaymentRequestsWithIncludesAsync
if (includeTags)
{
paymentsQueryable = paymentsQueryable
- .Include(pr => pr.PaymentTags)
+ .Include(pr => pr.PaymentTags!)
.ThenInclude(pt => pt.Tag);
}
@@ -161,9 +161,7 @@ public async Task> GetPagedPaymentRequestsWithIncludesAsync
paymentsQueryable = paymentsQueryable.Include(pr => pr.ExpenseApprovals);
}
-#pragma warning disable CS8620 // Argument cannot be used for parameter due to differences in the nullability of reference types.
var paymentWithIncludes = await paymentsQueryable.ToListAsync();
-#pragma warning restore CS8620 // Argument cannot be used for parameter due to differences in the nullability of reference types.
return paymentWithIncludes;
}
diff --git a/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentsApplicationMapperlyProfile.cs b/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentsApplicationMapperlyProfile.cs
index 2eb6dcf743..10ff71d7e1 100644
--- a/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentsApplicationMapperlyProfile.cs
+++ b/applications/Unity.GrantManager/modules/Unity.Payments/src/Unity.Payments.Application/PaymentsApplicationMapperlyProfile.cs
@@ -24,11 +24,15 @@ public partial class PaymentRequestToPaymentRequestDtoMapper : MapperBase
- Loading...
+ Loading...
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js
index 7e4992918b..e655747a58 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/ApplicationForms/Mapping.js
@@ -8,7 +8,6 @@
let worksheetMapColumn = document.querySelector('#worksheet-map-available-fields-column');
let excludedIntakeMappings = new Set(['ConfirmationId', 'SubmissionId', 'SubmissionDate']);
let dataTable;
- if (globalThis.toastr) { toastr.options.positionClass = 'toast-top-center'; }
let allowableTypes = new Set(['textarea',
'orgbook',
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml
index be2f3c00af..5cfb432069 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.cshtml
@@ -3,17 +3,14 @@
@using Unity.GrantManager.Web.Pages.Dashboard
@section styles {
+
+
-
-
}
@section scripts
{
+
-
-
-
-
}
@@ -32,32 +29,27 @@
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.css b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.css
index a6efc06f1b..fd85e840da 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.css
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.css
@@ -24,10 +24,6 @@
justify-content: center;
}
-.application-dashboard-dropdown select {
- display: none !important;
-}
-
.application-dashboard-date {
min-width: 250px;
margin-top: 10px;
@@ -35,16 +31,136 @@
font-weight: bold;
}
-.bs-actionsbox {
- margin-top: 4px;
-}
-
-.bs-actionsbox .btn-group {
+/* Select All / Deselect All controls injected into the Select2 dropdown,
+ replacing bootstrap-select's actionsBox. */
+.dashboard-actionsbox {
display: flex;
justify-content: space-between;
- gap: 8px;
+ gap: var(--bc-layout-margin-small);
+ padding: var(--bc-layout-margin-xsmall);
}
-.bs-actionsbox .btn-group button {
+.dashboard-actionsbox button {
+ flex: 1 1 auto;
width: auto;
+}
+
+/* The filter dropdowns always show a fixed label, so style them as the
+ toolbar buttons they replace (see .custom-table-btn in unity-styles.css)
+ rather than as multi-select inputs. */
+.application-dashboard-dropdown .select2-container--bootstrap-5 .select2-selection {
+ position: relative;
+ /* Fixed rather than content-driven so all six stay level: "SUB-STATUS" is
+ long enough to wrap and would otherwise make its box taller. Not
+ --bc-input-field-height (34px), which nothing in this toolbar uses. */
+ height: 38px;
+ min-height: 38px;
+ display: flex;
+ align-items: center;
+ padding: 0 1.75rem 0 0.75rem;
+ /* Matches the literal in .custom-table-btn; the theme has no radius token. */
+ border-radius: 5px;
+ background-color: var(--bc-colors-white-primary-500);
+}
+
+.application-dashboard-dropdown .select2-container--bootstrap-5 .select2-selection:hover {
+ border-color: var(--bc-colors-blue-primary);
+}
+
+/* The label is written straight into the
, so strip its list styling and
+ keep it on one line: "SUB-STATUS" wrapping made that box taller than the
+ other five and broke the row alignment. */
+.application-dashboard-dropdown .select2-container--bootstrap-5 .select2-selection__rendered {
+ display: block;
+ /* Grow to fill the button: overflow:hidden below zeroes a flex item's
+ automatic minimum size, so without this the label collapses and
+ ellipsises even though there is room for it. */
+ flex: 1 1 auto;
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ color: var(--bc-colors-blue-primary);
+ /* These filters replaced buttons styled with .btn/.dt-buttons, so use the
+ theme's button size rather than the base body size. layout.css feeds the
+ same variable into --bs-btn-font-size. */
+ font-size: var(--bc-font-size-btn);
+ font-weight: 700;
+ text-transform: uppercase;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+/* Select2 only draws an arrow for single selects, so supply one. */
+.application-dashboard-dropdown .select2-container--bootstrap-5 .select2-selection::after {
+ content: "";
+ position: absolute;
+ right: 0.75rem;
+ top: 50%;
+ transform: translateY(-25%);
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 5px solid var(--bc-colors-blue-primary);
+ pointer-events: none;
+}
+
+/* For multiple selects Select2 renders the search field inline in the control,
+ as a sibling of the label, and the two compete for width. Rather than move
+ the field (which detaches it from Select2's filtering), swap which one is
+ visible: label while closed, search while open. */
+.application-dashboard-dropdown .select2-container:not(.select2-container--open) .select2-search--inline {
+ display: none;
+}
+
+.application-dashboard-dropdown .select2-container--open .select2-selection__rendered {
+ display: none;
+}
+
+/* Select2 sizes the inline search field to its content, which clips the
+ placeholder to a character or two. The label is hidden while open, so give
+ the field the whole control. */
+.application-dashboard-dropdown .select2-container--open .select2-search--inline,
+.application-dashboard-dropdown .select2-container--open .select2-search--inline .select2-search__field {
+ width: 100% !important;
+ margin: 0;
+}
+
+/* Everything below is scoped to dashboard-filter-dropdown (set via
+ dropdownCssClass) because Select2 renders panels at the end of ,
+ outside .application-dashboard-dropdown. */
+
+/* Selected entries get a light tint and a checkmark rather than the theme's
+ solid fill, which turned the whole list blue given these filters default to
+ everything selected.
+ These selectors deliberately mirror the shape of the ones in
+ select2-bootstrap-5-theme.css and add .dashboard-filter-dropdown on top:
+ the theme's are five classes deep, so anything shorter loses to them. */
+.select2-container--bootstrap-5 .select2-dropdown.dashboard-filter-dropdown .select2-results__options .select2-results__option.select2-results__option--selected {
+ /* Same tint the theme uses for pressed state and DataTables selected rows
+ (--dt-row-selected is the same colour), so selection reads consistently. */
+ background-color: var(--bc-colors-grey-pressed);
+ color: var(--bc-type-color-primary);
+}
+
+.select2-container--bootstrap-5 .select2-dropdown.dashboard-filter-dropdown .select2-results__options .select2-results__option.select2-results__option--selected::after {
+ content: "\2713";
+ float: right;
+ color: var(--bc-type-color-primary);
+}
+
+/* Keyboard position: subtle, so it does not look like a hover left behind.
+ Declared before :hover so that hovering the keyboard-highlighted option
+ still shows the hover colour, since both carry the same specificity. */
+.select2-container--bootstrap-5 .select2-dropdown.dashboard-filter-dropdown .select2-results__options .select2-results__option.select2-results__option--highlighted {
+ background-color: var(--bc-colors-grey-hover);
+ color: var(--bc-type-color-primary);
+}
+
+/* Mouse feedback comes from :hover, not Select2's --highlighted class, which
+ marks the keyboard position and lingers once the pointer leaves the list.
+ --bc-colors-blue-hover is the theme's hover tint and is light enough to keep
+ the text and checkmark readable in their normal colour. */
+.select2-container--bootstrap-5 .select2-dropdown.dashboard-filter-dropdown .select2-results__options .select2-results__option:hover {
+ background-color: var(--bc-colors-blue-hover);
+ color: var(--bc-type-color-primary);
}
\ No newline at end of file
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js
index 270eafe0f8..adb540d9d1 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/Dashboard/Index.js
@@ -407,18 +407,266 @@ $('#dashboardIntakeId').change(function () {
reloadDashboard();
});
-function highlightSelected(dropdownId,title) {
+// These dropdowns always show a fixed label (e.g. "STATUS") rather than the
+// current selection, so the filter bar keeps a constant width.
+function setDropdownLabel(dropdownId, title) {
+ $('#' + dropdownId)
+ .next('.select2-container')
+ .find('.select2-selection__rendered')
+ .attr('title', title)
+ .text(title);
+}
+
+function highlightSelected(dropdownId, title) {
$('#' + dropdownId + ' option:selected').addClass('dt-button-active');
$('#' + dropdownId + ' option:not(:selected)').removeClass('dt-button-active');
- $('#' + dropdownId).selectpicker('refresh');
- $('#' + dropdownId).closest('.bootstrap-select').find('.btn .filter-option-inner-inner').html(title);
- $('#' + dropdownId).closest('.bootstrap-select').find('.btn').removeClass('bs-placeholder');
+ setDropdownLabel(dropdownId, title);
+}
+
+// Select2 has no equivalent of bootstrap-select's actionsBox, so build one.
+function addSelectAllControls($select) {
+ const $dropdown = $('.select2-container--open .select2-dropdown');
+ if ($dropdown.find('.dashboard-actionsbox').length) {
+ return;
+ }
+
+ const $box = $('');
+ const $selectAll = $('');
+ const $deselectAll = $('');
+
+ const setAll = (selected) => (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ $select.find('option').prop('selected', selected);
+ // Fires the inline onchange (reloadDashboard) plus our own change handlers.
+ $select.trigger('change');
+ syncResultRows($select);
+ };
+
+ $selectAll.on('click', setAll(true));
+ $deselectAll.on('click', setAll(false));
+
+ $box.append($selectAll, $deselectAll);
+ $dropdown.prepend($box);
+
+ // Select2 leaves --highlighted on the last option the mouse passed over,
+ // because it doubles as the keyboard position. Left alone it looks like a
+ // hover that never cleared, so drop it once the pointer leaves the list.
+ // Select2 reapplies it on the next mousemove or arrow key.
+ $dropdown.find('.select2-results')
+ .off('mouseleave.dashboardFilters')
+ .on('mouseleave.dashboardFilters', function () {
+ $(this).find('.select2-results__option--highlighted')
+ .removeClass('select2-results__option--highlighted');
+ });
+}
+
+// Result rows are matched to their
- Loading...
+ Loading...
@@ -129,7 +129,7 @@
- Loading...
+ Loading...
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js
index 072af00edd..9cfeae270f 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/Details.js
@@ -398,7 +398,7 @@ $(function () {
const bootstrapCSS = doc.createElement('link');
bootstrapCSS.rel = 'stylesheet';
- bootstrapCSS.href = '/libs/bootstrap-4/dist/css/bootstrap.min.css';
+ bootstrapCSS.href = '/libs/bootstrap/css/bootstrap.min.css';
const formioCSS = doc.createElement('link');
formioCSS.rel = 'stylesheet';
@@ -416,6 +416,19 @@ $(function () {
button {
display: none !important;
}
+ /* Print only. Bootstrap 5 sizes headings with calc(... + vw), so
+ printed output would otherwise vary with the width of the window
+ it was opened from. Pin them to the fixed sizes Bootstrap 4 used
+ so the printed result is the same whatever the screen, while the
+ on-screen preview keeps Bootstrap 5's responsive sizing. */
+ @media print {
+ h1, .h1 { font-size: 2.5rem !important; }
+ h2, .h2 { font-size: 2rem !important; }
+ h3, .h3 { font-size: 1.75rem !important; }
+ h4, .h4 { font-size: 1.5rem !important; }
+ h5, .h5 { font-size: 1.25rem !important; }
+ h6, .h6 { font-size: 1rem !important; }
+ }
`;
head.appendChild(jqueryScript);
@@ -462,7 +475,7 @@ $(function () {
// Create and append stylesheets
const stylesheets = [
- { href: '/libs/bootstrap-4/dist/css/bootstrap.min.css' },
+ { href: '/libs/bootstrap/css/bootstrap.min.css' },
{ href: '/Pages/GrantApplications/ScoresheetPrint.css' }
];
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/ScoresheetPrint.css b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/ScoresheetPrint.css
index b2cd89f790..4a032d7928 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/ScoresheetPrint.css
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Pages/GrantApplications/ScoresheetPrint.css
@@ -1,3 +1,15 @@
+/* Print only. Bootstrap 5 sizes headings with calc(... + vw), so printed output
+ would otherwise vary with the width of the window it was opened from. Pin them
+ to the fixed sizes Bootstrap 4 used, leaving the on-screen preview alone. */
+@media print {
+ h1, .h1 { font-size: 2.5rem; }
+ h2, .h2 { font-size: 2rem; }
+ h3, .h3 { font-size: 1.75rem; }
+ h4, .h4 { font-size: 1.5rem; }
+ h5, .h5 { font-size: 1.25rem; }
+ h6, .h6 { font-size: 1rem; }
+}
+
.unity-user-initials {
display: none !important;
}
diff --git a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml
index fa4b64e81d..7843f10950 100644
--- a/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml
+++ b/applications/Unity.GrantManager/src/Unity.GrantManager.Web/Views/Shared/Components/ActionBar/Default.cshtml
@@ -134,7 +134,7 @@