feat: adding new plugin slot for an enterprise modal

This commit is contained in:
Kira Miller
2025-02-12 06:57:46 +00:00
committed by Jason Wesson
parent dd4f61eec3
commit 5d2b33abd3
9 changed files with 48 additions and 163 deletions

View File

@@ -2,9 +2,9 @@ import React from 'react';
import { reduxHooks } from 'hooks';
import { RequestKeys } from 'data/constants/requests';
import EnterpriseDashboardModal from 'containers/EnterpriseDashboardModal';
import SelectSessionModal from 'containers/SelectSessionModal';
import CoursesPanel from 'containers/CoursesPanel';
import EnterpriseDashboardModalSlot from 'plugin-slots/EnterpriseDashboardModalSlot';
import LoadingView from './LoadingView';
import DashboardLayout from './DashboardLayout';
@@ -24,7 +24,7 @@ export const Dashboard = () => {
<h1 className="sr-only">{pageTitle}</h1>
{!initIsPending && (
<>
{hasAvailableDashboards && <EnterpriseDashboardModal />}
{hasAvailableDashboards && <EnterpriseDashboardModalSlot />}
{(hasCourses && showSelectSessionModal) && <SelectSessionModal />}
</>
)}

View File

@@ -2,9 +2,9 @@ import { shallow } from '@edx/react-unit-test-utils';
import { reduxHooks } from 'hooks';
import EnterpriseDashboardModal from 'containers/EnterpriseDashboardModal';
import SelectSessionModal from 'containers/SelectSessionModal';
import CoursesPanel from 'containers/CoursesPanel';
import EnterpriseDashboardModalSlot from 'plugin-slots/EnterpriseDashboardModalSlot';
import DashboardLayout from './DashboardLayout';
import LoadingView from './LoadingView';
@@ -20,7 +20,7 @@ jest.mock('hooks', () => ({
},
}));
jest.mock('containers/EnterpriseDashboardModal', () => 'EnterpriseDashboardModal');
jest.mock('plugin-slots/EnterpriseDashboardModalSlot', () => 'EnterpriseDashboardModalSlot');
jest.mock('containers/CoursesPanel', () => 'CoursesPanel');
jest.mock('./LoadingView', () => 'LoadingView');
jest.mock('./DashboardLayout', () => 'DashboardLayout');
@@ -81,7 +81,7 @@ describe('Dashboard', () => {
testContent(contentEl);
});
it(`${renderString(showEnterpriseModal)} dashbaord modal`, () => {
expect(wrapper.instance.findByType(EnterpriseDashboardModal).length)
expect(wrapper.instance.findByType(EnterpriseDashboardModalSlot).length)
.toEqual(showEnterpriseModal ? 1 : 0);
});
it(`${renderString(showSelectSessionModal)} select session modal`, () => {

View File

@@ -1,42 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EnterpriseDashboard empty snapshot 1`] = `null`;
exports[`EnterpriseDashboard snapshot 1`] = `
<ModalDialog
hasCloseButton={false}
onClose={[MockFunction useEnterpriseDashboardHook.handleEscape]}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={
{
"textAlign": "start",
}
}
>
<h4>
You have access to the edX, Inc. dashboard
</h4>
<p>
To access the courses available to you through edX, Inc., visit the edX, Inc. dashboard now.
</p>
<ActionRow>
<Button
onClick={[MockFunction useEnterpriseDashboardHook.handleClose]}
variant="tertiary"
>
Dismiss
</Button>
<Button
href="/edx-dashboard"
onClick={[MockFunction useEnterpriseDashboardHook.handleCTAClick]}
type="a"
>
Go to dashboard
</Button>
</ActionRow>
</div>
</ModalDialog>
`;

View File

@@ -1,60 +0,0 @@
import React from 'react';
// import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
ModalDialog, ActionRow, Button,
} from '@openedx/paragon';
import messages from './messages';
import useEnterpriseDashboardHook from './hooks';
export const EnterpriseDashboardModal = () => {
const { formatMessage } = useIntl();
const {
showModal,
handleClose,
handleCTAClick,
handleEscape,
dashboard,
} = useEnterpriseDashboardHook();
if (!dashboard || !dashboard.label) {
return null;
}
return (
<ModalDialog
isOpen={showModal}
onClose={handleEscape}
hasCloseButton={false}
title=""
>
<div
className="bg-white p-3 rounded shadow"
style={{ textAlign: 'start' }}
>
<h4>
{formatMessage(messages.enterpriseDialogHeader, {
label: dashboard.label,
})}
</h4>
<p>
{formatMessage(messages.enterpriseDialogBody, {
label: dashboard.label,
})}
</p>
<ActionRow>
<Button variant="tertiary" onClick={handleClose}>
{formatMessage(messages.enterpriseDialogDismissButton)}
</Button>
<Button type="a" href={dashboard.url} onClick={handleCTAClick}>
{formatMessage(messages.enterpriseDialogConfirmButton)}
</Button>
</ActionRow>
</div>
</ModalDialog>
);
};
EnterpriseDashboardModal.propTypes = {};
export default EnterpriseDashboardModal;

View File

@@ -1,29 +0,0 @@
import { shallow } from '@edx/react-unit-test-utils';
import EnterpriseDashboard from '.';
import useEnterpriseDashboardHook from './hooks';
jest.mock('./hooks', () => ({
__esModule: true,
default: jest.fn(),
}));
describe('EnterpriseDashboard', () => {
test('snapshot', () => {
const hookData = {
dashboard: { label: 'edX, Inc.', url: '/edx-dashboard' },
showDialog: false,
handleClose: jest.fn().mockName('useEnterpriseDashboardHook.handleClose'),
handleCTAClick: jest.fn().mockName('useEnterpriseDashboardHook.handleCTAClick'),
handleEscape: jest.fn().mockName('useEnterpriseDashboardHook.handleEscape'),
};
useEnterpriseDashboardHook.mockReturnValueOnce({ ...hookData });
const el = shallow(<EnterpriseDashboard />);
expect(el.snapshot).toMatchSnapshot();
});
test('empty snapshot', () => {
useEnterpriseDashboardHook.mockReturnValueOnce({});
const el = shallow(<EnterpriseDashboard />);
expect(el.snapshot).toMatchSnapshot();
});
});

View File

@@ -1,26 +0,0 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
enterpriseDialogHeader: {
id: 'leanerDashboard.enterpriseDialogHeader',
defaultMessage: 'You have access to the {label} dashboard',
description: 'title for enterpise dashboard dialog',
},
enterpriseDialogBody: {
id: 'leanerDashboard.enterpriseDialogBody',
defaultMessage: 'To access the courses available to you through {label}, visit the {label} dashboard now.',
description: 'Body text for enterpise dashboard dialog',
},
enterpriseDialogDismissButton: {
id: 'leanerDashboard.enterpriseDialogDismissButton',
defaultMessage: 'Dismiss',
description: 'Dismiss button to cancel visiting dashboard',
},
enterpriseDialogConfirmButton: {
id: 'leanerDashboard.enterpriseDialogConfirmButton',
defaultMessage: 'Go to dashboard',
description: 'Confirm button to go to the dashboard url',
},
});
export default messages;

View File

@@ -0,0 +1,33 @@
# Course Card Action Slot
### Slot ID: `enterprise_dashboard_modal_slot`
## Description
This slot is used for the modal on a dashboard that directs you to the enterprise dashboard if applicable.
The following `env.config.jsx` will render the modal.
```js
import { DIRECT_PLUGIN, PLUGIN_OPERATIONS } from '@openedx/frontend-plugin-framework';
import { EnterpriseDashboardModal } from '@edx/frontend-plugin-learner-dashboard';
const config = {
pluginSlots: {
enterprise_dashboard_modal_slot: {
plugins: [
{
op: PLUGIN_OPERATIONS.Insert,
widget: {
id: 'dashboard_modal',
type: DIRECT_PLUGIN,
priority: 60,
RenderWidget: EnterpriseDashboardModal,
},
},
],
}
},
}
export default config;
```

View File

@@ -0,0 +1,8 @@
import React from 'react';
import { PluginSlot } from '@openedx/frontend-plugin-framework';
const EnterpriseDashboardModal = () => (
<PluginSlot id="enterprise_dashboard_modal_slot" />
);
export default EnterpriseDashboardModal;

View File

@@ -4,4 +4,5 @@
* [`footer_slot`](./FooterSlot/)
* [`widget_sidebar_slot`](./WidgetSidebarSlot/)
* [`course_list_slot`](./CourseListSlot/)
* [`no_courses_view_slot`](./NoCoursesViewSlot/)
* [`no_courses_view_slot`](./NoCoursesViewSlot/)
* [`enterprise_dashboard_modal_slot](./EnterpriseDashboardModalSlot)