Skip to content

Commit

Permalink
fix: don't hide highlights for staff and alert (#1197)
Browse files Browse the repository at this point in the history
* fix: don't hide highlights for staff

* fix: adding highlights alert

* fix: test fixes
  • Loading branch information
kiram15 authored Apr 9, 2024
1 parent 8e145f9 commit c4f5897
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 23 deletions.
47 changes: 45 additions & 2 deletions src/components/ContentHighlights/ContentHighlights.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import React, { useEffect, useState, useContext } from 'react';
import { connect } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';
import { v4 as uuidv4 } from 'uuid';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { logError } from '@edx/frontend-platform/logging';
import { Alert } from '@edx/paragon';
import { WarningFilled } from '@edx/paragon/icons';

import LmsApiService from '../../data/services/LmsApiService';
import ContentHighlightRoutes from './ContentHighlightRoutes';
import Hero from '../Hero';
import ContentHighlightsContextProvider from './ContentHighlightsContext';
import ContentHighlightToast from './ContentHighlightToast';
import { EnterpriseAppContext } from '../EnterpriseApp/EnterpriseAppContextProvider';
import { withLocation } from '../../hoc';

const ContentHighlights = ({ location }) => {
const ContentHighlights = ({ location, enterpriseGroupsV1 }) => {
const navigate = useNavigate();
const { state: locationState } = location;
const [toasts, setToasts] = useState([]);
const isEdxStaff = getAuthenticatedUser().administrator;
const [isSubGroup, setIsSubGroup] = useState(false);
const { enterpriseCuration: { enterpriseCuration } } = useContext(EnterpriseAppContext);

useEffect(() => {
async function fetchGroupsData() {
try {
const response = await LmsApiService.fetchEnterpriseGroups();
response.data.results.forEach((group) => {
if (group.applies_to_all_contexts === false) {
setIsSubGroup(true);
}
});
} catch (error) {
logError(error);
}
}
if (enterpriseGroupsV1 && isEdxStaff) {
fetchGroupsData();
}
}, [enterpriseGroupsV1, isEdxStaff]);
useEffect(() => {
if (locationState?.highlightToast) {
setToasts((prevState) => [...prevState, {
Expand Down Expand Up @@ -55,6 +82,17 @@ const ContentHighlights = ({ location }) => {
return (
<ContentHighlightsContextProvider>
<Hero title="Highlights" />
{isSubGroup && (
<Alert variant="warning" className="mt-4 mb-0" icon={WarningFilled}>
<Alert.Heading>Highlights hidden for administrators with custom groups enabled</Alert.Heading>
<p>
edX staff are able to view the highlights tab, but because this customer has custom
groups enabled, administrators will not be able to see this tab, and users will not
see highlights on their learner portal. This is just temporary as highlights are
not currently compatible with custom groups.
</p>
</Alert>
)}
<ContentHighlightRoutes />
{toasts.map(({ toastText, uuid }) => (<ContentHighlightToast toastText={toastText} key={uuid} />))}
</ContentHighlightsContextProvider>
Expand All @@ -71,6 +109,11 @@ ContentHighlights.propTypes = {
highlightToast: PropTypes.bool,
}),
}),
enterpriseGroupsV1: PropTypes.bool,
};

export default withLocation(ContentHighlights);
const mapStateToProps = state => ({
enterpriseGroupsV1: state.portalConfiguration.enterpriseFeatures?.enterpriseGroupsV1,
});

export default connect(mapStateToProps)(withLocation(ContentHighlights));
16 changes: 16 additions & 0 deletions src/components/ContentHighlights/tests/ContentHighlights.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { renderWithRouter } from '@edx/frontend-enterprise-utils';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import ContentHighlights from '../ContentHighlights';
import { EnterpriseAppContext } from '../../EnterpriseApp/EnterpriseAppContextProvider';
import LmsApiService from '../../../data/services/LmsApiService';

jest.mock('../../../data/services/LmsApiService');

const mockStore = configureMockStore([thunk]);
const initialEnterpriseAppContextValue = {
Expand Down Expand Up @@ -38,6 +42,11 @@ const ContentHighlightsWrapper = ({
);

describe('<ContentHighlights>', () => {
beforeEach(() => {
getAuthenticatedUser.mockReturnValue({
administrator: true,
});
});
it('Displays the Hero', () => {
renderWithRouter(<ContentHighlightsWrapper location={{ state: {} }} />);
expect(screen.getAllByText('Highlights')[0]).toBeInTheDocument();
Expand Down Expand Up @@ -75,4 +84,11 @@ describe('<ContentHighlights>', () => {
);
expect(screen.getByText('Archived courses deleted')).toBeInTheDocument();
});
it('Displays the alert if custom groups is enabled and user is staff', () => {
LmsApiService.fetchEnterpriseGroups.mockImplementation(() => Promise.resolve({
data: { results: [{ applies_to_all_contexts: true }] },
}));
renderWithRouter(<ContentHighlightsWrapper location={{ state: {} }} />);
screen.debug();
});
});
11 changes: 6 additions & 5 deletions src/components/Sidebar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { Icon } from '@edx/paragon';
import {
BookOpen, CreditCard, Description, InsertChartOutlined, MoneyOutline, Settings, Support, Tag, TrendingUp,
} from '@edx/paragon/icons';

import { logError } from '@edx/frontend-platform/logging';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform/config';
import IconLink from './IconLink';
import { logError } from '@edx/frontend-platform/logging';

import IconLink from './IconLink';
import { configuration, features } from '../../config';
import { SubsidyRequestsContext } from '../subsidy-requests';
import { ROUTE_NAMES } from '../EnterpriseApp/data/constants';
Expand Down Expand Up @@ -41,8 +41,9 @@ const Sidebar = ({
const { subsidyRequestsCounts } = useContext(SubsidyRequestsContext);
const { canManageLearnerCredit } = useContext(EnterpriseSubsidiesContext);
const { FEATURE_CONTENT_HIGHLIGHTS } = getConfig();
const isEdxStaff = getAuthenticatedUser().administrator;
const [isSubGroup, setIsSubGroup] = useState(false);
const hideHighlightsForGroups = enterpriseGroupsV1 && isSubGroup;
const hideHighlightsForGroups = enterpriseGroupsV1 && isSubGroup && !isEdxStaff;

const getSidebarWidth = useCallback(() => {
if (navRef && navRef.current) {
Expand Down Expand Up @@ -73,7 +74,7 @@ const Sidebar = ({
logError(error);
}
}
if (enterpriseGroupsV1) {
if (enterpriseGroupsV1 && !isEdxStaff) {
fetchGroupsData();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const BudgetDetailPageHeader = ({ enterpriseUUID, enterpriseFeatures }) => {
policy={subsidyAccessPolicy}
/>
<BudgetDetailPageOverviewAvailability
enterpriseFeatures={enterpriseFeatures}
budgetId={budgetId}
budgetTotalSummary={budgetTotalSummary}
isAssignable={isAssignable}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { generatePath, useParams, Link } from 'react-router-dom';
import {
Button, Col, ProgressBar, Row, Stack,
Button, Col, Hyperlink, ProgressBar, Row, Stack,
} from '@edx/paragon';
import { Add } from '@edx/paragon/icons';
import { sendEnterpriseTrackEvent } from '@edx/frontend-enterprise-utils';

import { configuration } from '../../config';
import { BudgetDetailPageContext } from './BudgetDetailPageWrapper';
import { formatPrice, useBudgetId, useSubsidyAccessPolicy } from './data';
import useEnterpriseGroup from './data/hooks/useEnterpriseGroup';
Expand Down Expand Up @@ -42,12 +43,15 @@ BudgetDetail.propTypes = {
limit: PropTypes.number.isRequired,
};

const BudgetActions = ({ budgetId, isAssignable, enterpriseId }) => {
const BudgetActions = ({
budgetId, isAssignable, enterpriseId, enterpriseGroupsV1,
}) => {
const { enterpriseSlug, enterpriseAppPage } = useParams();
const { subsidyAccessPolicyId } = useBudgetId();
const { data: subsidyAccessPolicy } = useSubsidyAccessPolicy(subsidyAccessPolicyId);
const { data: appliesToAllContexts } = useEnterpriseGroup(subsidyAccessPolicy);
const { openInviteModal } = useContext(BudgetDetailPageContext);
const supportUrl = configuration.ENTERPRISE_SUPPORT_URL;

const trackEventMetadata = {};
if (subsidyAccessPolicy) {
Expand All @@ -68,37 +72,63 @@ const BudgetActions = ({ budgetId, isAssignable, enterpriseId }) => {
}

if (!isAssignable) {
if (appliesToAllContexts === true) {
if (enterpriseGroupsV1) {
if (appliesToAllContexts === true) {
return (
<div className="h-100 d-flex align-items-center pt-4 pt-lg-0">
<div>
<h3>Manage edX for your organization</h3>
<p>
All people in your organization can choose what to learn
from the catalog and spend from the available balance to enroll.
</p>
<Link to={`/${enterpriseSlug}/admin/settings/access`}>
<Button variant="outline-primary">Configure access</Button>
</Link>,
</div>
</div>
);
}
return (
<div className="h-100 d-flex align-items-center pt-4 pt-lg-0">
<div>
<h3>Manage edX for your organization</h3>
<h3>Drive learner-led enrollments by inviting members</h3>
<p>
All people in your organization can choose what to learn
from the catalog and spend from the available balance to enroll.
Members of this budget can choose what to learn from the catalog
and spend from the available balance to enroll.
</p>
<Link to={`/${enterpriseSlug}/admin/settings/access`}>
<Button variant="outline-primary">Configure access</Button>
</Link>,
<Button
variant="brand"
onClick={openInviteModal}
target="_blank"
iconBefore={Add}
>
New members
</Button>
</div>
</div>
);
}
return (
<div className="h-100 d-flex align-items-center pt-4 pt-lg-0">
<div>
<h3>Drive learner-led enrollments by inviting members</h3>
<h4>Get people learning using this budget</h4>
<p>
Members of this budget can choose what to learn from the catalog
and spend from the available balance to enroll.
Funds from this budget are set to auto-allocate to registered learners based on
settings configured with your support team.
</p>
<Button
variant="brand"
onClick={openInviteModal}
variant="outline-primary"
as={Hyperlink}
destination={supportUrl}
onClick={() => sendEnterpriseTrackEvent(
enterpriseId,
EVENT_NAMES.LEARNER_CREDIT_MANAGEMENT.BUDGET_OVERVIEW_CONTACT_US,
trackEventMetadata,
)}
target="_blank"
iconBefore={Add}
>
New members
Contact support
</Button>
</div>
</div>
Expand Down Expand Up @@ -136,6 +166,7 @@ BudgetActions.propTypes = {
budgetId: PropTypes.string.isRequired,
isAssignable: PropTypes.bool.isRequired,
enterpriseId: PropTypes.string.isRequired,
enterpriseGroupsV1: PropTypes.bool.isRequired,
};

const BudgetDetailPageOverviewAvailability = ({
Expand All @@ -155,6 +186,7 @@ const BudgetDetailPageOverviewAvailability = ({
budgetId={budgetId}
isAssignable={isAssignable && enterpriseFeatures.topDownAssignmentRealTimeLcm}
enterpriseId={enterpriseId}
enterpriseGroupsV1={enterpriseFeatures.enterpriseGroupsV1}
/>
</Col>
</Row>
Expand All @@ -173,6 +205,7 @@ BudgetDetailPageOverviewAvailability.propTypes = {
isAssignable: PropTypes.bool.isRequired,
enterpriseFeatures: PropTypes.shape({
topDownAssignmentRealTimeLcm: PropTypes.bool,
enterpriseGroupsV1: PropTypes.bool,
}).isRequired,
enterpriseId: PropTypes.string.isRequired,
};
Expand Down
7 changes: 7 additions & 0 deletions src/containers/Sidebar/Sidebar.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from '@testing-library/react';
import '@testing-library/jest-dom';
import { getConfig } from '@edx/frontend-platform/config';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';

import Sidebar from './index';
import { SubsidyRequestsContext } from '../../components/subsidy-requests';
Expand Down Expand Up @@ -111,6 +112,9 @@ describe('<Sidebar />', () => {
let wrapper;

beforeEach(() => {
getAuthenticatedUser.mockReturnValue({
administrator: true,
});
wrapper = mount((
<SidebarWrapper />
));
Expand Down Expand Up @@ -430,6 +434,9 @@ describe('<Sidebar />', () => {
});

it('hides highlights when we have groups with a subset of all learners', async () => {
getAuthenticatedUser.mockReturnValue({
administrator: false,
});
getConfig.mockReturnValue({ FEATURE_CONTENT_HIGHLIGHTS: true });
const store = mockStore({
...initialState,
Expand Down

0 comments on commit c4f5897

Please sign in to comment.