From abdf29ea1958877e7cd43017a5a2f1bda0eab159 Mon Sep 17 00:00:00 2001 From: salmannawaz Date: Fri, 22 May 2026 12:50:55 +0500 Subject: [PATCH 1/2] chore: remove waffle flags for legacy UI Co-Authored-By: Claude Sonnet 4.6 --- .../ChecklistSection/ChecklistItemBody.jsx | 15 +++-------- .../add-component/AddComponent.tsx | 26 ++++++++----------- src/course-unit/breadcrumbs/Breadcrumbs.tsx | 12 ++------- src/header/Header.tsx | 7 ++--- 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx b/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx index 7ac9f06cb2..79cde9a4ea 100644 --- a/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx +++ b/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx @@ -5,24 +5,18 @@ import { ActionRow, Button, Icon } from '@openedx/paragon'; import { CheckCircle, RadioButtonUnchecked } from '@openedx/paragon/icons'; import { getConfig } from '@edx/frontend-platform'; -import { useWaffleFlags } from '@src/data/apiHooks'; - import messages from './messages'; -const getUpdateLinks = (courseId, waffleFlags) => { +const getUpdateLinks = (courseId) => { const baseUrl = getConfig().STUDIO_BASE_URL; - const isLegacyCertificateUrl = !waffleFlags.useNewCertificatesPage; - const isLegacyOutlineUrl = !waffleFlags.useNewCourseOutlinePage; return { welcomeMessage: `/course/${courseId}/course_info`, gradingPolicy: `/course/${courseId}/settings/grading`, - certificate: isLegacyCertificateUrl - ? `${baseUrl}/certificates/${courseId}` : - `/course/${courseId}/certificates`, + certificate: `/course/${courseId}/certificates`, courseDates: `/course/${courseId}/settings/details/#schedule`, proctoringEmail: `${baseUrl}/pages-and-resources/proctoring/settings`, - outline: isLegacyOutlineUrl ? `${baseUrl}/course/${courseId}` : `/course/${courseId}`, + outline: `/course/${courseId}`, }; }; @@ -32,8 +26,7 @@ const ChecklistItemBody = ({ isCompleted, }) => { const intl = useIntl(); - const waffleFlags = useWaffleFlags(courseId); - const updateLinks = getUpdateLinks(courseId, waffleFlags); + const updateLinks = getUpdateLinks(courseId); return ( diff --git a/src/course-unit/add-component/AddComponent.tsx b/src/course-unit/add-component/AddComponent.tsx index 9dd8078f41..5b9844380d 100644 --- a/src/course-unit/add-component/AddComponent.tsx +++ b/src/course-unit/add-component/AddComponent.tsx @@ -86,7 +86,7 @@ const AddComponent = ({ const [selectedComponents, setSelectedComponents] = useState([]); const [usageId, setUsageId] = useState(null); const { sendMessageToIframe } = useIframe(); - const { useVideoGalleryFlow, useNewPdfEditor } = useWaffleFlags(courseId ?? undefined); + const { useVideoGalleryFlow } = useWaffleFlags(courseId ?? undefined); const courseUnit = useSelector(getCourseUnitData); const sequenceId = courseUnit?.ancestorInfo?.ancestors?.[0]?.id; @@ -181,20 +181,16 @@ const AddComponent = ({ // *in code* and not just in UI seems like a mistake in retrospect. // // There will be more of these, and soon. - if (moduleName === COMPONENT_TYPES.pdf && useNewPdfEditor) { - handleCreateNewCourseXBlock( - { type: moduleName, parentLocator: blockId }, - /* istanbul ignore next */ - ({ courseKey, locator }) => { - setCourseId(courseKey); - setBlockType(moduleName); - setNewBlockId(locator); - showXBlockEditorModal(); - }, - ); - } else { - handleCreateNewCourseXBlock({ type: moduleName, category: moduleName, parentLocator: blockId }); - } + handleCreateNewCourseXBlock( + { type: moduleName, parentLocator: blockId }, + /* istanbul ignore next */ + ({ courseKey, locator }) => { + setCourseId(courseKey); + setBlockType(moduleName ?? null); + setNewBlockId(locator); + showXBlockEditorModal(); + }, + ); break; case COMPONENT_TYPES.openassessment: handleCreateNewCourseXBlock({ boilerplate: moduleName, category: type, parentLocator: blockId }); diff --git a/src/course-unit/breadcrumbs/Breadcrumbs.tsx b/src/course-unit/breadcrumbs/Breadcrumbs.tsx index 1790ff1917..10b1be1350 100644 --- a/src/course-unit/breadcrumbs/Breadcrumbs.tsx +++ b/src/course-unit/breadcrumbs/Breadcrumbs.tsx @@ -5,23 +5,15 @@ import { ArrowDropDown as ArrowDropDownIcon, ChevronRight as ChevronRightIcon, } from '@openedx/paragon/icons'; -import { getConfig } from '@edx/frontend-platform'; - -import { useWaffleFlags } from '../../data/apiHooks'; import { getCourseSectionVertical } from '../data/selectors'; import { adoptCourseSectionUrl, subsectionFirstUnitEditUrl } from '../utils'; const Breadcrumbs = ({ courseId, parentUnitId }: { courseId: string; parentUnitId: string; }) => { const { ancestorXblocks = [] } = useSelector(getCourseSectionVertical); - const waffleFlags = useWaffleFlags(courseId); - const getPathToCourseOutlinePage = (url) => (waffleFlags.useNewCourseOutlinePage - ? url : - `${getConfig().STUDIO_BASE_URL}${url}`); + const getPathToCourseOutlinePage = (url) => url; - const getPathToCourseUnitPage = (url) => (waffleFlags.useNewUnitPage - ? adoptCourseSectionUrl({ url, courseId, parentUnitId }) - : `${getConfig().STUDIO_BASE_URL}${url}`); + const getPathToCourseUnitPage = (url) => adoptCourseSectionUrl({ url, courseId, parentUnitId }); // based on the level of breadcrumbs the url will differ // at the subsection level it should navigate to the first unit if available diff --git a/src/header/Header.tsx b/src/header/Header.tsx index 2f2e307cf4..791e7edb6c 100644 --- a/src/header/Header.tsx +++ b/src/header/Header.tsx @@ -3,7 +3,6 @@ import { getConfig } from '@edx/frontend-platform'; import { useIntl } from '@edx/frontend-platform/i18n'; import { type Container, useToggle } from '@openedx/paragon'; -import { useWaffleFlags } from '../data/apiHooks'; import { SearchModal } from '../search-modal'; import { useContentMenuItems, @@ -38,11 +37,9 @@ const Header = ({ readOnly = false, }: HeaderProps) => { const intl = useIntl(); - const waffleFlags = useWaffleFlags(); const [isShowSearchModalOpen, openSearchModal, closeSearchModal] = useToggle(false); - const studioBaseUrl = getConfig().STUDIO_BASE_URL; const meiliSearchEnabled = [true, 'true'].includes(getConfig().MEILISEARCH_ENABLED); const contentMenuItems = useContentMenuItems(contextId); @@ -90,7 +87,7 @@ const Header = ({ if (isLibrary) { return `/library/${contextId}`; } - return waffleFlags.useNewCourseOutlinePage ? `/course/${contextId}` : `${studioBaseUrl}/course/${contextId}`; + return `/course/${contextId}`; }; return ( @@ -104,7 +101,7 @@ const Header = ({ outlineLink={getOutlineLink()} searchButtonAction={meiliSearchEnabled ? openSearchModal : undefined} containerProps={containerProps} - isNewHomePage={waffleFlags.useNewHomePage} + isNewHomePage /> {meiliSearchEnabled && ( Date: Mon, 25 May 2026 13:28:08 +0500 Subject: [PATCH 2/2] chore: remove waffle flag tests for legacy UI Co-Authored-By: Claude Sonnet 4.6 --- .../add-component/AddComponent.test.tsx | 14 ----------- .../add-component/AddComponent.tsx | 24 +++++++++++-------- .../breadcrumbs/Breadcrumbs.test.tsx | 19 --------------- 3 files changed, 14 insertions(+), 43 deletions(-) diff --git a/src/course-unit/add-component/AddComponent.test.tsx b/src/course-unit/add-component/AddComponent.test.tsx index a44d44917b..ecff00fe42 100644 --- a/src/course-unit/add-component/AddComponent.test.tsx +++ b/src/course-unit/add-component/AddComponent.test.tsx @@ -2,7 +2,6 @@ /* eslint-disable react/prop-types */ import userEvent, { UserEvent } from '@testing-library/user-event'; -import { mockWaffleFlags } from '@src/data/apiHooks.mock'; import { RenderResult } from '@testing-library/react'; import { act, @@ -360,19 +359,6 @@ describe('', () => { }, expect.any(Function)); }); - it('adds a PDF block and launches the legacy iframe editor', async () => { - const user = userEvent.setup(); - mockWaffleFlags({ useNewPdfEditor: false }); - const { getByRole, queryAllByRole } = renderComponent(); - await createPdfBlock({ getByRole, queryAllByRole, user }); - expect(handleCreateNewCourseXBlockMock).toHaveBeenCalled(); - expect(handleCreateNewCourseXBlockMock).toHaveBeenCalledWith({ - parentLocator: '123', - type: COMPONENT_TYPES.pdf, - // Setting the category and not supplying an additional function launches the traditional editor. - category: COMPONENT_TYPES.pdf, - }); - }); it('verifies "Text" component selection in modal', async () => { const user = userEvent.setup(); diff --git a/src/course-unit/add-component/AddComponent.tsx b/src/course-unit/add-component/AddComponent.tsx index 5b9844380d..cbb0134913 100644 --- a/src/course-unit/add-component/AddComponent.tsx +++ b/src/course-unit/add-component/AddComponent.tsx @@ -181,16 +181,20 @@ const AddComponent = ({ // *in code* and not just in UI seems like a mistake in retrospect. // // There will be more of these, and soon. - handleCreateNewCourseXBlock( - { type: moduleName, parentLocator: blockId }, - /* istanbul ignore next */ - ({ courseKey, locator }) => { - setCourseId(courseKey); - setBlockType(moduleName ?? null); - setNewBlockId(locator); - showXBlockEditorModal(); - }, - ); + if (moduleName === COMPONENT_TYPES.pdf) { + handleCreateNewCourseXBlock( + { type: moduleName, parentLocator: blockId }, + /* istanbul ignore next */ + ({ courseKey, locator }) => { + setCourseId(courseKey); + setBlockType(moduleName ?? null); + setNewBlockId(locator); + showXBlockEditorModal(); + }, + ); + } else { + handleCreateNewCourseXBlock({ type: moduleName, category: moduleName, parentLocator: blockId }); + } break; case COMPONENT_TYPES.openassessment: handleCreateNewCourseXBlock({ boilerplate: moduleName, category: type, parentLocator: blockId }); diff --git a/src/course-unit/breadcrumbs/Breadcrumbs.test.tsx b/src/course-unit/breadcrumbs/Breadcrumbs.test.tsx index 5f47f25251..4e29d207fa 100644 --- a/src/course-unit/breadcrumbs/Breadcrumbs.test.tsx +++ b/src/course-unit/breadcrumbs/Breadcrumbs.test.tsx @@ -151,23 +151,4 @@ describe('', () => { expect(dropdownItem).toHaveAttribute('href', url); }); - it('falls back to window.location.href when the waffle flag is disabled', async () => { - const user = userEvent.setup(); - // eslint-disable-next-line @typescript-eslint/naming-convention - const { ancestor_xblocks: [{ children: [{ display_name, url }] }] } = courseSectionVerticalMock; - axiosMock - .onGet(getApiWaffleFlagsUrl(courseId)) - .reply(200, { useNewCourseOutlinePage: false }); - - const { getByText, getByRole } = renderComponent(); - - const dropdownBtn = getByText(breadcrumbsExpected.section.displayName); - await user.click(dropdownBtn); - - const dropdownItem = getByRole('link', { name: display_name }); - // We need waitFor here because the waffle flag defaults to true but asynchronously loads false from our axiosMock - await waitFor(() => { - expect(dropdownItem).toHaveAttribute('href', `${getConfig().STUDIO_BASE_URL}${url}`); - }); - }); });