Skip to content

Commit cd34b30

Browse files
farhanclaude
andauthored
refactor: Remove Legacy UI Waffle Flag Consumers — Phase 1c (#5)
* refactor: Remove Legacy UI Waffle Flag Consumers — Phase 1c * refactor: remove useNewUpdatesPage and useNewCustomPages waffle flags Remove routing waffle flags from useContentMenuItems (useNewUpdatesPage), useSettingMenuItems (unused waffleFlags ref), and PageSettingButton tests (useNewCustomPages legacy-link test). All paths now always resolve to MFE. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b3e0e61 commit cd34b30

8 files changed

Lines changed: 22 additions & 89 deletions

File tree

src/CourseAuthoringContext.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { getConfig } from '@edx/frontend-platform';
21
import {
32
createContext,
43
useContext,
@@ -10,7 +9,7 @@ import { useNavigate } from 'react-router';
109
import { useToggleWithValue } from '@src/hooks';
1110
import { type UnitXBlock, type XBlock } from '@src/data/types';
1211
import { CourseDetailsData } from './data/api';
13-
import { useCourseDetails, useWaffleFlags } from './data/apiHooks';
12+
import { useCourseDetails } from './data/apiHooks';
1413
import { RequestStatusType } from './data/constants';
1514
import { getOutlineIndexData } from './course-outline/data/selectors';
1615

@@ -53,7 +52,6 @@ export const CourseAuthoringProvider = ({
5352
courseId,
5453
}: CourseAuthoringProviderProps) => {
5554
const navigate = useNavigate();
56-
const waffleFlags = useWaffleFlags();
5755
const { data: courseDetails, status: courseDetailStatus } = useCourseDetails(courseId);
5856
const canChangeProviders = getAuthenticatedUser().administrator || new Date(courseDetails?.start ?? 0) > new Date();
5957
const { courseStructure } = useSelector(getOutlineIndexData);
@@ -65,26 +63,12 @@ export const CourseAuthoringProvider = ({
6563
closeUnlinkModal,
6664
] = useToggleWithValue<ModalState>();
6765

68-
const getUnitUrl = (locator: string) => {
69-
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
70-
// instanbul ignore next
71-
return `/course/${courseId}/container/${locator}`;
72-
}
73-
return `${getConfig().STUDIO_BASE_URL}/container/${locator}`;
74-
};
66+
const getUnitUrl = (locator: string) => `/course/${courseId}/container/${locator}`;
7567

7668
/**
7769
* Open the unit page for a given locator.
7870
*/
79-
const openUnitPage = async (locator: string) => {
80-
const url = getUnitUrl(locator);
81-
if (getConfig().ENABLE_UNIT_PAGE === 'true' && waffleFlags.useNewUnitPage) {
82-
// instanbul ignore next
83-
navigate(url);
84-
} else {
85-
window.location.assign(url);
86-
}
87-
};
71+
const openUnitPage = async (locator: string) => { navigate(getUnitUrl(locator)); };
8872

8973
const context = useMemo<CourseAuthoringContextData>(() => ({
9074
courseId,

src/editors/containers/VideoEditor/components/VideoEditorModal.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { useEffect } from 'react';
22
import { useDispatch, useSelector } from 'react-redux';
33
import { useLocation } from 'react-router-dom';
4-
import { useWaffleFlags } from '@src/data/apiHooks';
54
import * as appHooks from '../../../hooks';
65
import { thunkActions, selectors } from '../../../data/redux';
76
import VideoSettingsModal from './VideoSettingsModal';
@@ -42,7 +41,6 @@ const VideoEditorModal: React.FC<Props> = ({
4241
const isLoaded = useSelector(
4342
(state) => selectors.requests.isFinished(state, { requestKey: RequestKeys.fetchVideos }),
4443
);
45-
const { useNewVideoUploadsPage } = useWaffleFlags();
4644

4745
useEffect(() => {
4846
hooks.initialize(dispatch, selectedVideoId, selectedVideoUrl);
@@ -54,7 +52,6 @@ const VideoEditorModal: React.FC<Props> = ({
5452
onReturn: onSettingsReturn,
5553
isLibrary,
5654
onClose,
57-
useNewVideoUploadsPage,
5855
}}
5956
/>
6057
);

src/editors/containers/VideoEditor/components/VideoSettingsModal/index.test.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const defaultProps = {
1010
onReturn: jest.fn(),
1111
isLibrary: false,
1212
onClose: jest.fn(),
13-
useNewVideoUploadsPage: true,
1413
};
1514

1615
const renderComponent = (overrideProps = {}) => {
@@ -38,7 +37,7 @@ describe('<VideoSettingsModal />', () => {
3837
window.scrollTo = jest.fn();
3938
});
4039

41-
it('renders back button when useNewVideoUploadsPage is true and isLibrary is false', () => {
40+
it('renders back button when isLibrary is false', () => {
4241
renderComponent();
4342
expect(screen.getByRole('button', { name: /replace video/i })).toBeInTheDocument();
4443
});

src/editors/containers/VideoEditor/components/VideoSettingsModal/index.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,15 @@ interface Props {
2121
onReturn: () => void;
2222
isLibrary: boolean;
2323
onClose?: (() => void) | null;
24-
useNewVideoUploadsPage?: boolean;
2524
}
2625

2726
const VideoSettingsModal: React.FC<Props> = ({
2827
onReturn,
2928
isLibrary,
3029
onClose,
31-
useNewVideoUploadsPage,
3230
}) => (
3331
<>
34-
{!isLibrary && useNewVideoUploadsPage && (
32+
{!isLibrary && (
3533
<Button
3634
variant="link"
3735
className="text-primary-500"

src/header/hooks.test.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
2222
}));
2323

2424
// Bypass React Query for waffle flags, and just return the default values.
25-
mockWaffleFlags({
26-
// Some flags can be enabled with either a config value or a waffle flag.
27-
// For test purposes, we'll configure the video upload page using the config, so leave the waffle flag off.
28-
useNewVideoUploadsPage: false,
29-
useNewCertificatesPage: false,
30-
});
25+
mockWaffleFlags({});
3126

3227
jest.mock('react-redux', () => ({
3328
...jest.requireActual('react-redux'),

src/header/hooks.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ import { getCourseUpdatesPermissions } from '@src/authz/permissionHelpers';
2222

2323
export const useContentMenuItems = (courseId: string) => {
2424
const intl = useIntl();
25-
const studioBaseUrl = getConfig().STUDIO_BASE_URL;
26-
const waffleFlags = useWaffleFlags(courseId);
2725
const { librariesV2Enabled } = useSelector(getStudioHomeData);
2826

2927
const { canViewCourseUpdates, canViewPagesAndResources } = useCourseUserPermissions(
@@ -36,14 +34,12 @@ export const useContentMenuItems = (courseId: string) => {
3634

3735
const items = [
3836
{
39-
href: waffleFlags.useNewCourseOutlinePage ? `/course/${courseId}` : `${studioBaseUrl}/course/${courseId}`,
37+
href: `/course/${courseId}`,
4038
title: intl.formatMessage(messages['header.links.outline']),
4139
},
4240
...(canViewCourseUpdates ?
4341
[{
44-
href: waffleFlags.useNewUpdatesPage
45-
? `/course/${courseId}/course_info`
46-
: `${studioBaseUrl}/course_info/${courseId}`,
42+
href: `/course/${courseId}/course_info`,
4743
title: intl.formatMessage(messages['header.links.updates']),
4844
}] :
4945
[]),
@@ -54,11 +50,12 @@ export const useContentMenuItems = (courseId: string) => {
5450
}]
5551
: []),
5652
{
57-
href: waffleFlags.useNewFilesUploadsPage ? `/course/${courseId}/assets` : `${studioBaseUrl}/assets/${courseId}`,
53+
href: `/course/${courseId}/assets`,
5854
title: intl.formatMessage(messages['header.links.filesAndUploads']),
5955
},
6056
];
61-
if (getConfig().ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN === 'true' || waffleFlags.useNewVideoUploadsPage) {
57+
58+
if (getConfig().ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN === 'true') {
6259
items.push({
6360
href: `/course/${courseId}/videos`,
6461
title: intl.formatMessage(messages['header.links.videoUploads']),
@@ -78,7 +75,6 @@ export const useContentMenuItems = (courseId: string) => {
7875
export const useSettingMenuItems = (courseId: string) => {
7976
const intl = useIntl();
8077
const { canAccessAdvancedSettings: legacyCanAccessAdvancedSettings } = useSelector(getStudioHomeData);
81-
const waffleFlags = useWaffleFlags(courseId);
8278

8379
/*
8480
AuthZ for Course Authoring
@@ -133,7 +129,7 @@ export const useSettingMenuItems = (courseId: string) => {
133129
}] :
134130
[]),
135131
];
136-
if (getConfig().ENABLE_CERTIFICATE_PAGE === 'true' || waffleFlags.useNewCertificatesPage) {
132+
if (getConfig().ENABLE_CERTIFICATE_PAGE === 'true') {
137133
items.push({
138134
href: `/course/${courseId}/certificates`,
139135
title: intl.formatMessage(messages['header.links.certificates']),
@@ -144,21 +140,20 @@ export const useSettingMenuItems = (courseId: string) => {
144140

145141
export const useToolsMenuItems = (courseId: string) => {
146142
const intl = useIntl();
147-
const studioBaseUrl = getConfig().STUDIO_BASE_URL;
148143
const waffleFlags = useWaffleFlags();
149144

150145
const items = [
151146
{
152-
href: waffleFlags.useNewImportPage ? `/course/${courseId}/import` : `${studioBaseUrl}/import/${courseId}`,
147+
href: `/course/${courseId}/import`,
153148
title: intl.formatMessage(messages['header.links.import']),
154149
},
155150
{
156-
href: waffleFlags.useNewExportPage ? `/course/${courseId}/export` : `${studioBaseUrl}/export/${courseId}`,
151+
href: `/course/${courseId}/export`,
157152
title: intl.formatMessage(messages['header.links.exportCourse']),
158153
},
159154
...(getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'
160155
? [{
161-
href: `${studioBaseUrl}/course/${courseId}#export-tags`,
156+
href: `${getConfig().STUDIO_BASE_URL}/course/${courseId}#export-tags`,
162157
title: intl.formatMessage(messages['header.links.exportTags']),
163158
}] :
164159
[]),

src/pages-and-resources/pages/PageSettingButton.jsx

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { Icon, IconButton } from '@openedx/paragon';
66
import { ArrowForward, Settings } from '@openedx/paragon/icons';
77
import { useNavigate, Link } from 'react-router-dom';
88

9-
import { useWaffleFlags } from '../../data/apiHooks';
109
import { useCourseUserPermissions } from '../../authz/hooks';
1110
import { getAdvancedSettingsPermissions } from '../../authz/permissionHelpers';
1211
import messages from '../messages';
@@ -22,25 +21,12 @@ const PageSettingButton = ({
2221
const { path: pagesAndResourcesPath, isEditable } = useContext(PagesAndResourcesContext);
2322
const { canManageAdvancedSettings } = useCourseUserPermissions(courseId, getAdvancedSettingsPermissions(courseId));
2423
const navigate = useNavigate();
25-
const waffleFlags = useWaffleFlags(courseId);
2624

27-
const determineLinkDestination = useMemo(() => {
28-
if (!legacyLink) { return null; }
29-
30-
if (legacyLink.includes('textbooks')) {
31-
return waffleFlags.useNewTextbooksPage
32-
? `/course/${courseId}/${id.replace('_', '-')}`
33-
: legacyLink;
34-
}
35-
36-
if (legacyLink.includes('tabs')) {
37-
return waffleFlags.useNewCustomPages
38-
? `/course/${courseId}/${id.replace('_', '-')}`
39-
: legacyLink;
40-
}
41-
42-
return null;
43-
}, [legacyLink, waffleFlags, id]);
25+
const determineLinkDestination = useMemo(() => (
26+
legacyLink?.includes('textbooks') || legacyLink?.includes('tabs')
27+
? `/course/${courseId}/${id.replace('_', '-')}`
28+
: null
29+
), [legacyLink, courseId, id]);
4430

4531
const canConfigureOrEnable = allowedOperations?.configure || allowedOperations?.enable;
4632

src/pages-and-resources/pages/PageSettingButton.test.jsx

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// @ts-check
22
import { screen, render, initializeMocks, fireEvent } from '../../testUtils';
33
import PageSettingButton from './PageSettingButton';
4-
import { mockWaffleFlags } from '../../data/apiHooks.mock';
54
import { useCourseUserPermissions } from '../../authz/hooks';
65
import PagesAndResourcesProvider from '../PagesAndResourcesProvider';
76

@@ -30,14 +29,12 @@ const renderComponent = (props = {}, { isEditable = true, canManageAdvancedSetti
3029
);
3130
};
3231

33-
mockWaffleFlags();
34-
3532
describe('PageSettingButton', () => {
3633
beforeEach(() => {
3734
initializeMocks();
3835
});
3936

40-
it('renders the settings button with the new textbooks page link when useNewTextbooksPage is true', () => {
37+
it('renders the settings button with the new textbooks page link', () => {
4138
renderComponent({ legacyLink: 'http://legacylink.com/textbooks' });
4239

4340
const linkElement = screen.getByRole('link');
@@ -50,31 +47,13 @@ describe('PageSettingButton', () => {
5047
expect(screen.queryByRole('link')).toBeNull();
5148
});
5249

53-
it('renders the settings button with the legacy link when useNewTextbooksPage is false', () => {
54-
mockWaffleFlags({ useNewTextbooksPage: false });
55-
56-
renderComponent({ legacyLink: 'http://legacylink.com/textbooks' });
57-
58-
const linkElement = screen.getByRole('link');
59-
expect(linkElement).toHaveAttribute('href', 'http://legacylink.com/textbooks');
60-
});
61-
62-
it('renders the settings button with the new custom pages link when useNewCustomPages is true', () => {
50+
it('renders the settings button with the new custom pages link', () => {
6351
renderComponent();
6452

6553
const linkElement = screen.getByRole('link');
6654
expect(linkElement).toHaveAttribute('href', `/course/${defaultProps.courseId}/page-id`);
6755
});
6856

69-
it('renders the settings button with the legacy link when useNewCustomPages is false', () => {
70-
mockWaffleFlags({ useNewCustomPages: false });
71-
72-
renderComponent();
73-
74-
const linkElement = screen.getByRole('link');
75-
expect(linkElement).toHaveAttribute('href', defaultProps.legacyLink);
76-
});
77-
7857
it('renders disabled icon button in read-only mode with legacy link', () => {
7958
renderComponent({ legacyLink: 'http://legacylink.com/textbooks' }, { isEditable: false });
8059

0 commit comments

Comments
 (0)