diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index b3548d61b78f..e278e5846af9 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -2142,12 +2142,13 @@ def _test_page(self, page, status_code=200): resp = self.client.get_html(page) self.assertEqual(resp.status_code, status_code) # noqa: PT009 - @override_waffle_flag(toggles.LEGACY_STUDIO_LOGGED_OUT_HOME, True) - def test_how_it_works_legacy(self): - self._test_page("/howitworks") + def test_homepage_redirects_to_home(self): + # Root URL permanently redirects to studio home (sign-in page). + self._test_page("/", 301) - def test_how_it_works_redirect_to_signin(self): - self._test_page("/howitworks", 302) + def test_howitworks_redirects_to_home(self): + # Legacy landing page permanently redirects; preserves bookmarks. + self._test_page("/howitworks", 301) def test_signup(self): # deprecated signup url redirects to LMS register. diff --git a/cms/djangoapps/contentstore/tests/tests.py b/cms/djangoapps/contentstore/tests/tests.py index f67b43ecf6ac..e38d1533b5fb 100644 --- a/cms/djangoapps/contentstore/tests/tests.py +++ b/cms/djangoapps/contentstore/tests/tests.py @@ -10,8 +10,7 @@ import datetime import time -from unittest import mock -from urllib.parse import quote_plus, unquote +from urllib.parse import unquote from ddt import data, ddt, unpack from django.conf import settings @@ -179,32 +178,6 @@ def test_inactive_session_timeout(self): # re-request, and we should get a redirect to login page self.assertRedirects(resp, settings.LOGIN_URL + '?next=/home/', target_status_code=302) - @data( - (True, 'assertContains'), - (False, 'assertNotContains')) - @unpack - @override_waffle_flag(toggles.LEGACY_STUDIO_LOGGED_OUT_HOME, True) - def test_signin_and_signup_buttons_index_page(self, allow_account_creation, assertion_method_name): - """ - Navigate to the home page and check the Sign Up button is hidden when ALLOW_PUBLIC_ACCOUNT_CREATION flag - is turned off, and not when it is turned on. The Sign In button should always appear. - """ - with mock.patch.dict(settings.FEATURES, {"ALLOW_PUBLIC_ACCOUNT_CREATION": allow_account_creation}): - response = self.client.get(reverse('homepage')) - assertion_method = getattr(self, assertion_method_name) - login_url = quote_plus(f"http://testserver{settings.LOGIN_URL}") - assertion_method( - response, - f'Sign Up' - ) - self.assertContains( - response, - '' - 'Sign In' - ) - - class ForumTestCase(CourseTestCase): """Tests class to verify course to forum operations""" diff --git a/cms/djangoapps/contentstore/toggles.py b/cms/djangoapps/contentstore/toggles.py index 30a030f966a9..7f5aa9673845 100644 --- a/cms/djangoapps/contentstore/toggles.py +++ b/cms/djangoapps/contentstore/toggles.py @@ -519,28 +519,6 @@ def enable_course_optimizer(course_id): return ENABLE_COURSE_OPTIMIZER.is_enabled(course_id) -# .. toggle_name: legacy_studio.logged_out_home -# .. toggle_implementation: WaffleFlag -# .. toggle_default: False -# .. toggle_description: Temporarily fall back to the old Studio "How it Works" page when unauthenticated -# .. 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, along with the legacy page. The only available -# behavior will be to send the user to the log-in page with a redirect to Studio Course Listing (/home). -LEGACY_STUDIO_LOGGED_OUT_HOME = WaffleFlag('legacy_studio.logged_out_home', __name__) - - -def use_legacy_logged_out_home(): - """ - Returns whether the old "how it works" page should be shown. - - If not, then we should just go to the login page w/ redirect to studio course listing. - """ - return LEGACY_STUDIO_LOGGED_OUT_HOME.is_enabled() - - # .. toggle_name: contentstore.enable_course_optimizer_check_prev_run_links # .. toggle_implementation: CourseWaffleFlag # .. toggle_default: False diff --git a/cms/djangoapps/contentstore/views/public.py b/cms/djangoapps/contentstore/views/public.py index d0d782e1be43..f841d345b1af 100644 --- a/cms/djangoapps/contentstore/views/public.py +++ b/cms/djangoapps/contentstore/views/public.py @@ -8,13 +8,10 @@ from django.http.response import Http404 from django.shortcuts import redirect -from common.djangoapps.edxmako.shortcuts import render_to_response - from ..config.waffle import ENABLE_ACCESSIBILITY_POLICY_PAGE -from ..toggles import use_legacy_logged_out_home __all__ = [ - 'register_redirect_to_lms', 'login_redirect_to_lms', 'howitworks', 'accessibility', + 'register_redirect_to_lms', 'login_redirect_to_lms', 'accessibility', 'redirect_to_lms_login_for_admin', ] @@ -62,15 +59,6 @@ def _build_next_param(request): return '' -def howitworks(request): - """ - Deprecated logged-out home page. New behavior is just login w/ redirect to studio course list. - """ - if use_legacy_logged_out_home() and not request.user.is_authenticated: - return render_to_response('howitworks.html', {}) - return redirect('/home/') - - def accessibility(request): """ Display the accessibility accommodation form. diff --git a/cms/static/images/hiw-feature1.png b/cms/static/images/hiw-feature1.png deleted file mode 100644 index bc8625e866d8..000000000000 Binary files a/cms/static/images/hiw-feature1.png and /dev/null differ diff --git a/cms/static/images/hiw-feature2.png b/cms/static/images/hiw-feature2.png deleted file mode 100644 index 039a9ed5f742..000000000000 Binary files a/cms/static/images/hiw-feature2.png and /dev/null differ diff --git a/cms/static/images/hiw-feature3.png b/cms/static/images/hiw-feature3.png deleted file mode 100644 index 4cab3e80467b..000000000000 Binary files a/cms/static/images/hiw-feature3.png and /dev/null differ diff --git a/cms/static/images/thumb-hiw-feature1.png b/cms/static/images/thumb-hiw-feature1.png deleted file mode 100644 index 462207db6953..000000000000 Binary files a/cms/static/images/thumb-hiw-feature1.png and /dev/null differ diff --git a/cms/static/images/thumb-hiw-feature2.png b/cms/static/images/thumb-hiw-feature2.png deleted file mode 100644 index 075b2e988d71..000000000000 Binary files a/cms/static/images/thumb-hiw-feature2.png and /dev/null differ diff --git a/cms/static/images/thumb-hiw-feature3.png b/cms/static/images/thumb-hiw-feature3.png deleted file mode 100644 index 57cbc895d37b..000000000000 Binary files a/cms/static/images/thumb-hiw-feature3.png and /dev/null differ diff --git a/cms/static/sass/_build-v1.scss b/cms/static/sass/_build-v1.scss index e5e97978e7a8..c9360d7089a0 100644 --- a/cms/static/sass/_build-v1.scss +++ b/cms/static/sass/_build-v1.scss @@ -64,7 +64,6 @@ @import 'views/updates'; @import 'views/dashboard'; @import 'views/export'; -@import 'views/index'; @import 'views/course-create'; @import 'views/import'; @import 'views/outline'; diff --git a/cms/static/sass/elements/_header.scss b/cms/static/sass/elements/_header.scss index c17338acade3..33f50e3c2f06 100644 --- a/cms/static/sass/elements/_header.scss +++ b/cms/static/sass/elements/_header.scss @@ -353,7 +353,6 @@ // STATE: active/current nav states .nav-item.is-current, -body.howitworks .nav-not-signedin-hiw, body.dashboard .nav-account-dashboard, body.course.view-outline .nav-course-courseware .title, body.course.view-updates .nav-course-courseware .title, diff --git a/cms/static/sass/views/_index.scss b/cms/static/sass/views/_index.scss deleted file mode 100644 index 7f7525aca427..000000000000 --- a/cms/static/sass/views/_index.scss +++ /dev/null @@ -1,354 +0,0 @@ -// studio - views - how it works -// ==================== - -.view-howitworks { - &.not-signedin { - .wrapper-header { - margin-bottom: 0; - } - - .wrapper-content-header, - .wrapper-content-features, - .wrapper-content-cta { - box-sizing: border-box; - margin: 0; - padding: 0 $baseline; - position: relative; - width: 100%; - } - - .content { - @extend %t-copy-base; - - @include clearfix(); - - max-width: $fg-max-width; - min-width: $fg-min-width; - width: flex-grid(12); - margin: 0 auto; - color: $gray-d2; - - header { - border: none; - padding-bottom: 0; - margin-bottom: 0; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - color: $gray-d3; - } - } - - // welcome content - .wrapper-content-header { - @include linear-gradient($blue-l1, $blue, $blue-d1); - - padding-bottom: ($baseline*4); - padding-top: ($baseline*4); - } - - .content-header { - position: relative; - text-align: center; - color: $white; - - h1 { - @extend %t-title2; - @extend %t-strong; - - float: none; - margin: 0 0 ($baseline/2) 0; - border-bottom: 1px solid $blue-l1; - padding: 0; - color: $white; - } - - .wrapper-text-welcome, - .logo { - display: inline-block; - } - - .logo { - @extend %t-strong; - - margin-left: ($baseline/2); - } - - .tagline { - @extend %t-title4; - - margin: 0; - color: $blue-l3; - } - } - - .arrow_box { - position: relative; - background: $white; - border: 4px solid $black; - } - - .arrow_box::after, - .arrow_box::before { - top: 100%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - } - - .arrow_box::after { - border-color: rgba(255, 255, 255, 0); - border-top-color: $white; - border-width: 30px; - left: 50%; - margin-left: -($baseline*1.5); - } - - .arrow_box::before { - border-color: $transparent; - border-top-color: $black; - border-width: 36px; - left: 50%; - margin-left: -36px; - } - - // feature content - .wrapper-content-features { - box-shadow: 0 -1px ($baseline/4) $shadow; - padding-bottom: ($baseline*2); - padding-top: ($baseline*3); - background: $white; - } - - .content-features { - // indiv features - .feature { - @include clearfix(); - - margin: 0 0 ($baseline*2) 0; - border-bottom: 1px solid $gray-l4; - padding: 0 0 ($baseline*2) 0; - - .img { - box-sizing: border-box; - float: left; - width: flex-grid(3, 12); - margin-right: flex-gutter(); - - a { - box-sizing: border-box; - box-shadow: 0 1px ($baseline/10) $shadow-l1; - position: relative; - top: 0; - display: block; - overflow: hidden; - border: 1px solid $gray-l3; - padding: ($baseline/4); - background: $white; - - .action-zoom { - @include transition(bottom $tmg-f2 ease-in-out 0s); - - position: absolute; - bottom: -30px; - right: ($baseline/2); - opacity: 0; - - .icon { - @include border-top-radius(3px); - - @extend %t-icon4; - - display: inline-block; - padding: ($baseline/2); - background: $blue; - color: $white; - text-align: center; - } - } - - &:hover { - border-color: $blue; - - .action-zoom { - opacity: 1; - bottom: -2px; - } - } - } - - img { - display: block; - width: 100%; - height: auto; - } - } - - .copy { - float: left; - width: flex-grid(9, 12); - margin-top: -($baseline/4); - - h3 { - @extend %t-title4; - @extend %t-strong; - - margin: 0 0 ($baseline/2) 0; - } - - > p { - @extend %t-copy-lead1; - - color: $gray-d1; - } - - strong { - @extend %t-strong; - - color: $gray-d2; - } - - .list-proofpoints { - @extend %t-copy-sub1; - - @include clearfix(); - - width: flex-grid(9, 9); - margin: ($baseline*1.5) 0 0 0; - - .proofpoint { - box-sizing: border-box; - - @include transition(all $tmg-f2 ease-in-out 0s); - - border-radius: ($baseline/4); - position: relative; - top: 0; - float: left; - width: flex-grid(3, 9); - min-height: ($baseline*8); - margin-right: flex-gutter(); - padding: ($baseline*0.75) $baseline; - color: $gray-d1; - - .title { - @extend %t-copy-base; - @extend %t-strong; - - margin: 0 0 ($baseline/4) 0; - color: $gray-d3; - } - - &:hover { - @extend %ui-fake-link; - - box-shadow: 0 1px ($baseline/10) $shadow-l1; - background: $blue-l5; - top: -($baseline/5); - - .title { - color: $blue-d2; - } - } - - &:last-child { - margin-right: 0; - } - } - } - } - - - &:last-child { - margin-bottom: 0; - border: none; - padding-bottom: 0; - } - - &:nth-child(even) { - .img { - float: right; - margin-right: 0; - margin-left: flex-gutter(); - } - - .copy { - float: right; - text-align: right; - } - - .list-proofpoints { - .proofpoint { - float: right; - width: flex-grid(3, 9); - margin-left: flex-gutter(); - margin-right: 0; - - &:last-child { - margin-left: 0; - } - } - } - } - } - } - - // call to action content - .wrapper-content-cta { - position: relative; - padding: ($baseline*2) 0; - background: $white; - } - - .content-cta { - border-top: 1px solid $gray-l4; - - header { - border: none; - margin: 0; - padding: 0; - } - - .list-actions { - position: relative; - margin-top: -($baseline*1.5); - - li { - width: flex-grid(6, 12); - margin: 0 auto; - } - - .action { - display: block; - width: 100%; - text-align: center; - - &.action-primary { - @include blue-button; - - @extend %t-action1; - @extend %t-strong; - - padding: ($baseline*0.75) ($baseline/2); - text-align: center; - text-transform: uppercase; - } - - &.action-secondary { - @extend %t-action3; - - margin-top: ($baseline/2); - } - } - } - } - } -} diff --git a/cms/templates/howitworks.html b/cms/templates/howitworks.html deleted file mode 100644 index d21dff2d66a5..000000000000 --- a/cms/templates/howitworks.html +++ /dev/null @@ -1,214 +0,0 @@ -<%page expression_filter="h"/> -<%inherit file="base.html" /> -<%def name="online_help_token()"><% return "welcome" %> -<%namespace name='static' file='static_content.html'/> -<%! - from django.conf import settings - from django.utils.translation import gettext as _ - from urllib.parse import quote_plus - from openedx.core.djangolib.markup import HTML, Text -%> - -<%block name="title">${_("Welcome")} -<%block name="bodyclass">not-signedin index view-howitworks - -<%block name="content"> - -
-
-
-

${_("Welcome to {studio_name}").format( - studio_name=settings.STUDIO_NAME - )}

-

${_("{studio_name} helps manage your online courses, so you can focus on teaching them").format( - studio_name=settings.STUDIO_SHORT_NAME - )}

-
-
-
- -
-
-
-

${_("{studio_name}'s Many Features").format(studio_name=settings.STUDIO_SHORT_NAME)}

-
- -
    -
  1. -
    - - ${_('{studio_name} Helps You Keep Your Courses Organized').format(studio_name=settings.STUDIO_SHORT_NAME)} -
    ${_("{studio_name} Helps You Keep Your Courses Organized").format(studio_name=settings.STUDIO_NAME)}
    - - ${_("Enlarge image")} - -
    -
    - -
    -

    ${_("Keeping Your Course Organized")}

    -

    ${Text(_("The backbone of your course is how it is organized. {studio_name} offers an {strong_start}Outline{strong_end} editor, providing a simple hierarchy and easy drag and drop to help you and your students stay organized.")).format( - studio_name=settings.STUDIO_SHORT_NAME, - strong_start=HTML(''), - strong_end=HTML('') - )}

    - -
      -
    • -

      ${_("Simple Organization For Content")}

      -

      ${Text(_("{studio_name} uses a simple hierarchy of {strong_start}sections{strong_end} and {strong_start}subsections{strong_end} to organize your content.")).format( - studio_name=settings.STUDIO_SHORT_NAME, - strong_start=HTML(''), - strong_end=HTML('') - )}

      -
    • - -
    • -

      ${_("Change Your Mind Anytime")}

      -

      ${_("Draft your outline and build content anywhere. Simple drag and drop tools let you reorganize quickly.")}

      -
    • - -
    • -

      ${_("Go A Week Or A Semester At A Time")}

      -

      ${Text(_("Build and release {strong_start}sections{strong_end} to your students incrementally. You don't have to have it all done at once.")).format( - strong_start=HTML(''), - strong_end=HTML('') - )}

      -
    • -
    -
    -
  2. - -
  3. -
    - - ${_('Learning is More than Just Lectures')} -
    ${_("Learning is More than Just Lectures")}
    - - ${_("Enlarge image")} - -
    -
    - -
    -

    ${_("Learning is More than Just Lectures")}

    -

    ${_("{studio_name} lets you weave your content together in a way that reinforces learning. Insert videos, discussions, and a wide variety of exercises with just a few clicks.").format(studio_name=settings.STUDIO_SHORT_NAME)}

    - -
      -
    • -

      ${_("Create Learning Pathways")}

      -

      ${_("Help your students understand one concept at a time with multimedia, HTML, and exercises.")}

      -
    • - -
    • -

      ${_("Work Visually, Organize Quickly")}

      -

      ${_("Work visually and see exactly what your students will see. Reorganize all your content with drag and drop.")}

      -
    • - -
    • -

      ${_("A Broad Library of Problem Types")}

      -

      ${_("It's more than just multiple choice. {studio_name} supports more than a dozen types of problems to challenge your learners.").format(studio_name=settings.STUDIO_SHORT_NAME)}

      -
    • -
    -
    -
  4. - -
  5. -
    - - ${_('{studio_name} Gives You Simple, Fast, and Incremental Publishing. With Friends.').format(studio_name=settings.STUDIO_SHORT_NAME)} -
    ${_("{studio_name} Gives You Simple, Fast, and Incremental Publishing. With Friends.").format(studio_name=settings.STUDIO_SHORT_NAME)}
    - - ${_("Enlarge image")} - -
    -
    - -
    -

    ${_("Simple, Fast, and Incremental Publishing. With Friends.")}

    -

    ${_("{studio_name} works like web applications you already know, yet understands how you build curriculum. Instant publishing to the web when you want it, incremental release when it makes sense. And with co-authors, you can have a whole team building a course, together.").format(studio_name=settings.STUDIO_SHORT_NAME)}

    - -
      -
    • -

      ${_("Instant Changes")}

      -

      ${_("Caught a bug? No problem. When you want, your changes go live when you click Save.")}

      -
    • - -
    • -

      ${_("Release-On Date Publishing")}

      -

      ${Text(_("When you've finished a {strong_start}section{strong_end}, pick when you want it to go live and {studio_name} takes care of the rest. Build your course incrementally.")).format( - studio_name=settings.STUDIO_SHORT_NAME, - strong_start=HTML(''), - strong_end=HTML('') - )}

      -
    • - -
    • -

      ${_("Work in Teams")}

      -

      ${_("Co-authors have full access to all the same authoring tools. Make your course better through a team effort.")}

      -
    • -
    -
    -
  6. -
-
-
- -% if static.get_value('ALLOW_PUBLIC_ACCOUNT_CREATION', settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION')) and settings.FEATURES.get('SHOW_REGISTRATION_LINKS', True): -
-
-
-

${_("Sign Up for {studio_name} Today!").format(studio_name=settings.STUDIO_SHORT_NAME)}

-
- - -
-
-% endif - -
-

${_("Outlining Your Course")}

-
- -
${_("Simple two-level outline to organize your course. Drag and drop, and see your course at a glance.")}
-
- - - - ${_("close modal")} - -
- -
-

${_("More than Just Lectures")}

-
- -
${_("Quickly create videos, text snippets, inline discussions, and a variety of problem types.")}
-
- - - - ${_("close modal")} - -
- -
-

${_("Publishing on Date")}

-
- -
${_("Simply set the date of a section or subsection, and {studio_name} will publish it to your students for you.").format(studio_name=settings.STUDIO_SHORT_NAME)}
-
- - - - ${_("close modal")} - -
- diff --git a/cms/urls.py b/cms/urls.py index 90b295f92804..de35a09483ce 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -9,6 +9,7 @@ from django.contrib.admin import autodiscover as django_autodiscover from django.urls import include, path, re_path from django.utils.translation import gettext_lazy as _ +from django.views.generic import RedirectView from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView from edx_api_doc_tools import make_docs_urls @@ -92,8 +93,8 @@ path('api/', include('cms.djangoapps.api.urls', namespace='api')), # restful api - path('', contentstore_views.howitworks, name='homepage'), - path('howitworks', contentstore_views.howitworks, name='howitworks'), + path('', RedirectView.as_view(url='/home/', permanent=True), name='homepage'), + path('howitworks', RedirectView.as_view(url='/home/', permanent=True), name='howitworks'), path('signin_redirect_to_lms', contentstore_views.login_redirect_to_lms, name='login_redirect_to_lms'), path('request_course_creator', contentstore_views.request_course_creator, name='request_course_creator'), re_path(fr'^course_team/{COURSELIKE_KEY_PATTERN}(?:/(?P.+))?$', diff --git a/lms/static/sass/shared/_header.scss b/lms/static/sass/shared/_header.scss index 898933685b26..b3942b90b058 100644 --- a/lms/static/sass/shared/_header.scss +++ b/lms/static/sass/shared/_header.scss @@ -379,7 +379,6 @@ } // page-based nav states -.view-howitworks .nav-global-01, .view-courses .nav-global-02, .view-schools .nav-global-03, .view-register .nav-global-04 { @@ -899,7 +898,6 @@ } // page-based nav states -.view-howitworks .nav-global-01, .view-courses .nav-global-02, .view-schools .nav-global-03, .view-register .nav-global-04 {