diff --git a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/alert_user.js b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/alert_user.js
index b63241c36e7b..228a62a76224 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/alert_user.js
+++ b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/alert_user.js
@@ -16,7 +16,7 @@
hqDefine("hqwebapp/js/bootstrap5/alert_user", [
"jquery",
"knockout",
- "hqwebapp/js/bootstrap3/hq.helpers",
+ "hqwebapp/js/bootstrap5/hq.helpers",
],
function (
$,
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq-bug-report.js b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq-bug-report.js
index a803cafda6ee..778d7485c6d9 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq-bug-report.js
+++ b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq-bug-report.js
@@ -1,49 +1,58 @@
hqDefine('hqwebapp/js/bootstrap5/hq-bug-report', [
- "jquery", "jquery-form/dist/jquery.form.min", "hqwebapp/js/bootstrap5/hq.helpers",
-], function ($) {
+ "jquery",
+ "hqwebapp/js/bootstrap5_loader",
+ "jquery-form/dist/jquery.form.min",
+ "hqwebapp/js/bootstrap5/hq.helpers",
+], function ($, bootstrap) {
+ 'use strict';
$(function () {
- var $hqwebappBugReportModal = $('#modalReportIssue'),
- $hqwebappBugReportForm = $('#hqwebapp-bugReportForm'),
- $hqwebappBugReportSubmit = $('#bug-report-submit'),
- $hqwebappBugReportCancel = $('#bug-report-cancel'),
- $ccFormGroup = $("#bug-report-cc-form-group"),
- $emailFormGroup = $("#bug-report-email-form-group"),
- $issueSubjectFormGroup = $("#bug-report-subject-form-group"),
- isBugReportSubmitting = false;
+ let self = {};
- var resetForm = function () {
- $hqwebappBugReportForm.find("button[type='submit']").button('reset');
- $hqwebappBugReportForm.resetForm();
- $hqwebappBugReportCancel.enableButton();
- $hqwebappBugReportSubmit.button('reset');
- $ccFormGroup.removeClass('has-error has-feedback');
- $ccFormGroup.find(".label-danger").addClass('hide');
- $emailFormGroup.removeClass('has-error has-feedback');
- $emailFormGroup.find(".label-danger").addClass('hide');
+ self.$bugReportModalElement = $('#modalReportIssue');
+ self.bugReportModal = new bootstrap.Modal(self.$bugReportModalElement);
+ self.$hqwebappBugReportForm = $('#hqwebapp-bugReportForm');
+ self.$hqwebappBugReportSubmit = $('#bug-report-submit');
+ self.$hqwebappBugReportCancel = $('#bug-report-cancel');
+ self.$ccFormGroup = $("#bug-report-cc-form-group");
+ self.$emailFormGroup = $("#bug-report-email-form-group");
+ self.$issueSubjectFormGroup = $("#bug-report-subject-form-group");
+ self.isBugReportSubmitting = false;
+
+ self.resetForm = function () {
+ self.$hqwebappBugReportForm.find("button[type='submit']").changeButtonState('reset');
+ self.$hqwebappBugReportForm.resetForm();
+ self.$hqwebappBugReportCancel.enableButton();
+ self.$hqwebappBugReportSubmit.changeButtonState('reset');
+ self.$ccFormGroup.removeClass('has-error has-feedback');
+ self.$ccFormGroup.find(".label-danger").addClass('hide');
+ self.$emailFormGroup.removeClass('has-error has-feedback');
+ self.$emailFormGroup.find(".label-danger").addClass('hide');
};
- $hqwebappBugReportModal.on('shown.bs.modal', function () {
+ self.$bugReportModalElement.on('shown.bs.modal', function () {
$("input#bug-report-subject").focus();
});
- $hqwebappBugReportForm.submit(function () {
- var isDescriptionEmpty = !$("#bug-report-subject").val() && !$("#bug-report-message").val();
+ self.$hqwebappBugReportForm.submit(function (e) {
+ e.preventDefault();
+
+ let isDescriptionEmpty = !$("#bug-report-subject").val() && !$("#bug-report-message").val();
if (isDescriptionEmpty) {
- highlightInvalidField($issueSubjectFormGroup);
+ self.highlightInvalidField(self.$issueSubjectFormGroup);
}
- var emailAddress = $(this).find("input[name='email']").val();
- if (emailAddress && !IsValidEmail(emailAddress)) {
- highlightInvalidField($emailFormGroup);
+ let emailAddress = $(this).find("input[name='email']").val();
+ if (emailAddress && !self.isValidEmail(emailAddress)) {
+ self.highlightInvalidField(self.$emailFormGroup);
return false;
}
- var emailAddresses = $(this).find("input[name='cc']").val();
+ let emailAddresses = $(this).find("input[name='cc']").val();
emailAddresses = emailAddresses.replace(/ /g, "").split(",");
- for (var index in emailAddresses) {
- var email = emailAddresses[index];
- if (email && !IsValidEmail(email)) {
- highlightInvalidField($ccFormGroup);
+ for (let index in emailAddresses) {
+ let email = emailAddresses[index];
+ if (email && !self.isValidEmail(email)) {
+ self.highlightInvalidField(self.$ccFormGroup);
return false;
}
}
@@ -51,57 +60,61 @@ hqDefine('hqwebapp/js/bootstrap5/hq-bug-report', [
return false;
}
- if (!isBugReportSubmitting && $hqwebappBugReportSubmit.text() === $hqwebappBugReportSubmit.data("success-text")) {
- $hqwebappBugReportModal.modal("hide");
- } else if (!isBugReportSubmitting) {
- $hqwebappBugReportCancel.disableButtonNoSpinner();
- $hqwebappBugReportSubmit.button('loading');
+ if (!self.isBugReportSubmitting && self.$hqwebappBugReportSubmit.text() ===
+ self.$hqwebappBugReportSubmit.data("success-text")) {
+ self.bugReportModal.hide();
+ } else if (!self.isBugReportSubmitting) {
+ self.$hqwebappBugReportCancel.disableButtonNoSpinner();
+ self.$hqwebappBugReportSubmit.changeButtonState('loading');
$(this).ajaxSubmit({
type: "POST",
url: $(this).attr('action'),
- beforeSerialize: hqwebappBugReportBeforeSerialize,
- beforeSubmit: hqwebappBugReportBeforeSubmit,
- success: hqwebappBugReportSucccess,
- error: hqwebappBugReportError,
+ beforeSerialize: self.hqwebappBugReportBeforeSerialize,
+ beforeSubmit: self.hqwebappBugReportBeforeSubmit,
+ success: self.hqwebappBugReportSuccess,
+ error: self.hqwebappBugReportError,
});
}
return false;
});
- function IsValidEmail(email) {
- var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
+ self.isValidEmail = function (email) {
+ let regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
return regex.test(email);
- }
+ };
- function hqwebappBugReportBeforeSerialize($form) {
+ self.hqwebappBugReportBeforeSerialize = function ($form) {
$form.find("#bug-report-url").val(location.href);
- }
+ };
- function hqwebappBugReportBeforeSubmit() {
- isBugReportSubmitting = true;
- }
+ self.hqwebappBugReportBeforeSubmit = function () {
+ self.isBugReportSubmitting = true;
+ };
- function hqwebappBugReportSucccess() {
- isBugReportSubmitting = false;
- $hqwebappBugReportForm.find("button[type='submit']").button('success').removeClass('btn-danger').addClass('btn-primary');
- $hqwebappBugReportModal.one('hidden.bs.modal', function () {
- resetForm();
+ self.hqwebappBugReportSuccess = function () {
+ self.isBugReportSubmitting = false;
+ self.$bugReportModalElement.one('hidden.bs.modal', function () {
+ self.resetForm();
});
- }
+ self.$hqwebappBugReportForm.find("button[type='submit']")
+ .changeButtonState('success')
+ .removeClass('btn-danger').addClass('btn-primary');
+ };
- function hqwebappBugReportError() {
- isBugReportSubmitting = false;
- $hqwebappBugReportForm.find("button[type='submit']").button('error').removeClass('btn-primary').addClass('btn-danger');
- $hqwebappBugReportCancel.enableButton();
- }
+ self.hqwebappBugReportError = function () {
+ self.isBugReportSubmitting = false;
+ self.$hqwebappBugReportForm.find("button[type='submit']").changeButtonState('error')
+ .removeClass('btn-primary').addClass('btn-danger');
+ self.$hqwebappBugReportCancel.enableButton();
+ };
- function highlightInvalidField($element) {
+ self.highlightInvalidField = function ($element) {
$element.addClass('has-error has-feedback');
$element.find(".label-danger").removeClass('hide');
$element.find("input").focus(function () {
$element.removeClass("has-error has-feedback");
$element.find(".label-danger").addClass('hide');
});
- }
+ };
});
});
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq.helpers.js b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq.helpers.js
index c5efcee20af2..245af1df0ce8 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq.helpers.js
+++ b/corehq/apps/hqwebapp/static/hqwebapp/js/bootstrap5/hq.helpers.js
@@ -59,19 +59,6 @@ hqDefine("hqwebapp/js/bootstrap5/hq.helpers", [
return false; // let default handler run
};
- var oldHide = $.fn.popover.Constructor.prototype.hide;
-
- $.fn.popover.Constructor.prototype.hide = function () {
- if (this.options.trigger === "hover" && this.tip().is(":hover")) {
- var that = this;
- setTimeout(function () {
- return that.hide.apply(that, arguments);
- }, that.options.delay.hide);
- return;
- }
- oldHide.apply(this, arguments);
- };
-
$.fn.hqHelp = function () {
var self = this;
self.each(function (i) {
@@ -103,6 +90,11 @@ hqDefine("hqwebapp/js/bootstrap5/hq.helpers", [
});
};
+ $.fn.changeButtonState = function (state) {
+ $(this).text($(this).data(state + '-text'));
+ return this;
+ };
+
$.fn.addSpinnerToButton = function () {
$(this).find("i").addClass("hide");
$(this).prepend(' ');
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/js/hqModules.js b/corehq/apps/hqwebapp/static/hqwebapp/js/hqModules.js
index b918a6e1bbb2..ce45af74f2d7 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/js/hqModules.js
+++ b/corehq/apps/hqwebapp/static/hqwebapp/js/hqModules.js
@@ -69,6 +69,9 @@ function hqDefine(path, dependencies, moduleAccessor) {
'hqwebapp/js/lib/modernizr': 'Modernizr',
'sinon/pkg/sinon': 'sinon',
};
+ if (window.USE_BOOTSTRAP5) {
+ thirdPartyGlobals['hqwebapp/js/bootstrap5_loader'] = 'bootstrap';
+ }
var args = [];
for (var i = 0; i < dependencies.length; i++) {
var dependency = dependencies[i];
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq.scss
index b2917bf269c2..e10e55aa5819 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq.scss
@@ -3,6 +3,7 @@
@import "functions";
@import "commcarehq/variables"; // This comes before Bootstrap 5 variables to override the defaults
@import "variables";
+@import "variables-dark";
@import "commcarehq/variables_bootstrap3"; // Variables specific to B3-era Stylesheet
@import "maps";
@import "mixins";
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_containers.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_containers.scss
index 590f2710cfe6..af4272472f0f 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_containers.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_containers.scss
@@ -1,3 +1,7 @@
+html, body {
+ height: 100%;
+}
+
.hq-container {
min-height: 100%;
height: auto !important;
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_dropdown.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_dropdown.scss
index 2a731ff34179..3f88bd53d541 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_dropdown.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_dropdown.scss
@@ -24,7 +24,7 @@
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
- border-left-color: darken($dropdown-bg, 20%);
+ border-left-color: darken($body-bg, 20%);
margin-right: -5px;
margin-top: 3.3px;
color: $dropdown-link-color;
@@ -72,14 +72,19 @@
margin-top: 5px;
}
- .dropdown-menu .dropdown-divider {
- margin-top: 0px;
- margin-bottom: 0px;
+ .navbar-nav > li > a.dropdown-toggle-with-icon {
+ padding-top: 22px !important;
+ padding-bottom: 17px !important;
}
.nav-settings-bar .dropdown-toggle-with-icon.nav-link::after {
display: none;
}
+
+ .dropdown-toggle::after {
+ vertical-align: 2.48px;
+ margin-left: 2px;
+ }
}
@media (max-width: map-get($grid-breakpoints, "lg")) {
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_nav.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_nav.scss
index 8365af7fad40..ee48ecfccf07 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_nav.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_nav.scss
@@ -54,6 +54,7 @@
.nav-main-icon {
font-size: 1.7em;
line-height: 0.7em;
+ color: $gray-light;
}
.text-hq-nav-header {
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_navbar.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_navbar.scss
index 9ab13848b2c2..66f0da7d7297 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_navbar.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_navbar.scss
@@ -6,9 +6,12 @@
min-height: $navbar-height;
.navbar-brand {
+ padding-top: 11px;
line-height: 17px;
- height: $navbar-height - 4px;
+ height: $navbar-height - 6px;
display: inline-block;
+ margin-left: -1px;
+ margin-right: 3px;
// Standard HQ logo
// Custom domain logos use an actual image
@@ -30,8 +33,9 @@
}
&.navbar-expand-lg .navbar-nav .nav-link {
- padding: 21px 15px;
+ padding: 21px 15px 20px;
line-height: 19.5px;
+ color: $gray-light;
}
&.navbar-expand-lg .navbar-nav li:not(.active) > .nav-link:focus,
@@ -64,6 +68,7 @@
.nav-settings-bar {
margin-left: auto;
order: 2;
+ padding-right: 8px;
}
@media(max-width: 1057px) {
@@ -131,7 +136,7 @@
.dimagi-logo svg {
height: 22px;
width: 50px;
- top: 3px;
+ top: 2px;
position: relative;
display: inline-block;
}
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_type.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_type.scss
index ecd1d6fbab2d..3e07104eeabc 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_type.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_type.scss
@@ -90,3 +90,10 @@ code {
a {
cursor: pointer;
}
+
+// we should eventually get rid of this as bootstrap5+ doesn't natively support
+.page-header {
+ padding-bottom: 7.5px;
+ margin: 34px 0 17px;
+ border-bottom: 1px solid #eeeeee;
+}
\ No newline at end of file
diff --git a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_variables.scss b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_variables.scss
index b92f181c310c..aa2607b71bf8 100644
--- a/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_variables.scss
+++ b/corehq/apps/hqwebapp/static/hqwebapp/scss/commcarehq/_variables.scss
@@ -1,3 +1,14 @@
+// Grid Containers
+// we will want to adapt the defaults in a full redesign
+$container-max-widths: (
+ sm: 540px,
+ md: 720px,
+ lg: 960px,
+ xl: 1140px,
+ xxl: 1160px
+);
+
+
// Typography Overrides
$font-family-sans-serif: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
$font-size-base: .75rem; // approx 12px
diff --git a/corehq/apps/hqwebapp/templates/hqwebapp/base.html b/corehq/apps/hqwebapp/templates/hqwebapp/base.html
index 069734eef272..663e8d346d56 100644
--- a/corehq/apps/hqwebapp/templates/hqwebapp/base.html
+++ b/corehq/apps/hqwebapp/templates/hqwebapp/base.html
@@ -184,7 +184,11 @@
{% block modals %}{% endblock %}
{% if show_mobile_ux_warning %}
- {% include "hqwebapp/partials/bootstrap3/mobile_ux_warning.html" %}
+ {% if use_bootstrap5 %}
+ {% include "hqwebapp/partials/bootstrap5/mobile_ux_warning.html" %}
+ {% else %}
+ {% include "hqwebapp/partials/bootstrap3/mobile_ux_warning.html" %}
+ {% endif %}
{% endif %}
{# Report Issue #}
@@ -208,7 +212,11 @@
{% if EULA_COMPLIANCE %}
{% if request.couch_user and not request.couch_user.is_eula_signed %}
{% registerurl 'agree_to_eula' %}
- {% include 'hqwebapp/includes/bootstrap3/modal_eula.html' %}
+ {% if use_bootstrap5 %}
+ {% include 'hqwebapp/includes/bootstrap5/modal_eula.html' %}
+ {% else %}
+ {% include 'hqwebapp/includes/bootstrap3/modal_eula.html' %}
+ {% endif %}
{% endif %}
{% endif %}
@@ -219,7 +227,11 @@
{% registerurl 'submit_hubspot_cta_form' %}
{# 30 Day Trial #}
- {% include 'hqwebapp/includes/bootstrap3/modal_30_day_trial.html' %}
+ {% if use_bootstrap5 %}
+ {% include 'hqwebapp/includes/bootstrap5/modal_30_day_trial.html' %}
+ {% else %}
+ {% include 'hqwebapp/includes/bootstrap3/modal_30_day_trial.html' %}
+ {% endif %}
{% block additional_initial_page_data %}
{% comment %}
@@ -281,26 +293,35 @@
{# javascript below this line #}
- {% if use_bootstrap5 %}
-
- {% else %}
- {% include "hqwebapp/partials/requirejs.html" with BASE_MAIN=True %}
- {% endif %}
+ {% include "hqwebapp/partials/requirejs.html" with BASE_MAIN=True %}
{# DO NOT COMPRESS #}
{# HQ Specific Libraries #}
{% if not requirejs_main %}
- {% compress js %}
-
-
-
-
-
-
-
-
- {% endcompress %}
+ {% if use_bootstrap5 %}
+ {% compress js %}
+
+
+
+
+
+
+
+
+ {% endcompress %}
+ {% else %}
+ {% compress js %}
+
+
+
+
+
+
+
+
+ {% endcompress %}
+ {% endif %}
{% endif %}
{# JavaScript Display Logic Libaries #}
@@ -387,22 +408,42 @@
{% endif %}
{% if is_demo_visible %}
- {% include "hqwebapp/partials/bootstrap3/get_demo_modals.html" %}
+ {% if use_bootstrap5 %}
+ {% include "hqwebapp/partials/bootstrap5/get_demo_modals.html" %}
+ {% else %}
+ {% include "hqwebapp/partials/bootstrap3/get_demo_modals.html" %}
+ {% endif %}
{% endif %}
{# Knockout component templates #}
- {% include 'hqwebapp/partials/bootstrap3/ko_pagination.html' %}
- {% include 'hqwebapp/partials/bootstrap3/ko_inline_edit.html' %}
- {% include 'hqwebapp/partials/bootstrap3/ko_search_box.html' %}
- {% include 'hqwebapp/partials/bootstrap3/ko_select_toggle.html' %}
- {% include 'hqwebapp/partials/bootstrap3/ko_feedback.html' %}
+ {% if use_bootstrap5 %}
+ {% include 'hqwebapp/partials/bootstrap5/ko_pagination.html' %}
+ {% include 'hqwebapp/partials/bootstrap5/ko_inline_edit.html' %}
+ {% include 'hqwebapp/partials/bootstrap5/ko_search_box.html' %}
+ {% include 'hqwebapp/partials/bootstrap5/ko_select_toggle.html' %}
+ {% include 'hqwebapp/partials/bootstrap5/ko_feedback.html' %}
+ {% else %}
+ {% include 'hqwebapp/partials/bootstrap3/ko_pagination.html' %}
+ {% include 'hqwebapp/partials/bootstrap3/ko_inline_edit.html' %}
+ {% include 'hqwebapp/partials/bootstrap3/ko_search_box.html' %}
+ {% include 'hqwebapp/partials/bootstrap3/ko_select_toggle.html' %}
+ {% include 'hqwebapp/partials/bootstrap3/ko_feedback.html' %}
+ {% endif %}
{% if show_overdue_invoice_modal and not requirejs_main %}
-
+ {% if use_bootstrap5 %}
+
+ {% else %}
+
+ {% endif %}
{% endif %}
{% if show_prepaid_modal and not requirejs_main %}
-
+ {% if use_bootstrap5 %}
+
+ {% else %}
+
+ {% endif %}
{% endif %}
{% if show_status_page %}
diff --git a/corehq/apps/hqwebapp/templates/hqwebapp/includes/core_libraries.html b/corehq/apps/hqwebapp/templates/hqwebapp/includes/core_libraries.html
index 3660ddb7f883..3fe88adccc5f 100644
--- a/corehq/apps/hqwebapp/templates/hqwebapp/includes/core_libraries.html
+++ b/corehq/apps/hqwebapp/templates/hqwebapp/includes/core_libraries.html
@@ -68,7 +68,7 @@
otherwise the two tooltip widgets and two button widgets conflict.
{% endcomment %}
{% if use_bootstrap5 %}
-
+
{% else %}
{% endif %}
@@ -103,29 +103,48 @@
{# already minified #}
{% if hq %}
+ {% if use_bootstrap5 %}
{% compress js %}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
{% endcompress %}
+ {% else %}
+ {% compress js %}
+
+
+
+
+
+
+
+
+
+ {% endcompress %}
+ {% endif %}
{% endif %}
{% endif %}
{% if hq %}
- {% if use_bootstrap5 %}
+ {% if use_bootstrap5 %}
+ {% compress js %}
- {% else %}
-
- {% endif %}
+
+
+
+ {% endcompress %}
+ {% else %}
{% compress js %}
+
{% endcompress %}
+ {% endif %}
{% endif %}
diff --git a/corehq/apps/hqwebapp/templatetags/tests/rendered/javascript_libraries_hq_bootstrap5.html b/corehq/apps/hqwebapp/templatetags/tests/rendered/javascript_libraries_hq_bootstrap5.html
index 27c9e69e8fb2..af54c8c15cee 100644
--- a/corehq/apps/hqwebapp/templatetags/tests/rendered/javascript_libraries_hq_bootstrap5.html
+++ b/corehq/apps/hqwebapp/templatetags/tests/rendered/javascript_libraries_hq_bootstrap5.html
@@ -8,7 +8,7 @@
-
+
@@ -27,16 +27,16 @@
-
+
-
-
+
+
-
-
+
+
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/alert_user.js.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/alert_user.js.diff.txt
index 564ea8a604fb..522b85780c7b 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/alert_user.js.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/alert_user.js.diff.txt
@@ -1,6 +1,6 @@
---
+++
-@@ -13,7 +13,7 @@
+@@ -13,10 +13,10 @@
(success < info < warning < danger).
fadeOut: Set to 'true' to have the message automatically removed from the UI after 5s.
*/
@@ -8,4 +8,8 @@
+hqDefine("hqwebapp/js/bootstrap5/alert_user", [
"jquery",
"knockout",
- "hqwebapp/js/bootstrap3/hq.helpers",
+- "hqwebapp/js/bootstrap3/hq.helpers",
++ "hqwebapp/js/bootstrap5/hq.helpers",
+ ],
+ function (
+ $,
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq-bug-report.js.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq-bug-report.js.diff.txt
index c31613200580..1754533dd38c 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq-bug-report.js.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq-bug-report.js.diff.txt
@@ -1,10 +1,185 @@
---
+++
-@@ -1,5 +1,5 @@
+@@ -1,49 +1,58 @@
-hqDefine('hqwebapp/js/bootstrap3/hq-bug-report', [
- "jquery", "jquery-form/dist/jquery.form.min", "hqwebapp/js/bootstrap3/hq.helpers",
+-], function ($) {
+hqDefine('hqwebapp/js/bootstrap5/hq-bug-report', [
-+ "jquery", "jquery-form/dist/jquery.form.min", "hqwebapp/js/bootstrap5/hq.helpers",
- ], function ($) {
++ "jquery",
++ "hqwebapp/js/bootstrap5_loader",
++ "jquery-form/dist/jquery.form.min",
++ "hqwebapp/js/bootstrap5/hq.helpers",
++], function ($, bootstrap) {
++ 'use strict';
$(function () {
- var $hqwebappBugReportModal = $('#modalReportIssue'),
+- var $hqwebappBugReportModal = $('#modalReportIssue'),
+- $hqwebappBugReportForm = $('#hqwebapp-bugReportForm'),
+- $hqwebappBugReportSubmit = $('#bug-report-submit'),
+- $hqwebappBugReportCancel = $('#bug-report-cancel'),
+- $ccFormGroup = $("#bug-report-cc-form-group"),
+- $emailFormGroup = $("#bug-report-email-form-group"),
+- $issueSubjectFormGroup = $("#bug-report-subject-form-group"),
+- isBugReportSubmitting = false;
++ let self = {};
+
+- var resetForm = function () {
+- $hqwebappBugReportForm.find("button[type='submit']").button('reset');
+- $hqwebappBugReportForm.resetForm();
+- $hqwebappBugReportCancel.enableButton();
+- $hqwebappBugReportSubmit.button('reset');
+- $ccFormGroup.removeClass('has-error has-feedback');
+- $ccFormGroup.find(".label-danger").addClass('hide');
+- $emailFormGroup.removeClass('has-error has-feedback');
+- $emailFormGroup.find(".label-danger").addClass('hide');
++ self.$bugReportModalElement = $('#modalReportIssue');
++ self.bugReportModal = new bootstrap.Modal(self.$bugReportModalElement);
++ self.$hqwebappBugReportForm = $('#hqwebapp-bugReportForm');
++ self.$hqwebappBugReportSubmit = $('#bug-report-submit');
++ self.$hqwebappBugReportCancel = $('#bug-report-cancel');
++ self.$ccFormGroup = $("#bug-report-cc-form-group");
++ self.$emailFormGroup = $("#bug-report-email-form-group");
++ self.$issueSubjectFormGroup = $("#bug-report-subject-form-group");
++ self.isBugReportSubmitting = false;
++
++ self.resetForm = function () {
++ self.$hqwebappBugReportForm.find("button[type='submit']").changeButtonState('reset');
++ self.$hqwebappBugReportForm.resetForm();
++ self.$hqwebappBugReportCancel.enableButton();
++ self.$hqwebappBugReportSubmit.changeButtonState('reset');
++ self.$ccFormGroup.removeClass('has-error has-feedback');
++ self.$ccFormGroup.find(".label-danger").addClass('hide');
++ self.$emailFormGroup.removeClass('has-error has-feedback');
++ self.$emailFormGroup.find(".label-danger").addClass('hide');
+ };
+
+- $hqwebappBugReportModal.on('shown.bs.modal', function () {
++ self.$bugReportModalElement.on('shown.bs.modal', function () {
+ $("input#bug-report-subject").focus();
+ });
+
+- $hqwebappBugReportForm.submit(function () {
+- var isDescriptionEmpty = !$("#bug-report-subject").val() && !$("#bug-report-message").val();
++ self.$hqwebappBugReportForm.submit(function (e) {
++ e.preventDefault();
++
++ let isDescriptionEmpty = !$("#bug-report-subject").val() && !$("#bug-report-message").val();
+ if (isDescriptionEmpty) {
+- highlightInvalidField($issueSubjectFormGroup);
++ self.highlightInvalidField(self.$issueSubjectFormGroup);
+ }
+
+- var emailAddress = $(this).find("input[name='email']").val();
+- if (emailAddress && !IsValidEmail(emailAddress)) {
+- highlightInvalidField($emailFormGroup);
++ let emailAddress = $(this).find("input[name='email']").val();
++ if (emailAddress && !self.isValidEmail(emailAddress)) {
++ self.highlightInvalidField(self.$emailFormGroup);
+ return false;
+ }
+
+- var emailAddresses = $(this).find("input[name='cc']").val();
++ let emailAddresses = $(this).find("input[name='cc']").val();
+ emailAddresses = emailAddresses.replace(/ /g, "").split(",");
+- for (var index in emailAddresses) {
+- var email = emailAddresses[index];
+- if (email && !IsValidEmail(email)) {
+- highlightInvalidField($ccFormGroup);
++ for (let index in emailAddresses) {
++ let email = emailAddresses[index];
++ if (email && !self.isValidEmail(email)) {
++ self.highlightInvalidField(self.$ccFormGroup);
+ return false;
+ }
+ }
+@@ -51,57 +60,61 @@
+ return false;
+ }
+
+- if (!isBugReportSubmitting && $hqwebappBugReportSubmit.text() === $hqwebappBugReportSubmit.data("success-text")) {
+- $hqwebappBugReportModal.modal("hide");
+- } else if (!isBugReportSubmitting) {
+- $hqwebappBugReportCancel.disableButtonNoSpinner();
+- $hqwebappBugReportSubmit.button('loading');
++ if (!self.isBugReportSubmitting && self.$hqwebappBugReportSubmit.text() ===
++ self.$hqwebappBugReportSubmit.data("success-text")) {
++ self.bugReportModal.hide();
++ } else if (!self.isBugReportSubmitting) {
++ self.$hqwebappBugReportCancel.disableButtonNoSpinner();
++ self.$hqwebappBugReportSubmit.changeButtonState('loading');
+ $(this).ajaxSubmit({
+ type: "POST",
+ url: $(this).attr('action'),
+- beforeSerialize: hqwebappBugReportBeforeSerialize,
+- beforeSubmit: hqwebappBugReportBeforeSubmit,
+- success: hqwebappBugReportSucccess,
+- error: hqwebappBugReportError,
++ beforeSerialize: self.hqwebappBugReportBeforeSerialize,
++ beforeSubmit: self.hqwebappBugReportBeforeSubmit,
++ success: self.hqwebappBugReportSuccess,
++ error: self.hqwebappBugReportError,
+ });
+ }
+ return false;
+ });
+
+- function IsValidEmail(email) {
+- var regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
++ self.isValidEmail = function (email) {
++ let regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
+ return regex.test(email);
+- }
++ };
+
+- function hqwebappBugReportBeforeSerialize($form) {
++ self.hqwebappBugReportBeforeSerialize = function ($form) {
+ $form.find("#bug-report-url").val(location.href);
+- }
++ };
+
+- function hqwebappBugReportBeforeSubmit() {
+- isBugReportSubmitting = true;
+- }
++ self.hqwebappBugReportBeforeSubmit = function () {
++ self.isBugReportSubmitting = true;
++ };
+
+- function hqwebappBugReportSucccess() {
+- isBugReportSubmitting = false;
+- $hqwebappBugReportForm.find("button[type='submit']").button('success').removeClass('btn-danger').addClass('btn-primary');
+- $hqwebappBugReportModal.one('hidden.bs.modal', function () {
+- resetForm();
++ self.hqwebappBugReportSuccess = function () {
++ self.isBugReportSubmitting = false;
++ self.$bugReportModalElement.one('hidden.bs.modal', function () {
++ self.resetForm();
+ });
+- }
++ self.$hqwebappBugReportForm.find("button[type='submit']")
++ .changeButtonState('success')
++ .removeClass('btn-danger').addClass('btn-primary');
++ };
+
+- function hqwebappBugReportError() {
+- isBugReportSubmitting = false;
+- $hqwebappBugReportForm.find("button[type='submit']").button('error').removeClass('btn-primary').addClass('btn-danger');
+- $hqwebappBugReportCancel.enableButton();
+- }
++ self.hqwebappBugReportError = function () {
++ self.isBugReportSubmitting = false;
++ self.$hqwebappBugReportForm.find("button[type='submit']").changeButtonState('error')
++ .removeClass('btn-primary').addClass('btn-danger');
++ self.$hqwebappBugReportCancel.enableButton();
++ };
+
+- function highlightInvalidField($element) {
++ self.highlightInvalidField = function ($element) {
+ $element.addClass('has-error has-feedback');
+ $element.find(".label-danger").removeClass('hide');
+ $element.find("input").focus(function () {
+ $element.removeClass("has-error has-feedback");
+ $element.find(".label-danger").addClass('hide');
+ });
+- }
++ };
+ });
+ });
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq.helpers.js.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq.helpers.js.diff.txt
index 28b7decbbf5d..709ba772458e 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq.helpers.js.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/javascript/hqwebapp/hq.helpers.js.diff.txt
@@ -6,3 +6,35 @@
'jquery',
'knockout',
'underscore',
+@@ -59,19 +59,6 @@
+ return false; // let default handler run
+ };
+
+- var oldHide = $.fn.popover.Constructor.prototype.hide;
+-
+- $.fn.popover.Constructor.prototype.hide = function () {
+- if (this.options.trigger === "hover" && this.tip().is(":hover")) {
+- var that = this;
+- setTimeout(function () {
+- return that.hide.apply(that, arguments);
+- }, that.options.delay.hide);
+- return;
+- }
+- oldHide.apply(this, arguments);
+- };
+-
+ $.fn.hqHelp = function () {
+ var self = this;
+ self.each(function (i) {
+@@ -101,6 +88,11 @@
+ event.preventDefault();
+ });
+ });
++ };
++
++ $.fn.changeButtonState = function (state) {
++ $(this).text($(this).data(state + '-text'));
++ return this;
+ };
+
+ $.fn.addSpinnerToButton = function () {
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/dropdowns._dropdown.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/dropdowns._dropdown.style.diff.txt
index de9c8d33f5a6..58a1f6dc6658 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/dropdowns._dropdown.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/dropdowns._dropdown.style.diff.txt
@@ -1,6 +1,6 @@
---
+++
-@@ -24,97 +24,69 @@
+@@ -24,97 +24,74 @@
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
@@ -9,7 +9,7 @@
- margin-top: 3px;
- color: @dropdown-link-color;
- line-height: @line-height-base;
-+ border-left-color: darken($dropdown-bg, 20%);
++ border-left-color: darken($body-bg, 20%);
+ margin-right: -5px;
+ margin-top: 3.3px;
+ color: $dropdown-link-color;
@@ -96,14 +96,19 @@
+ margin-top: 5px;
+ }
+
-+ .dropdown-menu .dropdown-divider {
-+ margin-top: 0px;
-+ margin-bottom: 0px;
++ .navbar-nav > li > a.dropdown-toggle-with-icon {
++ padding-top: 22px !important;
++ padding-bottom: 17px !important;
+ }
+
+ .nav-settings-bar .dropdown-toggle-with-icon.nav-link::after {
+ display: none;
+ }
++
++ .dropdown-toggle::after {
++ vertical-align: 2.48px;
++ margin-left: 2px;
++ }
+}
+
+@media (max-width: map-get($grid-breakpoints, "lg")) {
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/includes_variables._variables.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/includes_variables._variables.style.diff.txt
index 8ca48ddd6439..e5c1030bbe39 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/includes_variables._variables.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/includes_variables._variables.style.diff.txt
@@ -1,18 +1,29 @@
---
+++
-@@ -1,119 +1,111 @@
+@@ -1,119 +1,122 @@
-@import "@{b3-import-variables}";
-+// Typography Overrides
-+$font-family-sans-serif: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
-+$font-size-base: .75rem; // approx 12px
++// Grid Containers
++// we will want to adapt the defaults in a full redesign
++$container-max-widths: (
++ sm: 540px,
++ md: 720px,
++ lg: 960px,
++ xl: 1140px,
++ xxl: 1160px
++);
-// Nunito Sans is used on dimagi.com and embedded in hqwebapp/base.html
-@font-family-sans-serif: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
-+// Links
-+$link-decoration: none;
-@font-size-base: 12px;
-@icon-font-path: "../../bootstrap/fonts/";
++// Typography Overrides
++$font-family-sans-serif: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
++$font-size-base: .75rem; // approx 12px
++
++// Links
++$link-decoration: none;
++
+// Form Overrides
+$input-border-radius-lg: 5px;
+
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/layouts._containers.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/layouts._containers.style.diff.txt
index 955db4aff434..931797da4f89 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/layouts._containers.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/layouts._containers.style.diff.txt
@@ -1,10 +1,12 @@
---
+++
-@@ -1,32 +1,11 @@
+@@ -1,32 +1,15 @@
-body, html {
- height: 100%;
--}
--
++html, body {
++ height: 100%;
+ }
+
.hq-container {
min-height: 100%;
height: auto !important;
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/navs._nav.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/navs._nav.style.diff.txt
index e7d3dc762f45..befd5207acde 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/navs._nav.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/navs._nav.style.diff.txt
@@ -36,7 +36,15 @@
}
.nav-input {
padding: 3px 20px;
-@@ -68,7 +68,7 @@
+@@ -54,6 +54,7 @@
+ .nav-main-icon {
+ font-size: 1.7em;
+ line-height: 0.7em;
++ color: $gray-light;
+ }
+
+ .text-hq-nav-header {
+@@ -68,7 +69,7 @@
}
.nav > li > a {
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/typography._type.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/typography._type.style.diff.txt
index 18d3c742bfa4..011dab19e956 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/typography._type.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/imports/typography._type.style.diff.txt
@@ -28,3 +28,14 @@
}
.no-border {
+@@ -89,3 +90,10 @@
+ a {
+ cursor: pointer;
+ }
++
++// we should eventually get rid of this as bootstrap5+ doesn't natively support
++.page-header {
++ padding-bottom: 7.5px;
++ margin: 34px 0 17px;
++ border-bottom: 1px solid #eeeeee;
++}
\ No newline at end of file
diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/style-imports.commcarehq.style.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/style-imports.commcarehq.style.diff.txt
index 6b4ac2ab3b82..a6e9e037cb48 100644
--- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/style-imports.commcarehq.style.diff.txt
+++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/stylesheets/style-imports.commcarehq.style.diff.txt
@@ -1,6 +1,6 @@
---
+++
-@@ -1,43 +1,93 @@
+@@ -1,43 +1,94 @@
-@import "_hq/includes/variables.less";
-@import "_hq/includes/mixins.less";
@@ -48,6 +48,7 @@
+@import "functions";
+@import "commcarehq/variables"; // This comes before Bootstrap 5 variables to override the defaults
+@import "variables";
++@import "variables-dark";
+@import "commcarehq/variables_bootstrap3"; // Variables specific to B3-era Stylesheet
+@import "maps";
+@import "mixins";
diff --git a/corehq/apps/hqwebapp/tests/utils/test_bootstrap_changes.py b/corehq/apps/hqwebapp/tests/utils/test_bootstrap_changes.py
index 1eac08a7cfa5..6eb781272804 100644
--- a/corehq/apps/hqwebapp/tests/utils/test_bootstrap_changes.py
+++ b/corehq/apps/hqwebapp/tests/utils/test_bootstrap_changes.py
@@ -64,12 +64,16 @@ def test_flag_changed_javascript_plugins_bootstrap5():
flags = flag_changed_javascript_plugins(
line, get_spec('bootstrap_3_to_5')
)
- eq(flags, ['The `modal` plugin has been restructured since the removal of jQuery.\n\n'
- 'There is now a new way of triggering modal events and interacting with '
- 'modals in javascript.\n\nPlease feel free to update this help text as '
- 'you find common replacements/restructuring\nfor our usage of this plugin. '
- 'Thanks!\n\nOld docs: https://getbootstrap.com/docs/3.4/javascript/#modals\n'
- 'New docs: https://getbootstrap.com/docs/5.3/components/modal/#via-javascript\n'])
+ eq(flags, ["The `modal` plugin has been restructured since the removal of jQuery.\n\n"
+ "There is now a new way of triggering modal events and interacting with "
+ "modals in javascript.\nFor instance, if we wanted to hide a modal with "
+ "id `#bugReport` before, we would now do the\nfollowing...\n\npreviously"
+ "\n```\n$('#bugReport').modal('hide');\n```\n\nnow\n```\nconst bugReportModal"
+ " = new bootstrap.Modal($('#bugReport'));\nbugReportModal.hide();\n```\n\n"
+ "Hint: make sure to list `hqwebapp/js/bootstrap5_loader` as a js dependency "
+ "in the file where\nbootstrap is referenced.\n\nOld docs: "
+ "https://getbootstrap.com/docs/3.4/javascript/#modals\nNew docs: "
+ "https://getbootstrap.com/docs/5.3/components/modal/#via-javascript\n"])
def test_flag_extended_changed_javascript_plugins_bootstrap5():
diff --git a/corehq/apps/hqwebapp/utils/bootstrap/changes_guide/js-modal.txt b/corehq/apps/hqwebapp/utils/bootstrap/changes_guide/js-modal.txt
index cec01970d492..cc70e7ef4402 100644
--- a/corehq/apps/hqwebapp/utils/bootstrap/changes_guide/js-modal.txt
+++ b/corehq/apps/hqwebapp/utils/bootstrap/changes_guide/js-modal.txt
@@ -1,9 +1,22 @@
The `modal` plugin has been restructured since the removal of jQuery.
There is now a new way of triggering modal events and interacting with modals in javascript.
+For instance, if we wanted to hide a modal with id `#bugReport` before, we would now do the
+following...
-Please feel free to update this help text as you find common replacements/restructuring
-for our usage of this plugin. Thanks!
+previously
+```
+$('#bugReport').modal('hide');
+```
+
+now
+```
+const bugReportModal = new bootstrap.Modal($('#bugReport'));
+bugReportModal.hide();
+```
+
+Hint: make sure to list `hqwebapp/js/bootstrap5_loader` as a js dependency in the file where
+bootstrap is referenced.
Old docs: https://getbootstrap.com/docs/3.4/javascript/#modals
New docs: https://getbootstrap.com/docs/5.3/components/modal/#via-javascript
diff --git a/corehq/apps/hqwebapp/views.py b/corehq/apps/hqwebapp/views.py
index c7b980972f2c..b2ad3becb4b2 100644
--- a/corehq/apps/hqwebapp/views.py
+++ b/corehq/apps/hqwebapp/views.py
@@ -76,7 +76,7 @@
DEPLOY_IN_PROGRESS_FLAG,
)
from corehq.apps.hqadmin.service_checks import CHECKS, run_checks
-from corehq.apps.hqwebapp.decorators import waf_allow
+from corehq.apps.hqwebapp.decorators import waf_allow, use_bootstrap5
from corehq.apps.hqwebapp.doc_info import get_doc_info
from corehq.apps.hqwebapp.doc_lookup import lookup_doc_id
from corehq.apps.hqwebapp.encoders import LazyEncoder
@@ -89,6 +89,7 @@
from corehq.apps.hqwebapp.models import HQOauthApplication
from corehq.apps.hqwebapp.login_utils import get_custom_login_page
from corehq.apps.hqwebapp.utils import get_environment_friendly_name
+from corehq.apps.hqwebapp.utils.bootstrap import get_bootstrap_version
from corehq.apps.locations.permissions import location_safe
from corehq.apps.sms.event_handlers import handle_email_messaging_subevent
from corehq.apps.users.event_handlers import handle_email_invite_message
@@ -841,14 +842,16 @@ def render_static(request, template, page_name):
"""
Takes an html file and renders it Commcare HQ's styling
"""
- return render(request, "hqwebapp/bootstrap3/blank.html",
+ return render(request, f"hqwebapp/{get_bootstrap_version()}/blank.html",
{'tmpl': template, 'page_name': page_name})
+@use_bootstrap5
def apache_license(request):
return render_static(request, "apache_license.html", _("Apache License"))
+@use_bootstrap5
def bsd_license(request):
return render_static(request, "bsd_license.html", _("BSD License"))
diff --git a/package.json b/package.json
index df71416248b0..1a84fdc62d12 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"bootstrap-switch": "3.3.2",
"bootstrap-timepicker": "0.5.1",
"bootstrap3-typeahead": "bassjobsen/Bootstrap-3-Typeahead#~3.1.1",
- "bootstrap5": "npm:bootstrap@5.2.3",
+ "bootstrap5": "npm:bootstrap@5.3.1",
"calendars": "kbwood/calendars#2.1.2",
"clipboard": "1.5.15",
"crypto-js": "4.0.0",
diff --git a/yarn.lock b/yarn.lock
index 3e17d7f9fe63..e3a38d7ece17 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -806,10 +806,10 @@ bootstrap3-typeahead@bassjobsen/Bootstrap-3-Typeahead#~3.1.1:
version "3.1.1"
resolved "https://codeload.github.com/bassjobsen/Bootstrap-3-Typeahead/tar.gz/c65c829fe8411f6eadb88415d09c1e85bb4603d0"
-"bootstrap5@npm:bootstrap@5.2.3":
- version "5.2.3"
- resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.3.tgz#54739f4414de121b9785c5da3c87b37ff008322b"
- integrity sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==
+"bootstrap5@npm:bootstrap@5.3.1":
+ version "5.3.1"
+ resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.1.tgz#8ca07040ad15d7f75891d1504cf14c5dedfb1cfe"
+ integrity sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==
bootstrap@3.4.1, bootstrap@^3.3:
version "3.4.1"
@@ -5725,7 +5725,7 @@ wide-align@^1.1.5:
dependencies:
string-width "^1.0.2 || 2 || 3 || 4"
-word-wrap@^1.2.3, "word-wrap@npm:@aashutoshrathi/word-wrap@1.2.5", word-wrap@~1.2.3:
+word-wrap@^1.2.3, word-wrap@~1.2.3:
version "1.2.5"
resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.5.tgz#383aeebd5c176c320d6364fb869669559bbdbac9"
integrity sha512-plhoNEfSVdHMKXQyAxvH0Zyv3/4NL8r6pwgMQdmHR2vBUXn2t74PN2pBRppqKUa6RMT0yldyvOHG5Dbjwy2mBQ==