(
<>
@@ -27,12 +28,16 @@ export const NotFound = () => (
>
);
-const NotFoundPage = () => (
-
-
-
-
-
-);
+const NotFoundPage = () => {
+ const { minHeight } = useContext(GlobalContext);
+
+ return (
+
+
+
+
+
+ );
+};
export default NotFoundPage;
diff --git a/src/components/learner-credit-management/tests/BudgetDetailPage.test.jsx b/src/components/learner-credit-management/tests/BudgetDetailPage.test.jsx
index b549dc9546..b3b1cc86b7 100644
--- a/src/components/learner-credit-management/tests/BudgetDetailPage.test.jsx
+++ b/src/components/learner-credit-management/tests/BudgetDetailPage.test.jsx
@@ -47,6 +47,7 @@ import {
mockSubsidySummary,
} from '../data/tests/constants';
import { getButtonElement, queryClient } from '../../test/testUtils';
+import { GlobalContext } from '../../GlobalContextProvider';
jest.mock('@edx/frontend-enterprise-utils', () => ({
...jest.requireActual('@edx/frontend-enterprise-utils'),
@@ -190,6 +191,16 @@ const defaultEnterpriseSubsidiesContextValue = {
isLoading: false,
};
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
+
const BudgetDetailPageWrapper = ({
initialState = initialStoreState,
enterpriseSubsidiesContextValue = defaultEnterpriseSubsidiesContextValue,
@@ -200,9 +211,11 @@ const BudgetDetailPageWrapper = ({
-
-
-
+
+
+
+
+
diff --git a/src/components/settings/tests/SettingsPage.test.jsx b/src/components/settings/tests/SettingsPage.test.jsx
index fb1b20cd14..d89ec1dc07 100644
--- a/src/components/settings/tests/SettingsPage.test.jsx
+++ b/src/components/settings/tests/SettingsPage.test.jsx
@@ -9,9 +9,20 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
import { MemoryRouter, Route, Routes } from 'react-router-dom';
import SettingsPage from '../index';
+import { GlobalContext } from '../../GlobalContextProvider';
jest.mock('../SettingsTabs');
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
+
const mockStore = configureMockStore();
const store = mockStore({
portalConfiguration: {
@@ -26,9 +37,11 @@ const settingsPageWithRouter = (route) => (
-
- } />
-
+
+
+ } />
+
+
diff --git a/src/components/subscriptions/tests/SubscriptionTabs.test.jsx b/src/components/subscriptions/tests/SubscriptionTabs.test.jsx
index 8ec2d48444..c8455c848e 100644
--- a/src/components/subscriptions/tests/SubscriptionTabs.test.jsx
+++ b/src/components/subscriptions/tests/SubscriptionTabs.test.jsx
@@ -19,6 +19,7 @@ import {
MANAGE_REQUESTS_TAB,
SUBSCRIPTION_TABS_LABELS,
} from '../data/constants';
+import { GlobalContext } from '../../GlobalContextProvider';
const MANAGE_LEARNERS_MOCK_CONTENT = 'learners';
const MANAGE_REQUESTS_MOCK_CONTENT = 'requests';
@@ -37,6 +38,16 @@ jest.mock(
},
);
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
+
const enterpriseId = 'test-enterprise';
const enterpriseSlug = 'sluggy';
const initialStore = {
@@ -63,16 +74,18 @@ const SubscriptionTabsWrapper = ({
-
-
-
-
- )}
- />
-
+
+
+
+
+
+ )}
+ />
+
+
diff --git a/src/containers/EnterpriseApp/EnterpriseApp.test.jsx b/src/containers/EnterpriseApp/EnterpriseApp.test.jsx
index c35796714a..054823bc23 100644
--- a/src/containers/EnterpriseApp/EnterpriseApp.test.jsx
+++ b/src/containers/EnterpriseApp/EnterpriseApp.test.jsx
@@ -20,6 +20,7 @@ import { features } from '../../config';
import NotFoundPage from '../../components/NotFoundPage';
import { EnterpriseSubsidiesContext } from '../../components/EnterpriseSubsidiesContext';
import { EnterpriseAppContext } from '../../components/EnterpriseApp/EnterpriseAppContextProvider';
+import { GlobalContext } from '../../components/GlobalContextProvider';
const defaultEnterpriseAppContextValue = {
enterpriseCuration: {
@@ -71,6 +72,16 @@ getAuthenticatedUser.mockReturnValue({
username: 'foo',
});
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
+
const mockStore = configureMockStore([thunk]);
const initialState = {
@@ -78,7 +89,7 @@ const initialState = {
portalConfiguration: {
enterpriseId: 'test-enterprise-id',
enterpriseSlug: 'test-enterprise-slug',
- enterpriseName: 'test-enterpris',
+ enterpriseName: 'test-enterprise',
enableCodeManagementScreen: true,
enableSubscriptionManagementScreen: true,
enableAnalyticsScreen: true,
@@ -99,12 +110,14 @@ const EnterpriseAppWrapper = ({ store, initialEntries, ...props }) => (
-
- }
- />
-
+
+
+ }
+ />
+
+
diff --git a/src/containers/Footer/Footer.test.jsx b/src/containers/Footer/Footer.test.jsx
index dc6a725e34..bc493f7afc 100644
--- a/src/containers/Footer/Footer.test.jsx
+++ b/src/containers/Footer/Footer.test.jsx
@@ -8,16 +8,29 @@ import { IntlProvider } from '@edx/frontend-platform/i18n';
import { configuration } from '../../config';
import Footer from './index';
+import { GlobalContext } from '../../components/GlobalContextProvider';
const mockStore = configureMockStore([thunk]);
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
+
const FooterWrapper = props => (
-
+
+
+
);
diff --git a/src/containers/Header/Header.test.jsx b/src/containers/Header/Header.test.jsx
index d79be88939..effdfc28f1 100644
--- a/src/containers/Header/Header.test.jsx
+++ b/src/containers/Header/Header.test.jsx
@@ -14,15 +14,28 @@ import SidebarToggle from '../SidebarToggle';
import { configuration } from '../../config';
import Img from '../../components/Img';
+import { GlobalContext } from '../../components/GlobalContextProvider';
+
+const headerHeight = 0;
+const footerHeight = 0;
+
+const defaultGlobalContextValue = {
+ headerHeight,
+ footerHeight,
+ minHeight: `calc(100vh - ${headerHeight + footerHeight + 16}px)`,
+ dispatch: jest.fn(),
+};
const mockStore = configureMockStore([thunk]);
const HeaderWrapper = props => (
-
+
+
+
);
diff --git a/src/data/actions/global.js b/src/data/actions/global.js
new file mode 100644
index 0000000000..1f7470bf1e
--- /dev/null
+++ b/src/data/actions/global.js
@@ -0,0 +1,19 @@
+import {
+ HEADER_HEIGHT,
+ FOOTER_HEIGHT,
+} from '../constants/global';
+
+const setHeaderHeight = (refValue = 0) => ({
+ type: HEADER_HEIGHT,
+ payload: { headerHeight: refValue },
+});
+
+const setFooterHeight = (refValue = 0) => ({
+ type: FOOTER_HEIGHT,
+ payload: { footerHeight: refValue },
+});
+
+export {
+ setHeaderHeight,
+ setFooterHeight,
+};
diff --git a/src/data/constants/global.js b/src/data/constants/global.js
new file mode 100644
index 0000000000..9302cd8d59
--- /dev/null
+++ b/src/data/constants/global.js
@@ -0,0 +1,7 @@
+const HEADER_HEIGHT = 'GLOBAL_HEADER_HEIGHT';
+const FOOTER_HEIGHT = 'GLOBAL_FOOTER_HEIGHT';
+
+export {
+ HEADER_HEIGHT,
+ FOOTER_HEIGHT,
+};
diff --git a/src/data/reducers/global.js b/src/data/reducers/global.js
new file mode 100644
index 0000000000..d5795b811e
--- /dev/null
+++ b/src/data/reducers/global.js
@@ -0,0 +1,26 @@
+import {
+ HEADER_HEIGHT,
+ FOOTER_HEIGHT,
+} from '../constants/global';
+
+export const initialState = {
+ headerHeight: 0,
+ footerHeight: 0,
+};
+
+export const globalReducer = (state = initialState, action) => {
+ switch (action.type) {
+ case HEADER_HEIGHT:
+ return {
+ ...state,
+ headerHeight: action.payload.headerHeight,
+ };
+ case FOOTER_HEIGHT:
+ return {
+ ...state,
+ footerHeight: action.payload.footerHeight,
+ };
+ default:
+ return state;
+ }
+};
diff --git a/src/data/reducers/global.test.js b/src/data/reducers/global.test.js
new file mode 100644
index 0000000000..43652b339c
--- /dev/null
+++ b/src/data/reducers/global.test.js
@@ -0,0 +1,37 @@
+import { globalReducer } from './global';
+import { FOOTER_HEIGHT, HEADER_HEIGHT } from '../constants/global';
+
+const initialState = {
+ headerHeight: 0,
+ footerHeight: 0,
+};
+
+describe('Global Reducer', () => {
+ it('Should return the initial state', () => {
+ expect(globalReducer(undefined, {})).toEqual(initialState);
+ });
+ it('Updates the headerHeight', () => {
+ const expected = {
+ ...initialState,
+ headerHeight: 25,
+ };
+ expect(globalReducer(undefined, {
+ type: HEADER_HEIGHT,
+ payload: {
+ headerHeight: 25,
+ },
+ })).toEqual(expected);
+ });
+ it('Updates the footerHeight', () => {
+ const expected = {
+ ...initialState,
+ footerHeight: 35,
+ };
+ expect(globalReducer(undefined, {
+ type: FOOTER_HEIGHT,
+ payload: {
+ footerHeight: 35,
+ },
+ })).toEqual(expected);
+ });
+});
diff --git a/src/index.scss b/src/index.scss
index f38108a463..f2e73aee5e 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -17,7 +17,7 @@ $modal-max-width: 650px;
@import "./components/NumberCard/NumberCard";
@import "./components/RequestCodesPage/RequestCodesPage";
@import "./components/Sidebar/Sidebar";
-@import "./components/subscriptions/styles/";
+@import "./components/subscriptions/styles";
@import "./components/LoadingMessage/LoadingMessage";
@import "./components/TableComponent/TableComponent";
@import "./components/TableLoadingOverlay/TableLoadingOverlay";