feat!: Drop the legacy files and uplades page.
The assets page and related tests and settings flags will be removed. They have been replaced with a new implementation in the frontend-app-authoring MFE. BREAKING CHANGE: The legacy_studio.files_uploads flag has been removed and will no longer allow operators to fall back to the legacy files and uploads view. The new MFE version is now the only available veiew.
This commit is contained in:
@@ -19,7 +19,6 @@ from django.views.decorators.http import require_http_methods, require_POST
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey
|
||||
from pymongo import ASCENDING, DESCENDING
|
||||
|
||||
from common.djangoapps.edxmako.shortcuts import render_to_response
|
||||
from common.djangoapps.student.auth import has_course_author_access
|
||||
from common.djangoapps.util.date_utils import get_default_time_display
|
||||
from common.djangoapps.util.json_request import JsonResponse
|
||||
@@ -34,8 +33,7 @@ from xmodule.modulestore.django import modulestore # lint-amnesty, pylint: disa
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from .exceptions import AssetNotFoundException, AssetSizeTooLargeException
|
||||
from .utils import reverse_course_url, get_files_uploads_url, get_response_format, request_response_format_is_json
|
||||
from .toggles import use_new_files_uploads_page
|
||||
from .utils import get_files_uploads_url, get_response_format, request_response_format_is_json
|
||||
|
||||
|
||||
REQUEST_DEFAULTS = {
|
||||
@@ -169,22 +167,8 @@ def _get_asset_usage_path(course_key, assets):
|
||||
def _asset_index(request, course_key):
|
||||
'''
|
||||
Display an editable asset library.
|
||||
|
||||
Supports start (0-based index into the list of assets) and max query parameters.
|
||||
'''
|
||||
course_block = modulestore().get_course(course_key)
|
||||
|
||||
if use_new_files_uploads_page(course_key):
|
||||
return redirect(get_files_uploads_url(course_key))
|
||||
|
||||
return render_to_response('asset_index.html', {
|
||||
'language_code': request.LANGUAGE_CODE,
|
||||
'context_course': course_block,
|
||||
'max_file_size_in_mbs': settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB,
|
||||
'chunk_size_in_mbs': settings.UPLOAD_CHUNK_SIZE_IN_MB,
|
||||
'max_file_size_redirect_url': settings.MAX_ASSET_UPLOAD_FILE_SIZE_URL,
|
||||
'asset_callback_url': reverse_course_url('assets_handler', course_key)
|
||||
})
|
||||
return redirect(get_files_uploads_url(course_key))
|
||||
|
||||
|
||||
def _assets_json(request, course_key):
|
||||
|
||||
@@ -102,9 +102,11 @@ class CourseWaffleFlagsSerializer(serializers.Serializer):
|
||||
def get_use_new_files_uploads_page(self, obj):
|
||||
"""
|
||||
Method to get the use_new_files_uploads_page switch
|
||||
|
||||
Always true, because the switch is being removed an the new experience
|
||||
should alawys be on.
|
||||
"""
|
||||
course_key = self.get_course_key()
|
||||
return toggles.use_new_files_uploads_page(course_key)
|
||||
return True
|
||||
|
||||
def get_use_new_video_uploads_page(self, obj):
|
||||
"""
|
||||
|
||||
@@ -1491,8 +1491,6 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
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_FILES_UPLOADS, True):
|
||||
test_get_html('assets_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):
|
||||
|
||||
@@ -168,7 +168,6 @@ class CourseAdvanceSettingViewTest(CourseTestCase, MilestonesTestCaseMixin):
|
||||
@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_FILES_UPLOADS, 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)
|
||||
@@ -188,7 +187,6 @@ class CourseAdvanceSettingViewTest(CourseTestCase, MilestonesTestCaseMixin):
|
||||
'export_handler',
|
||||
'course_team_handler',
|
||||
'course_info_handler',
|
||||
'assets_handler',
|
||||
'tabs_handler',
|
||||
'settings_handler',
|
||||
'grading_handler',
|
||||
|
||||
@@ -313,25 +313,6 @@ def use_new_export_page(course_key):
|
||||
return not LEGACY_STUDIO_EXPORT.is_enabled(course_key)
|
||||
|
||||
|
||||
# .. toggle_name: legacy_studio.files_uploads
|
||||
# .. toggle_implementation: WaffleFlag
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: Temporarily fall back to the old Studio Files & Uploads 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_FILES_UPLOADS = CourseWaffleFlag('legacy_studio.files_uploads', __name__)
|
||||
|
||||
|
||||
def use_new_files_uploads_page(course_key):
|
||||
"""
|
||||
Returns a boolean if new studio files and uploads mfe is enabled
|
||||
"""
|
||||
return not LEGACY_STUDIO_FILES_UPLOADS.is_enabled(course_key)
|
||||
|
||||
|
||||
# .. toggle_name: contentstore.new_studio_mfe.use_new_video_uploads_page
|
||||
# .. toggle_implementation: CourseWaffleFlag
|
||||
# .. toggle_default: False
|
||||
|
||||
@@ -46,7 +46,6 @@ from cms.djangoapps.contentstore.toggles import (
|
||||
use_new_course_team_page,
|
||||
use_new_custom_pages,
|
||||
use_new_export_page,
|
||||
use_new_files_uploads_page,
|
||||
use_new_grading_page,
|
||||
use_new_group_configurations_page,
|
||||
use_new_import_page,
|
||||
@@ -416,11 +415,10 @@ def get_files_uploads_url(course_locator) -> str:
|
||||
Gets course authoring microfrontend URL for files and uploads page view.
|
||||
"""
|
||||
files_uploads_url = None
|
||||
if use_new_files_uploads_page(course_locator):
|
||||
mfe_base_url = get_course_authoring_url(course_locator)
|
||||
course_mfe_url = f'{mfe_base_url}/course/{course_locator}/assets'
|
||||
if mfe_base_url:
|
||||
files_uploads_url = course_mfe_url
|
||||
mfe_base_url = get_course_authoring_url(course_locator)
|
||||
course_mfe_url = f'{mfe_base_url}/course/{course_locator}/assets'
|
||||
if mfe_base_url:
|
||||
files_uploads_url = course_mfe_url
|
||||
return files_uploads_url
|
||||
|
||||
|
||||
|
||||
@@ -12,13 +12,11 @@ from unittest.mock import patch
|
||||
from ddt import data, ddt
|
||||
from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from opaque_keys.edx.keys import AssetKey
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
from PIL import Image
|
||||
from pytz import UTC
|
||||
|
||||
from cms.djangoapps.contentstore import toggles
|
||||
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
|
||||
from cms.djangoapps.contentstore.utils import reverse_course_url
|
||||
from cms.djangoapps.contentstore.views import assets
|
||||
@@ -87,10 +85,9 @@ class BasicAssetsTestCase(AssetsTestCase):
|
||||
Test getting assets via html w/o additional args
|
||||
"""
|
||||
|
||||
@override_waffle_flag(toggles.LEGACY_STUDIO_FILES_UPLOADS, True)
|
||||
def test_basic(self):
|
||||
resp = self.client.get(self.url, HTTP_ACCEPT='text/html')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(resp.status_code, 302)
|
||||
|
||||
def test_static_url_generation(self):
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<%page expression_filter="h"/>
|
||||
<%inherit file="base.html" />
|
||||
<%def name="online_help_token()"><% return "files" %></%def>
|
||||
<%!
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext as _
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from openedx.core.djangolib.js_utils import js_escaped_string, dump_js_escaped_json
|
||||
%>
|
||||
<%block name="title">${_("Files")}</%block>
|
||||
<%block name="bodyclass">is-signedin course uploads view-uploads</%block>
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%block name="header_extras">
|
||||
% if not settings.STUDIO_FRONTEND_CONTAINER_URL:
|
||||
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/common.min.css')}" />
|
||||
<link rel="stylesheet" type="text/css" href="${static.url('common/css/vendor/assets.min.css')}" />
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
|
||||
<div class="wrapper-mast wrapper">
|
||||
<header class="mast has-actions has-subtitle">
|
||||
<h2 class="page-header">
|
||||
<small class="subtitle">${_("Content")}</small>
|
||||
<span class="sr">- </span>${_("Files")}
|
||||
</h2>
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="wrapper-content wrapper">
|
||||
<div class="content">
|
||||
<%static:optional_include_mako file="asset_index_content_header.html" />
|
||||
<%static:studiofrontend entry="assets">
|
||||
{
|
||||
"lang": "${language_code | n, js_escaped_string}",
|
||||
"course": {
|
||||
"id": "${context_course.id | n, js_escaped_string}",
|
||||
"name": "${context_course.display_name_with_default | n, js_escaped_string}",
|
||||
"url_name": "${context_course.location.block_id | n, js_escaped_string}",
|
||||
"org": "${context_course.location.org | n, js_escaped_string}",
|
||||
"num": "${context_course.location.course | n, js_escaped_string}",
|
||||
"display_course_number": "${context_course.display_coursenumber | n, js_escaped_string}",
|
||||
"revision": "${context_course.location.branch | n, js_escaped_string}"
|
||||
},
|
||||
"help_tokens": {
|
||||
"files": "${get_online_help_info(online_help_token())['doc_url'] | n, js_escaped_string}"
|
||||
},
|
||||
"upload_settings": {
|
||||
"max_file_size_in_mbs": ${max_file_size_in_mbs|n, dump_js_escaped_json}
|
||||
}
|
||||
}
|
||||
</%static:studiofrontend>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</%block>
|
||||
@@ -47,7 +47,6 @@
|
||||
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)
|
||||
files_uploads_mfe_enabled = toggles.use_new_files_uploads_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)
|
||||
@@ -104,16 +103,9 @@
|
||||
<a href="${get_pages_and_resources_url(course_key)}">${_("Pages & Resources")}</a>
|
||||
</li>
|
||||
% endif
|
||||
%if not files_uploads_mfe_enabled:
|
||||
<li class="nav-item nav-course-courseware-uploads">
|
||||
<a href="${assets_url}">${_("Files")}</a>
|
||||
</li>
|
||||
%endif
|
||||
%if files_uploads_mfe_enabled:
|
||||
<li class="nav-item nav-course-courseware-uploads">
|
||||
<a href="${get_files_uploads_url(course_key)}">${_("Files")}</a>
|
||||
</li>
|
||||
%endif
|
||||
% if not pages_and_resources_mfe_enabled:
|
||||
<li class="nav-item nav-course-courseware-textbooks">
|
||||
<a href="${textbooks_url}">${_("Textbooks")}</a>
|
||||
|
||||
Reference in New Issue
Block a user