diff --git a/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py b/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py index 31cf9c36f068..06dc1b87bedc 100644 --- a/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py +++ b/cms/djangoapps/contentstore/rest_api/v1/serializers/course_waffle_flags.py @@ -80,10 +80,15 @@ def get_use_new_grading_page(self, obj): def get_use_new_updates_page(self, obj): """ - Method to get the use_new_updates_page switch + Method to indicate if we should use the new updates_page + + This used to be based on a waffle flag but the flag is being removed so we + default it to true for now until we can remove the need for it from the consumers + of this serializer and the related APIs. + + See https://github.com/openedx/edx-platform/issues/37497 """ - course_key = self.get_course_key() - return toggles.use_new_updates_page(course_key) + return True def get_use_new_import_page(self, obj): """ diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index a8721d629c76..f4fe5554a063 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1489,8 +1489,6 @@ def test_get_html(handler): test_get_html('export_handler') with override_waffle_flag(toggles.LEGACY_STUDIO_COURSE_TEAM, True): test_get_html('course_team_handler') - with override_waffle_flag(toggles.LEGACY_STUDIO_UPDATES, True): - test_get_html('course_info_handler') with override_waffle_flag(toggles.LEGACY_STUDIO_CUSTOM_PAGES, True): test_get_html('tabs_handler') with override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True): @@ -1502,6 +1500,16 @@ def test_get_html(handler): with override_waffle_flag(toggles.LEGACY_STUDIO_TEXTBOOKS, True): test_get_html('textbooks_list_handler') + # Test that studio updates load + course_updates_url = reverse( + 'course_info_update_handler', + kwargs={ + 'course_key_string': str(course_key), + } + ) + resp = self.client.get(course_updates_url) + assert resp.status_code == 200 + # go look at the Edit page unit_key = course_key.make_usage_key('vertical', 'test_vertical') with override_waffle_flag(toggles.LEGACY_STUDIO_UNIT_EDITOR, True): diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index 9afba26b32e5..2fc4e58039c7 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -167,7 +167,6 @@ def test_discussion_fields_available(self, is_pages_and_resources_enabled, @override_waffle_flag(toggles.LEGACY_STUDIO_IMPORT, True) @override_waffle_flag(toggles.LEGACY_STUDIO_EXPORT, True) @override_waffle_flag(toggles.LEGACY_STUDIO_COURSE_TEAM, True) - @override_waffle_flag(toggles.LEGACY_STUDIO_UPDATES, True) @override_waffle_flag(toggles.LEGACY_STUDIO_CUSTOM_PAGES, True) @override_waffle_flag(toggles.LEGACY_STUDIO_SCHEDULE_DETAILS, True) @override_waffle_flag(toggles.LEGACY_STUDIO_GRADING, True) @@ -186,7 +185,6 @@ def test_disable_advanced_settings_feature(self, disable_advanced_settings): 'import_handler', 'export_handler', 'course_team_handler', - 'course_info_handler', 'tabs_handler', 'settings_handler', 'grading_handler', diff --git a/cms/djangoapps/contentstore/toggles.py b/cms/djangoapps/contentstore/toggles.py index 96a646bff211..8863e17e0681 100644 --- a/cms/djangoapps/contentstore/toggles.py +++ b/cms/djangoapps/contentstore/toggles.py @@ -256,25 +256,6 @@ def use_new_grading_page(course_key): return not LEGACY_STUDIO_GRADING.is_enabled(course_key) -# .. toggle_name: legacy_studio.updates -# .. toggle_implementation: WaffleFlag -# .. toggle_default: False -# .. toggle_description: Temporarily fall back to the old Studio Course Updates page. -# .. toggle_use_cases: temporary -# .. toggle_creation_date: 2025-03-14 -# .. toggle_target_removal_date: 2025-09-14 -# .. toggle_tickets: https://github.com/openedx/edx-platform/issues/36275 -# .. toggle_warning: In Ulmo, this toggle will be removed. Only the new (React-based) experience will be available. -LEGACY_STUDIO_UPDATES = CourseWaffleFlag('legacy_studio.updates', __name__) - - -def use_new_updates_page(course_key): - """ - Returns a boolean if new studio updates mfe is enabled - """ - return not LEGACY_STUDIO_UPDATES.is_enabled(course_key) - - # .. toggle_name: legacy_studio.import # .. toggle_implementation: WaffleFlag # .. toggle_default: False diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index 3b263570f616..4a4f45a8050f 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -52,7 +52,6 @@ use_new_schedule_details_page, use_new_textbooks_page, use_new_unit_page, - use_new_updates_page, use_new_video_uploads_page, ) from cms.djangoapps.models.settings.course_grading import CourseGradingModel @@ -363,11 +362,10 @@ def get_updates_url(course_locator) -> str: Gets course authoring microfrontend URL for updates page view. """ updates_url = None - if use_new_updates_page(course_locator): - mfe_base_url = get_course_authoring_url(course_locator) - course_mfe_url = f'{mfe_base_url}/course/{course_locator}/course_info' - if mfe_base_url: - updates_url = course_mfe_url + mfe_base_url = get_course_authoring_url(course_locator) + course_mfe_url = f'{mfe_base_url}/course/{course_locator}/course_info' + if mfe_base_url: + updates_url = course_mfe_url return updates_url diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 453e30e0aad0..e1c5c8089db9 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -71,7 +71,6 @@ from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.lib.course_tabs import CourseTabPluginManager from organizations.models import Organization -from xmodule.contentstore.content import StaticContent # lint-amnesty, pylint: disable=wrong-import-order from xmodule.course_block import CourseBlock, CourseFields # lint-amnesty, pylint: disable=wrong-import-order from xmodule.error_block import ErrorBlock # lint-amnesty, pylint: disable=wrong-import-order from xmodule.modulestore import EdxJSONEncoder # lint-amnesty, pylint: disable=wrong-import-order @@ -90,7 +89,6 @@ from ..tasks import rerun_course as rerun_course_task from ..toggles import ( default_enable_flexible_peer_openassessments, - use_new_updates_page, use_new_advanced_settings_page, use_new_grading_page, use_new_textbooks_page, @@ -1066,24 +1064,7 @@ def course_info_handler(request, course_key_string): except InvalidKeyError: raise Http404 # lint-amnesty, pylint: disable=raise-missing-from - with modulestore().bulk_operations(course_key): - course_block = get_course_and_check_access(course_key, request.user) - if not course_block: - raise Http404 - if use_new_updates_page(course_key): - return redirect(get_updates_url(course_key)) - if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'): - return render_to_response( - 'course_info.html', - { - 'context_course': course_block, - 'updates_url': reverse_course_url('course_info_update_handler', course_key), - 'handouts_locator': course_key.make_usage_key('course_info', 'handouts'), - 'base_asset_url': StaticContent.get_base_url_path_for_course_assets(course_block.id), - } - ) - else: - return HttpResponseBadRequest("Only supports html requests") + return redirect(get_updates_url(course_key)) @login_required diff --git a/cms/djangoapps/contentstore/views/tests/test_course_updates.py b/cms/djangoapps/contentstore/views/tests/test_course_updates.py index 7b3c31abe190..85f09bb7e83a 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_updates.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_updates.py @@ -5,9 +5,7 @@ import json from opaque_keys.edx.keys import UsageKey -from edx_toggles.toggles.testutils import override_waffle_flag -from cms.djangoapps.contentstore import toggles from cms.djangoapps.contentstore.tests.test_course_settings import CourseTestCase from cms.djangoapps.contentstore.utils import reverse_course_url, reverse_usage_url from openedx.core.lib.xblock_utils import get_course_update_items @@ -23,7 +21,6 @@ def create_update_url(self, provided_id=None, course_key=None): return reverse_course_url('course_info_update_handler', course_key, kwargs=kwargs) # The do all and end all of unit test cases. - @override_waffle_flag(toggles.LEGACY_STUDIO_UPDATES, True) def test_course_update(self): """Go through each interface and ensure it works.""" def get_response(content, date): @@ -40,11 +37,6 @@ def get_response(content, date): return json.loads(resp.content.decode('utf-8')) - resp = self.client.get_html( - reverse_course_url('course_info_handler', self.course.id) - ) - self.assertContains(resp, 'Course Updates', status_code=200) - init_content = '' payload = get_response(content, 'January 8, 2013') diff --git a/cms/static/cms/js/build.js b/cms/static/cms/js/build.js index e7b7a7730b2e..71e820697be4 100644 --- a/cms/static/cms/js/build.js +++ b/cms/static/cms/js/build.js @@ -20,7 +20,6 @@ 'js/factories/asset_index', 'js/factories/base', 'js/factories/course_create_rerun', - 'js/factories/course_info', 'js/factories/export', 'js/factories/group_configurations', 'js/certificates/factories/certificates_page_factory', diff --git a/cms/static/cms/js/spec/main.js b/cms/static/cms/js/spec/main.js index 4e093ee573b4..72741bc9b82c 100644 --- a/cms/static/cms/js/spec/main.js +++ b/cms/static/cms/js/spec/main.js @@ -236,7 +236,6 @@ 'js/spec/models/settings_grading_spec', 'js/spec/models/textbook_spec', 'js/spec/models/upload_spec', - 'js/spec/views/course_info_spec', 'js/spec/views/metadata_edit_spec', 'js/spec/views/textbook_spec', 'js/spec/views/upload_spec', diff --git a/cms/static/js/collections/course_update.js b/cms/static/js/collections/course_update.js deleted file mode 100644 index c4ec07684551..000000000000 --- a/cms/static/js/collections/course_update.js +++ /dev/null @@ -1,12 +0,0 @@ -define(['backbone', 'js/models/course_update'], function(Backbone, CourseUpdateModel) { - /* - The intitializer of this collection must set id to the update's location.url and courseLocation to the course's location. Must pass the - collection of updates as [{ date : "month day", content : "html"}] - */ - var CourseUpdateCollection = Backbone.Collection.extend({ - // instantiator must set url - - model: CourseUpdateModel - }); - return CourseUpdateCollection; -}); diff --git a/cms/static/js/factories/course_info.js b/cms/static/js/factories/course_info.js deleted file mode 100644 index 54fd381f7ad0..000000000000 --- a/cms/static/js/factories/course_info.js +++ /dev/null @@ -1,26 +0,0 @@ -define([ - 'jquery', 'js/collections/course_update', 'js/models/module_info', - 'js/models/course_info', 'js/views/course_info_edit' -], function($, CourseUpdateCollection, ModuleInfoModel, CourseInfoModel, CourseInfoEditView) { - 'use strict'; - - return function(updatesUrl, handoutsLocator, baseAssetUrl) { - var course_updates = new CourseUpdateCollection(), - course_handouts, editor; - - course_updates.url = updatesUrl; - course_updates.fetch({reset: true}); - course_handouts = new ModuleInfoModel({ - id: handoutsLocator - }); - editor = new CourseInfoEditView({ - el: $('.main-wrapper'), - model: new CourseInfoModel({ - updates: course_updates, - base_asset_url: baseAssetUrl, - handouts: course_handouts - }) - }); - editor.render(); - }; -}); diff --git a/cms/static/js/models/course_info.js b/cms/static/js/models/course_info.js deleted file mode 100644 index b4e710d5033d..000000000000 --- a/cms/static/js/models/course_info.js +++ /dev/null @@ -1,13 +0,0 @@ -define(['backbone'], function(Backbone) { - // single per course holds the updates and handouts - var CourseInfo = Backbone.Model.extend({ - // This model class is not suited for restful operations and is considered just a server side initialized container - url: '', - - defaults: { - updates: null, // UpdateCollection - handouts: null // HandoutCollection - } - }); - return CourseInfo; -}); diff --git a/cms/static/js/spec/views/course_info_spec.js b/cms/static/js/spec/views/course_info_spec.js deleted file mode 100644 index 8d3dca7fb43f..000000000000 --- a/cms/static/js/spec/views/course_info_spec.js +++ /dev/null @@ -1,283 +0,0 @@ -define(["js/views/course_info_handout", "js/views/course_info_update", "js/models/module_info", - "js/collections/course_update", "edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers"], -(CourseInfoHandoutsView, CourseInfoUpdateView, ModuleInfo, CourseUpdateCollection, AjaxHelpers) => - - describe("Course Updates and Handouts", function() { - const courseInfoPage = `\ -
-
-
-
    -
    -
    - -
    -\ -`; - - beforeEach(function() { - window.analytics = jasmine.createSpyObj('analytics', ['track']); - window.course_location_analytics = jasmine.createSpy(); - }); - - afterEach(function() { - delete window.analytics; - delete window.course_location_analytics; - }); - - describe("Course Updates", function() { - const courseInfoTemplate = readFixtures('course_info_update.underscore'); - - beforeEach(function() { - let cancelEditingUpdate; - setFixtures($(" -% endfor - - -<%block name="requirejs"> - require(["js/factories/course_info"], function(CourseInfoFactory) { - CourseInfoFactory( - "${updates_url | n, js_escaped_string}", - "${handouts_locator | n, js_escaped_string}", - "${base_asset_url | n, js_escaped_string}" - ); - }); - - -<%block name="content"> -
    -
    -

    - ${_("Content")} - > ${_("Course Updates")} -

    - - -
    -
    - -
    -
    -
    -

    ${_('Use course updates to notify students of important dates or exams, highlight particular discussions in the forums, announce schedule changes, and respond to student questions. You add or edit updates in HTML.')}

    -
    -
    -
    - -
    -
    -
    -
    -
    -
      -
      -
      - -
      -
      -
      - diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index 3280cef73f12..d01ee633ea87 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -46,7 +46,6 @@

      certificates_url = reverse('certificates_list_handler', kwargs={'course_key_string': str(course_key)}) checklists_url = reverse('checklists_handler', kwargs={'course_key_string': str(course_key)}) pages_and_resources_mfe_enabled = ENABLE_PAGES_AND_RESOURCES_MICROFRONTEND.is_enabled(context_course.id) - updates_mfe_enabled = toggles.use_new_updates_page(context_course.id) video_upload_mfe_enabled = toggles.use_new_video_uploads_page(context_course.id) schedule_details_mfe_enabled = toggles.use_new_schedule_details_page(context_course.id) grading_mfe_enabled = toggles.use_new_grading_page(context_course.id) @@ -83,16 +82,9 @@

      ${_("Course" ${_("Libraries")} % endif - % if not updates_mfe_enabled: - - % endif - % if updates_mfe_enabled: - % endif % if not pages_and_resources_mfe_enabled: