feat: add share link button when hide from toc is enabled in sections (#34043)
* feat: add share link modal when hide from toc is enabled Adds a new button in the child subsections of sections with Hide From TOC enabled. This button displays a new modal with two tabs. The first tab displays a button that allows you to copy the link of that subsection to the clipboard. The second tab displays a button that allows you to copy the embedded link of the same subsection to the clipboard. Ref: https://openedx.atlassian.net/wiki/spaces/OEPM/pages/3853975595/Feature+Enhancement+Proposal+Hide+Sections+from+course+outline
This commit is contained in:
committed by
GitHub
parent
c848767369
commit
19bc5c802c
@@ -8,6 +8,7 @@ from lxml import etree
|
||||
from mimetypes import guess_type
|
||||
|
||||
from attrs import frozen, Factory
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext as _
|
||||
from opaque_keys.edx.keys import AssetKey, CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import DefinitionLocator, LocalId
|
||||
@@ -22,6 +23,7 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.xml_block import XmlMixin
|
||||
|
||||
from cms.djangoapps.models.settings.course_grading import CourseGradingModel
|
||||
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
|
||||
import openedx.core.djangoapps.content_staging.api as content_staging_api
|
||||
|
||||
from .utils import reverse_course_url, reverse_library_url, reverse_usage_url
|
||||
@@ -125,6 +127,34 @@ def xblock_studio_url(xblock, parent_xblock=None, find_parent=False):
|
||||
return reverse_usage_url('container_handler', xblock.location)
|
||||
|
||||
|
||||
def xblock_lms_url(xblock) -> str:
|
||||
"""
|
||||
Returns the LMS URL for the specified xblock.
|
||||
|
||||
Args:
|
||||
xblock: The xblock to get the LMS URL for.
|
||||
|
||||
Returns:
|
||||
str: The LMS URL for the specified xblock.
|
||||
"""
|
||||
lms_root_url = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)
|
||||
return f"{lms_root_url}/courses/{xblock.location.course_key}/jump_to/{xblock.location}"
|
||||
|
||||
|
||||
def xblock_embed_lms_url(xblock) -> str:
|
||||
"""
|
||||
Returns the LMS URL for the specified xblock in embed mode.
|
||||
|
||||
Args:
|
||||
xblock: The xblock to get the LMS URL for.
|
||||
|
||||
Returns:
|
||||
str: The LMS URL for the specified xblock in embed mode.
|
||||
"""
|
||||
lms_root_url = configuration_helpers.get_value('LMS_ROOT_URL', settings.LMS_ROOT_URL)
|
||||
return f"{lms_root_url}/xblock/{xblock.location}"
|
||||
|
||||
|
||||
def xblock_type_display_name(xblock, default_display_name=None):
|
||||
"""
|
||||
Returns the display name for the specified type of xblock. Note that an instance can be passed in
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
Unit tests for helpers.py.
|
||||
"""
|
||||
|
||||
|
||||
from unittest.mock import patch, Mock
|
||||
from urllib.parse import quote
|
||||
|
||||
from cms.djangoapps.contentstore.tests.utils import CourseTestCase
|
||||
from xmodule.modulestore.tests.factories import BlockFactory, LibraryFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from ...helpers import xblock_studio_url, xblock_type_display_name
|
||||
from ...helpers import xblock_embed_lms_url, xblock_lms_url, xblock_studio_url, xblock_type_display_name
|
||||
|
||||
|
||||
class HelpersTestCase(CourseTestCase):
|
||||
@@ -60,6 +60,44 @@ class HelpersTestCase(CourseTestCase):
|
||||
expected_url = f'/library/{str(library.location.library_key)}'
|
||||
self.assertEqual(xblock_studio_url(library), expected_url)
|
||||
|
||||
@patch('cms.djangoapps.contentstore.helpers.configuration_helpers.get_value')
|
||||
def test_xblock_lms_url(self, mock_get_value: Mock):
|
||||
mock_get_value.return_value = 'lms.example.com'
|
||||
|
||||
# Verify chapter URL
|
||||
chapter = BlockFactory.create(
|
||||
parent_location=self.course.location, category='chapter', display_name="Week 1"
|
||||
)
|
||||
self.assertEqual(
|
||||
xblock_lms_url(chapter),
|
||||
f"lms.example.com/courses/{chapter.location.course_key}/jump_to/{chapter.location}"
|
||||
)
|
||||
|
||||
# Verify sequential URL
|
||||
sequential = BlockFactory.create(
|
||||
parent_location=chapter.location, category='sequential', display_name="Lesson 1"
|
||||
)
|
||||
self.assertEqual(
|
||||
xblock_lms_url(sequential),
|
||||
f"lms.example.com/courses/{sequential.location.course_key}/jump_to/{sequential.location}"
|
||||
)
|
||||
|
||||
@patch('cms.djangoapps.contentstore.helpers.configuration_helpers.get_value')
|
||||
def test_xblock_embed_lms_url(self, mock_get_value: Mock):
|
||||
mock_get_value.return_value = 'lms.example.com'
|
||||
|
||||
# Verify chapter URL
|
||||
chapter = BlockFactory.create(
|
||||
parent_location=self.course.location, category='chapter', display_name="Week 1"
|
||||
)
|
||||
self.assertEqual(xblock_embed_lms_url(chapter), f"lms.example.com/xblock/{chapter.location}")
|
||||
|
||||
# Verify sequential URL
|
||||
sequential = BlockFactory.create(
|
||||
parent_location=chapter.location, category='sequential', display_name="Lesson 1"
|
||||
)
|
||||
self.assertEqual(xblock_embed_lms_url(sequential), f"lms.example.com/xblock/{sequential.location}")
|
||||
|
||||
def test_xblock_type_display_name(self):
|
||||
|
||||
# Verify chapter type display name
|
||||
|
||||
@@ -78,6 +78,8 @@ from ..helpers import (
|
||||
get_parent_xblock,
|
||||
import_staged_content_from_user_clipboard,
|
||||
is_unit,
|
||||
xblock_embed_lms_url,
|
||||
xblock_lms_url,
|
||||
xblock_primary_child_category,
|
||||
xblock_studio_url,
|
||||
xblock_type_display_name,
|
||||
@@ -1070,6 +1072,8 @@ def create_xblock_info( # lint-amnesty, pylint: disable=too-many-statements
|
||||
"published": published,
|
||||
"published_on": published_on,
|
||||
"studio_url": xblock_studio_url(xblock, parent_xblock),
|
||||
"lms_url": xblock_lms_url(xblock),
|
||||
"embed_lms_url": xblock_embed_lms_url(xblock),
|
||||
"released_to_students": datetime.now(UTC) > xblock.start,
|
||||
"release_date": release_date,
|
||||
"visibility_state": visibility_state,
|
||||
|
||||
85
cms/static/images/subsection-embed.svg
Normal file
85
cms/static/images/subsection-embed.svg
Normal file
@@ -0,0 +1,85 @@
|
||||
<svg width="225" height="158" viewBox="0 0 225 158" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_60_202)">
|
||||
<rect width="225" height="158" rx="5" fill="white"/>
|
||||
<rect width="225" height="158" rx="5" fill="white"/>
|
||||
<g filter="url(#filter0_d_60_202)">
|
||||
<rect x="19" y="15" width="186" height="129" rx="4" fill="white"/>
|
||||
</g>
|
||||
<rect x="196.6" y="22" width="5" height="66" rx="2.5" fill="#D9D9D9">
|
||||
<animate attributeName="y" values="22;40;22" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<g clip-path="url(#clip1_60_202)">
|
||||
<rect x="118.899" y="33.6089" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="33.6089;25.6089;33.6089" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="65.4346" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="65.4346;57.4346;65.4346" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="38.9131" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="38.9131;30.9131;38.9131" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="70.7393" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="70.7393;62.7393;70.7393" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="44.2173" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="44.2173;36.2173;44.2173" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="76.0435" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="76.0435;68.0435;76.0435" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="97.0869" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="97.0869;89.0869;97.0869" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="49.5215" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="49.5215;41.5215;49.5215" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="81.3477" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="81.3477;73.3477;81.3477" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="102.391" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="102.391;94.3911;102.391" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="54.8262" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="54.8262;46.8262;54.8262" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="86.6523" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="86.6523;78.6523;86.6523" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="25" y="124" width="165" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="124;116;124" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="25" y="130" width="165" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="130;122;130" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="25" y="136" width="165" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="136;128;136" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="25.1884" y="23" width="164.435" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="23;15;23" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="60.1304" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="60.1304;52.1304;60.1304" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="91.9565" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="91.9565;83.9565;91.9565" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="118.899" y="97.0723" width="70.7246" height="3.53623" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="97.0723;89.0723;97.0723" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="25" y="142" width="165" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="142;134;142" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<path d="M25.1884 44.5965C25.1884 41.6824 26.341 38.8876 28.3927 36.8271C30.4444 34.7665 33.227 33.6089 36.1286 33.6089L101.77 33.6089C104.671 33.6089 107.454 34.7665 109.506 36.8271C111.557 38.8876 112.71 41.6824 112.71 44.5965L112.71 99.5343C112.71 102.448 111.557 105.243 109.506 107.304C107.454 109.364 104.671 110.522 101.77 110.522L36.1286 110.522C33.227 110.522 30.4444 109.364 28.3927 107.304C26.341 105.243 25.1884 102.448 25.1884 99.5343L25.1884 44.5965ZM30.6585 94.0406L30.6585 99.5343C30.6585 100.991 31.2348 102.389 32.2606 103.419C33.2865 104.449 34.6778 105.028 36.1286 105.028L101.77 105.028C103.221 105.028 104.612 104.449 105.638 103.419C106.664 102.389 107.24 100.991 107.24 99.5343L107.24 80.3061L86.5794 69.6097C86.0664 69.3516 85.4856 69.2621 84.9192 69.3538C84.3528 69.4455 83.8294 69.7137 83.4231 70.1206L63.129 90.5026L48.5785 80.7676C48.0532 80.4163 47.423 80.2583 46.7949 80.3204C46.1669 80.3825 45.5795 80.6608 45.1324 81.1082L30.6585 94.0406ZM58.009 58.3309C58.009 56.1454 57.1445 54.0493 55.6058 52.5039C54.067 50.9585 51.98 50.0903 49.8038 50.0903C47.6277 50.0903 45.5407 50.9585 44.0019 52.5039C42.4631 54.0493 41.5987 56.1454 41.5987 58.3309C41.5987 60.5165 42.4631 62.6126 44.0019 64.158C45.5407 65.7034 47.6277 66.5716 49.8038 66.5716C51.98 66.5716 54.067 65.7034 55.6058 64.158C57.1445 62.6126 58.009 60.5165 58.009 58.3309Z" fill="#EBEBEB">
|
||||
<animate attributeName="d" values="M25.1884 44.5965C25.1884 41.6824 26.341 38.8876 28.3927 36.8271C30.4444 34.7665 33.227 33.6089 36.1286 33.6089L101.77 33.6089C104.671 33.6089 107.454 34.7665 109.506 36.8271C111.557 38.8876 112.71 41.6824 112.71 44.5965L112.71 99.5343C112.71 102.448 111.557 105.243 109.506 107.304C107.454 109.364 104.671 110.522 101.77 110.522L36.1286 110.522C33.227 110.522 30.4444 109.364 28.3927 107.304C26.341 105.243 25.1884 102.448 25.1884 99.5343L25.1884 44.5965ZM30.6585 94.0406L30.6585 99.5343C30.6585 100.991 31.2348 102.389 32.2606 103.419C33.2865 104.449 34.6778 105.028 36.1286 105.028L101.77 105.028C103.221 105.028 104.612 104.449 105.638 103.419C106.664 102.389 107.24 100.991 107.24 99.5343L107.24 80.3061L86.5794 69.6097C86.0664 69.3516 85.4856 69.2621 84.9192 69.3538C84.3528 69.4455 83.8294 69.7137 83.4231 70.1206L63.129 90.5026L48.5785 80.7676C48.0532 80.4163 47.423 80.2583 46.7949 80.3204C46.1669 80.3825 45.5795 80.6608 45.1324 81.1082L30.6585 94.0406ZM58.009 58.3309C58.009 56.1454 57.1445 54.0493 55.6058 52.5039C54.067 50.9585 51.98 50.0903 49.8038 50.0903C47.6277 50.0903 45.5407 50.9585 44.0019 52.5039C42.4631 54.0493 41.5987 56.1454 41.5987 58.3309C41.5987 60.5165 42.4631 62.6126 44.0019 64.158C45.5407 65.7034 47.6277 66.5716 49.8038 66.5716C51.98 66.5716 54.067 65.7034 55.6058 64.158C57.1445 62.6126 58.009 60.5165 58.009 58.3309Z;M25.1884 36.5965C25.1884 33.6824 26.341 30.8876 28.3927 28.8271C30.4444 26.7665 33.227 25.6089 36.1286 25.6089L101.77 25.6089C104.671 25.6089 107.454 26.7665 109.506 28.8271C111.557 30.8876 112.71 33.6824 112.71 36.5965L112.71 91.5343C112.71 94.4484 111.557 97.2432 109.506 99.3037C107.454 101.364 104.671 102.522 101.77 102.522L36.1286 102.522C33.227 102.522 30.4444 101.364 28.3927 99.3037C26.341 97.2432 25.1884 94.4484 25.1884 91.5343L25.1884 36.5965ZM30.6585 86.0406L30.6585 91.5343C30.6585 92.9914 31.2348 94.3888 32.2606 95.419C33.2865 96.4493 34.6778 97.0281 36.1286 97.0281L101.77 97.0281C103.221 97.0281 104.612 96.4493 105.638 95.419C106.664 94.3888 107.24 92.9914 107.24 91.5343L107.24 72.3061L86.5794 61.6097C86.0664 61.3516 85.4856 61.2621 84.9192 61.3538C84.3528 61.4455 83.8294 61.7137 83.4231 62.1206L63.129 82.5026L48.5785 72.7676C48.0532 72.4163 47.423 72.2583 46.7949 72.3204C46.1669 72.3825 45.5795 72.6608 45.1324 73.1082L30.6585 86.0406ZM58.009 50.3309C58.009 48.1454 57.1445 46.0493 55.6058 44.5039C54.067 42.9585 51.98 42.0903 49.8038 42.0903C47.6277 42.0903 45.5407 42.9585 44.0019 44.5039C42.4631 46.0493 41.5987 48.1454 41.5987 50.3309C41.5987 52.5165 42.4631 54.6126 44.0019 56.158C45.5407 57.7034 47.6277 58.5716 49.8038 58.5716C51.98 58.5716 54.067 57.7034 55.6058 56.158C57.1445 54.6126 58.009 52.5165 58.009 50.3309Z;M25.1884 44.5965C25.1884 41.6824 26.341 38.8876 28.3927 36.8271C30.4444 34.7665 33.227 33.6089 36.1286 33.6089L101.77 33.6089C104.671 33.6089 107.454 34.7665 109.506 36.8271C111.557 38.8876 112.71 41.6824 112.71 44.5965L112.71 99.5343C112.71 102.448 111.557 105.243 109.506 107.304C107.454 109.364 104.671 110.522 101.77 110.522L36.1286 110.522C33.227 110.522 30.4444 109.364 28.3927 107.304C26.341 105.243 25.1884 102.448 25.1884 99.5343L25.1884 44.5965ZM30.6585 94.0406L30.6585 99.5343C30.6585 100.991 31.2348 102.389 32.2606 103.419C33.2865 104.449 34.6778 105.028 36.1286 105.028L101.77 105.028C103.221 105.028 104.612 104.449 105.638 103.419C106.664 102.389 107.24 100.991 107.24 99.5343L107.24 80.3061L86.5794 69.6097C86.0664 69.3516 85.4856 69.2621 84.9192 69.3538C84.3528 69.4455 83.8294 69.7137 83.4231 70.1206L63.129 90.5026L48.5785 80.7676C48.0532 80.4163 47.423 80.2583 46.7949 80.3204C46.1669 80.3825 45.5795 80.6608 45.1324 81.1082L30.6585 94.0406ZM58.009 58.3309C58.009 56.1454 57.1445 54.0493 55.6058 52.5039C54.067 50.9585 51.98 50.0903 49.8038 50.0903C47.6277 50.0903 45.5407 50.9585 44.0019 52.5039C42.4631 54.0493 41.5987 56.1454 41.5987 58.3309C41.5987 60.5165 42.4631 62.6126 44.0019 64.158C45.5407 65.7034 47.6277 66.5716 49.8038 66.5716C51.98 66.5716 54.067 65.7034 55.6058 64.158C57.1445 62.6126 58.009 60.5165 58.009 58.3309Z" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></path>
|
||||
<rect x="24" y="117" width="167" height="41" rx="12" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="117;109;117" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="38" y="136" width="139" height="22" rx="2" fill="#CBCBCB" fill-opacity="0.5">
|
||||
<animate attributeName="y" values="136;128;136" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<line x1="24" y1="127.807" x2="191" y2="127.807" stroke="#DBDBDB">
|
||||
<animate attributeName="y1" values="127.807;119.807;127.807" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/>
|
||||
<animate attributeName="y2" values="127.807;119.807;127.807" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/>
|
||||
<animate attributeName="stroke-opacity" values="1;0.5;1" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></line>
|
||||
</g>
|
||||
</g>
|
||||
<rect x="0.5" y="0.5" width="224" height="157" rx="4.5" stroke="black" stroke-opacity="0.1"/>
|
||||
<defs>
|
||||
<filter id="filter0_d_60_202" x="14.6" y="10.6" width="194.8" height="137.8" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2.2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_60_202">
|
||||
</feBlend>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_60_202" result="shape">
|
||||
</feBlend>
|
||||
|
||||
</filter>
|
||||
<clipPath id="clip0_60_202">
|
||||
<rect width="225" height="158" rx="5" fill="white"/>
|
||||
</clipPath>
|
||||
<clipPath id="clip1_60_202">
|
||||
<rect width="165" height="121" fill="white" transform="translate(25 23)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
60
cms/static/images/subsection-full-page.svg
Normal file
60
cms/static/images/subsection-full-page.svg
Normal file
@@ -0,0 +1,60 @@
|
||||
<svg width="225" height="157" viewBox="0 0 225 157" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="225" height="157" rx="5" fill="white"/>
|
||||
<rect x="0.5" y="0.5" width="224" height="156" rx="4.5" stroke="black" stroke-opacity="0.1"/>
|
||||
<rect width="225" height="157" rx="5" fill="white"/>
|
||||
<rect x="17" y="7" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="7;0;7" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="17" y="13" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="13;6;13" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="17" y="19" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="19;12;19" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="17" y="25" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="25;18;25" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="17" y="42" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="42;35;42" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="52" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="52;45;52" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="88" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="88;81;88" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="118" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="118;111;118" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="58" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="58;51;58" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="94" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="94;87;94" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="124" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="124;117;124" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="64" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="64;57;64" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="100" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="100;93;100" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="70" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="70;63;70" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="106" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="106;99;106" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="76" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="76;69;76" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="82" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="82;75;82" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect x="110" y="112" width="99" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="112;105;112" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<path d="M17 62.7143C17 59.8727 18.1194 57.1475 20.112 55.1381C22.1046 53.1288 24.8071 52 27.625 52L91.375 52C94.1929 52 96.8954 53.1288 98.888 55.1381C100.881 57.1475 102 59.8727 102 62.7143L102 116.286C102 119.127 100.881 121.853 98.888 123.862C96.8954 125.871 94.1929 127 91.375 127L27.625 127C24.8071 127 22.1046 125.871 20.112 123.862C18.1194 121.853 17 119.127 17 116.286L17 62.7143ZM22.3125 110.929L22.3125 116.286C22.3125 117.707 22.8722 119.069 23.8685 120.074C24.8648 121.078 26.216 121.643 27.625 121.643L91.375 121.643C92.784 121.643 94.1352 121.078 95.1315 120.074C96.1278 119.069 96.6875 117.707 96.6875 116.286L96.6875 97.5357L76.6222 87.1054C76.124 86.8537 75.5599 86.7664 75.0098 86.8558C74.4597 86.9452 73.9514 87.2068 73.5569 87.6036L53.8475 107.479L39.7163 97.9857C39.206 97.6432 38.594 97.4891 37.984 97.5496C37.374 97.6102 36.8036 97.8816 36.3694 98.3179L22.3125 110.929ZM48.875 76.1071C48.875 73.9759 48.0354 71.932 46.541 70.425C45.0466 68.918 43.0197 68.0714 40.9062 68.0714C38.7928 68.0714 36.7659 68.918 35.2715 70.425C33.7771 71.932 32.9375 73.9759 32.9375 76.1071C32.9375 78.2383 33.7771 80.2823 35.2715 81.7893C36.7659 83.2962 38.7928 84.1429 40.9062 84.1429C43.0197 84.1429 45.0466 83.2962 46.541 81.7893C48.0354 80.2823 48.875 78.2383 48.875 76.1071Z" fill="#EBEBEB">
|
||||
<animate attributeName="d" values="M17 62.7143C17 59.8727 18.1194 57.1475 20.112 55.1381C22.1046 53.1288 24.8071 52 27.625 52L91.375 52C94.1929 52 96.8954 53.1288 98.888 55.1381C100.881 57.1475 102 59.8727 102 62.7143L102 116.286C102 119.127 100.881 121.853 98.888 123.862C96.8954 125.871 94.1929 127 91.375 127L27.625 127C24.8071 127 22.1046 125.871 20.112 123.862C18.1194 121.853 17 119.127 17 116.286L17 62.7143ZM22.3125 110.929L22.3125 116.286C22.3125 117.707 22.8722 119.069 23.8685 120.074C24.8648 121.078 26.216 121.643 27.625 121.643L91.375 121.643C92.784 121.643 94.1352 121.078 95.1315 120.074C96.1278 119.069 96.6875 117.707 96.6875 116.286L96.6875 97.5357L76.6222 87.1054C76.124 86.8537 75.5599 86.7664 75.0098 86.8558C74.4597 86.9452 73.9514 87.2068 73.5569 87.6036L53.8475 107.479L39.7163 97.9857C39.206 97.6432 38.594 97.4891 37.984 97.5496C37.374 97.6102 36.8036 97.8816 36.3694 98.3179L22.3125 110.929ZM48.875 76.1071C48.875 73.9759 48.0354 71.932 46.541 70.425C45.0466 68.918 43.0197 68.0714 40.9062 68.0714C38.7928 68.0714 36.7659 68.918 35.2715 70.425C33.7771 71.932 32.9375 73.9759 32.9375 76.1071C32.9375 78.2383 33.7771 80.2823 35.2715 81.7893C36.7659 83.2962 38.7928 84.1429 40.9062 84.1429C43.0197 84.1429 45.0466 83.2962 46.541 81.7893C48.0354 80.2823 48.875 78.2383 48.875 76.1071Z;M17 55.7143C17 52.8727 18.1194 50.1475 20.112 48.1381C22.1046 46.1288 24.8071 45 27.625 45L91.375 45C94.1929 45 96.8954 46.1288 98.888 48.1381C100.881 50.1475 102 52.8727 102 55.7143L102 109.286C102 112.127 100.881 114.853 98.888 116.862C96.8954 118.871 94.1929 120 91.375 120L27.625 120C24.8071 120 22.1046 118.871 20.112 116.862C18.1194 114.853 17 112.127 17 109.286L17 55.7143ZM22.3125 103.929L22.3125 109.286C22.3125 110.707 22.8722 112.069 23.8685 113.074C24.8648 114.078 26.216 114.643 27.625 114.643L91.375 114.643C92.784 114.643 94.1352 114.078 95.1315 113.074C96.1278 112.069 96.6875 110.707 96.6875 109.286L96.6875 90.5357L76.6222 80.1054C76.124 79.8537 75.5599 79.7664 75.0098 79.8558C74.4597 79.9452 73.9514 80.2068 73.5569 80.6036L53.8475 100.479L39.7163 90.9857C39.206 90.6432 38.594 90.4891 37.984 90.5496C37.374 90.6102 36.8036 90.8816 36.3694 91.3179L22.3125 103.929ZM48.875 69.1071C48.875 66.9759 48.0354 64.932 46.541 63.425C45.0466 61.918 43.0197 61.0714 40.9062 61.0714C38.7928 61.0714 36.7659 61.918 35.2715 63.425C33.7771 64.932 32.9375 66.9759 32.9375 69.1071C32.9375 71.2383 33.7771 73.2823 35.2715 74.7893C36.7659 76.2962 38.7928 77.1429 40.9062 77.1429C43.0197 77.1429 45.0466 76.2962 46.541 74.7893C48.0354 73.2823 48.875 71.2383 48.875 69.1071Z;M17 62.7143C17 59.8727 18.1194 57.1475 20.112 55.1381C22.1046 53.1288 24.8071 52 27.625 52L91.375 52C94.1929 52 96.8954 53.1288 98.888 55.1381C100.881 57.1475 102 59.8727 102 62.7143L102 116.286C102 119.127 100.881 121.853 98.888 123.862C96.8954 125.871 94.1929 127 91.375 127L27.625 127C24.8071 127 22.1046 125.871 20.112 123.862C18.1194 121.853 17 119.127 17 116.286L17 62.7143ZM22.3125 110.929L22.3125 116.286C22.3125 117.707 22.8722 119.069 23.8685 120.074C24.8648 121.078 26.216 121.643 27.625 121.643L91.375 121.643C92.784 121.643 94.1352 121.078 95.1315 120.074C96.1278 119.069 96.6875 117.707 96.6875 116.286L96.6875 97.5357L76.6222 87.1054C76.124 86.8537 75.5599 86.7664 75.0098 86.8558C74.4597 86.9452 73.9514 87.2068 73.5569 87.6036L53.8475 107.479L39.7163 97.9857C39.206 97.6432 38.594 97.4891 37.984 97.5496C37.374 97.6102 36.8036 97.8816 36.3694 98.3179L22.3125 110.929ZM48.875 76.1071C48.875 73.9759 48.0354 71.932 46.541 70.425C45.0466 68.918 43.0197 68.0714 40.9062 68.0714C38.7928 68.0714 36.7659 68.918 35.2715 70.425C33.7771 71.932 32.9375 73.9759 32.9375 76.1071C32.9375 78.2383 33.7771 80.2823 35.2715 81.7893C36.7659 83.2962 38.7928 84.1429 40.9062 84.1429C43.0197 84.1429 45.0466 83.2962 46.541 81.7893C48.0354 80.2823 48.875 78.2383 48.875 76.1071Z" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></path>
|
||||
<rect x="17" y="130" width="192" height="4" fill="#EBEBEB">
|
||||
<animate attributeName="y" values="130;123;130" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<rect y="23" width="225" height="12" fill="#D9D9D9"/>
|
||||
<path d="M0 5C0 2.23858 2.23858 0 5 0H220C222.761 0 225 2.23858 225 5V23H0V5Z" fill="#238FC9"/>
|
||||
<rect x="17" y="7" width="32" height="10" rx="2" fill="#186E9D"/>
|
||||
<rect x="180" y="7" width="29" height="10" rx="2" fill="#186E9D"/>
|
||||
<rect x="116" y="7" width="59" height="10" rx="2" fill="#186E9D"/>
|
||||
<rect x="17" y="34" width="22" height="1" fill="#238FC9"/>
|
||||
<rect x="17" y="27" width="22" height="4" rx="2" fill="#ADADAD"/>
|
||||
<rect x="43" y="27" width="22" height="4" rx="2" fill="#ADADAD"/>
|
||||
<rect x="68" y="27" width="22" height="4" rx="2" fill="#ADADAD"/>
|
||||
<rect x="94" y="27" width="22" height="4" rx="2" fill="#ADADAD"/>
|
||||
<rect x="216" y="41" width="5" height="66" rx="2.5" fill="#D9D9D9">
|
||||
<animate attributeName="y" values="41;60;41" begin="0s" dur="2.5s" repeatCount="indefinite" calcMode="linear" keyTimes="0;0.5;1"/></rect>
|
||||
<path d="M0 134H225V152C225 154.761 222.761 157 220 157H5C2.23858 157 0 154.761 0 152V134Z" fill="#238FC9"/>
|
||||
<rect x="17" y="140" width="32" height="10" rx="2" fill="#186E9D"/>
|
||||
<rect x="52" y="143" width="156" height="5" rx="2" fill="#186E9D"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
@@ -323,7 +323,8 @@ describe('CourseOutlinePage', function() {
|
||||
'staff-lock-editor', 'unit-access-editor', 'discussion-editor', 'content-visibility-editor',
|
||||
'settings-modal-tabs', 'timed-examination-preference-editor', 'access-editor',
|
||||
'show-correctness-editor', 'highlights-editor', 'highlights-enable-editor',
|
||||
'course-highlights-enable', 'course-video-sharing-enable', 'summary-configuration-editor'
|
||||
'course-highlights-enable', 'course-video-sharing-enable', 'summary-configuration-editor',
|
||||
'subsection-share-link-modal-tabs', 'full-page-share-link-editor', 'embed-link-share-link-editor',
|
||||
]);
|
||||
appendSetFixtures(mockOutlinePage);
|
||||
mockCourseJSON = createMockCourseJSON({}, [
|
||||
|
||||
31
cms/static/js/utils/copy_to_clipboard.js
Normal file
31
cms/static/js/utils/copy_to_clipboard.js
Normal file
@@ -0,0 +1,31 @@
|
||||
define(["jquery"], function ($) {
|
||||
"use strict";
|
||||
function copyToClipboard(id, textToCopy) {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(textToCopy);
|
||||
changeButtonText(id);
|
||||
return;
|
||||
}
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = textToCopy;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(textArea);
|
||||
changeButtonText(id);
|
||||
}
|
||||
|
||||
function changeButtonText(id, delay = 2000) {
|
||||
const buttonId = `#${id}`;
|
||||
const textClass = ".copy-link-button-text";
|
||||
|
||||
const previewShareLinkText = $(buttonId).find(textClass).html();
|
||||
const shareLinkCopiedText = gettext("Copied");
|
||||
$(buttonId).find(textClass).text(shareLinkCopiedText);
|
||||
|
||||
setTimeout(() => {
|
||||
$(buttonId).find(textClass).text(previewShareLinkText);
|
||||
}, delay);
|
||||
}
|
||||
return { copyToClipboard };
|
||||
});
|
||||
@@ -453,6 +453,19 @@ function(
|
||||
}
|
||||
},
|
||||
|
||||
subsectionShareLinkXBlock: function() {
|
||||
var modal = CourseOutlineModalsFactory.getModal('subsection_share_link', this.model, {
|
||||
onSave: this.refresh.bind(this),
|
||||
xblockType: XBlockViewUtils.getXBlockType(
|
||||
this.model.get('category'), this.parentView.model, true
|
||||
)
|
||||
});
|
||||
|
||||
if (modal) {
|
||||
modal.show();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* If the new "Actions" menu is enabled, most actions like Configure,
|
||||
* Duplicate, Move, Delete, etc. are moved into this menu. For this
|
||||
@@ -501,6 +514,10 @@ function(
|
||||
this.highlightsXBlock();
|
||||
}
|
||||
}.bind(this));
|
||||
element.find('.subsection-share-link-button').click(function(event) {
|
||||
event.preventDefault();
|
||||
this.subsectionShareLinkXBlock();
|
||||
}.bind(this));
|
||||
element.find('.copy-button').click((event) => {
|
||||
event.preventDefault();
|
||||
this.copyXBlock();
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
*/
|
||||
define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
'js/views/modals/base_modal', 'date', 'js/views/utils/xblock_utils',
|
||||
'js/utils/date_utils', 'edx-ui-toolkit/js/utils/html-utils',
|
||||
'js/utils/date_utils', 'js/utils/copy_to_clipboard', 'edx-ui-toolkit/js/utils/html-utils',
|
||||
'edx-ui-toolkit/js/utils/string-utils'
|
||||
], function(
|
||||
$, Backbone, _, gettext, BaseView, BaseModal, date, XBlockViewUtils, DateUtils, HtmlUtils, StringUtils
|
||||
$, Backbone, _, gettext, BaseView, BaseModal, date, XBlockViewUtils, DateUtils, ClipboardUtils, HtmlUtils, StringUtils
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
@@ -19,7 +19,8 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
ReleaseDateEditor, DueDateEditor, SelfPacedDueDateEditor, GradingEditor, PublishEditor, AbstractVisibilityEditor,
|
||||
StaffLockEditor, UnitAccessEditor, ContentVisibilityEditor, TimedExaminationPreferenceEditor,
|
||||
AccessEditor, ShowCorrectnessEditor, HighlightsEditor, HighlightsEnableXBlockModal, HighlightsEnableEditor,
|
||||
DiscussionEditor, SummaryConfigurationEditor;
|
||||
DiscussionEditor, SummaryConfigurationEditor, SubsectionShareLinkXBlockModal, FullPageShareLinkEditor,
|
||||
EmbedLinkShareLinkEditor;
|
||||
|
||||
CourseOutlineXBlockModal = BaseModal.extend({
|
||||
events: _.extend({}, BaseModal.prototype.events, {
|
||||
@@ -298,6 +299,71 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
}
|
||||
});
|
||||
|
||||
SubsectionShareLinkXBlockModal = CourseOutlineXBlockModal.extend({
|
||||
|
||||
initializeEditors: function() {
|
||||
var tabsTemplate;
|
||||
var tabs = this.options.tabs;
|
||||
if (tabs && tabs.length > 0) {
|
||||
tabsTemplate = this.loadTemplate('subsection-share-link-modal-tabs');
|
||||
HtmlUtils.setHtml(this.$('.modal-section'), HtmlUtils.HTML(tabsTemplate({tabs: tabs})));
|
||||
_.each(this.options.tabs, function(tab) {
|
||||
// eslint-disable-next-line prefer-spread
|
||||
this.options.editors.push.apply(
|
||||
this.options.editors,
|
||||
_.map(tab.editors, function(Editor) {
|
||||
return new Editor({
|
||||
parent: this,
|
||||
parentElement: this.$(`.modal-section .${tab.name}`),
|
||||
model: this.model,
|
||||
xblockType: this.options.xblockType,
|
||||
});
|
||||
}, this)
|
||||
);
|
||||
}, this);
|
||||
this.showTab(tabs[0].name);
|
||||
} else {
|
||||
CourseOutlineXBlockModal.prototype.initializeEditors.call(this);
|
||||
}
|
||||
},
|
||||
|
||||
events: _.extend({}, CourseOutlineXBlockModal.prototype.events, {
|
||||
'click .subsection-share-link-tab-button': 'handleShowTab',
|
||||
'click #full-page-link-button': 'copyToClipboard',
|
||||
'click #embed-link-button': 'copyToClipboard',
|
||||
}),
|
||||
|
||||
getTitle: function() {
|
||||
return StringUtils.interpolate(
|
||||
gettext('Share {display_name} subsection'),
|
||||
{display_name: this.model.get('display_name')}
|
||||
);
|
||||
},
|
||||
|
||||
copyToClipboard: function(event) {
|
||||
return ClipboardUtils.copyToClipboard(
|
||||
$(event.currentTarget).attr('id'),
|
||||
$(event.currentTarget).data('clipboard-text')
|
||||
);
|
||||
},
|
||||
|
||||
addActionButtons: function() {
|
||||
this.addActionButton('cancel', gettext('Close'));
|
||||
},
|
||||
|
||||
handleShowTab: function(event) {
|
||||
event.preventDefault();
|
||||
this.showTab($(event.target).data('tab'));
|
||||
},
|
||||
|
||||
showTab: function(tab) {
|
||||
this.$('.modal-section .subsection-share-link-tab-button').removeClass('active');
|
||||
this.$(`.modal-section .subsection-share-link-tab-button[data-tab="${tab}"]`).addClass('active');
|
||||
this.$('.modal-section .subsection-share-link-tab').hide();
|
||||
this.$(`.modal-section .${tab}`).show();
|
||||
}
|
||||
});
|
||||
|
||||
AbstractEditor = BaseView.extend({
|
||||
tagName: 'section',
|
||||
templateName: null,
|
||||
@@ -307,7 +373,6 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
this.parentElement = this.options.parentElement;
|
||||
this.render();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var xblockInfo = this.model;
|
||||
var isTimeLimited = xblockInfo.get('is_time_limited');
|
||||
@@ -316,6 +381,8 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
var isOnboardingExam = xblockInfo.get('is_onboarding_exam');
|
||||
var enableHideFromTOCUI = xblockInfo.get('enable_hide_from_toc_ui');
|
||||
var hideFromTOC = xblockInfo.get('hide_from_toc');
|
||||
var lmsUrl = xblockInfo.get('lms_url');
|
||||
var embedLmsUrl = xblockInfo.get('embed_lms_url');
|
||||
var html = this.template($.extend({}, {
|
||||
xblockInfo: xblockInfo,
|
||||
xblockType: this.options.xblockType,
|
||||
@@ -327,6 +394,8 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
isOnboardingExam: isOnboardingExam,
|
||||
enableHideFromTOCUI: enableHideFromTOCUI,
|
||||
hideFromTOC: hideFromTOC,
|
||||
lmsUrl: lmsUrl,
|
||||
embedLmsUrl: embedLmsUrl,
|
||||
isTimedExam: isTimeLimited && !(
|
||||
isProctoredExam || isPracticeExam || isOnboardingExam
|
||||
),
|
||||
@@ -509,6 +578,16 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
}
|
||||
});
|
||||
|
||||
FullPageShareLinkEditor = AbstractEditor.extend({
|
||||
templateName: 'full-page-share-link-editor',
|
||||
className: 'edit-settings-full-page-share-link',
|
||||
});
|
||||
|
||||
EmbedLinkShareLinkEditor = AbstractEditor.extend({
|
||||
templateName: 'embed-link-share-link-editor',
|
||||
className: 'edit-settings-embed-link-share-link',
|
||||
});
|
||||
|
||||
TimedExaminationPreferenceEditor = AbstractEditor.extend({
|
||||
templateName: 'timed-examination-preference-editor',
|
||||
className: 'edit-settings-timed-examination',
|
||||
@@ -1289,7 +1368,10 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
return this.getHighlightsModal(xblockInfo, options);
|
||||
} else if (type === 'highlights_enable') {
|
||||
return this.getHighlightsEnableModal(xblockInfo, options);
|
||||
} else {
|
||||
} else if (type === 'subsection_share_link') {
|
||||
return this.getSubsectionShareLinkModal(xblockInfo, options);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
@@ -1395,6 +1477,26 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
|
||||
editors: [HighlightsEnableEditor],
|
||||
model: xblockInfo
|
||||
}, options));
|
||||
},
|
||||
|
||||
getSubsectionShareLinkModal: function(xblockInfo, options) {
|
||||
let tabs = [
|
||||
{
|
||||
name: 'full_page',
|
||||
displayName: gettext('Full Page'),
|
||||
editors: [FullPageShareLinkEditor],
|
||||
},
|
||||
{
|
||||
name: 'embed_link',
|
||||
displayName: gettext('Embed Link'),
|
||||
editors: [EmbedLinkShareLinkEditor],
|
||||
}
|
||||
]
|
||||
return new SubsectionShareLinkXBlockModal($.extend({
|
||||
tabs: tabs,
|
||||
editors: [FullPageShareLinkEditor, EmbedLinkShareLinkEditor],
|
||||
model: xblockInfo
|
||||
}, options));
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -113,6 +113,7 @@ function($, _, gettext, BaseView, ViewUtils, XBlockViewUtils, XBlockStringFieldE
|
||||
hasExplicitStaffLock: this.model.get('has_explicit_staff_lock'),
|
||||
staffOnlyMessage: this.model.get('staff_only_message'),
|
||||
hideFromTOCMessage: this.model.get('hide_from_toc_message'),
|
||||
enableHideFromTOC: this.model.get('hide_from_toc'),
|
||||
course: course,
|
||||
enableCopyPasteUnits: this.model.get("enable_copy_paste_units"), // ENABLE_COPY_PASTE_UNITS waffle flag
|
||||
useTaggingTaxonomyListPage: this.model.get("use_tagging_taxonomy_list_page"), // ENABLE_TAGGING_TAXONOMY_LIST_PAGE waffle flag
|
||||
|
||||
@@ -143,6 +143,40 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.subsection-share-link-tabs-header {
|
||||
margin-bottom: $baseline;
|
||||
border-bottom: 1px solid $gray-l3;
|
||||
|
||||
li.subsection-share-link-tab-buttons {
|
||||
display: inline-block;
|
||||
margin-right: $baseline;
|
||||
|
||||
.subsection-share-link-tab-button {
|
||||
@extend %t-copy-sub1;
|
||||
@extend %t-regular;
|
||||
|
||||
background-image: none;
|
||||
background-color: $white;
|
||||
color: $gray-d1;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
border: 0;
|
||||
padding: ($baseline/4) ($baseline/2);
|
||||
text-transform: uppercase;
|
||||
|
||||
&:hover {
|
||||
background-color: theme-color("inverse");
|
||||
color: theme-color("primary");
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-bottom: 4px solid theme-color("primary");
|
||||
color: theme-color("primary");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-section-title {
|
||||
@@ -183,6 +217,28 @@
|
||||
@extend %t-icon4;
|
||||
}
|
||||
}
|
||||
|
||||
.subsection-share-link-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.copy-link-button {
|
||||
border-radius: ($baseline/4);
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
padding: 0.7rem 1rem;
|
||||
|
||||
.icon-copy-clipboard {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.share-link-animated-svg {
|
||||
border-radius: 0.5rem;
|
||||
margin-left: 1rem;
|
||||
box-shadow: 0 0 7px $shadow-d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: need to sync up (alongside general editing mode) with xblocks.scss UI
|
||||
|
||||
@@ -666,6 +666,29 @@ $outline-indent-width: $baseline;
|
||||
.icon {
|
||||
@include margin-right($baseline/4);
|
||||
}
|
||||
|
||||
.status-message {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.subsection-share-link-button {
|
||||
border-radius: ($baseline/4);
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 0 1rem;
|
||||
|
||||
.icon-share-link {
|
||||
color: $white !important;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-message-copy {
|
||||
|
||||
@@ -29,7 +29,7 @@ from django.urls import reverse
|
||||
|
||||
<%block name="header_extras">
|
||||
<link rel="stylesheet" type="text/css" href="${static.url('js/vendor/timepicker/jquery.timepicker.css')}" />
|
||||
% for template_name in ['course-outline', 'xblock-string-field-editor', 'basic-modal', 'modal-button', 'course-outline-modal', 'due-date-editor', 'self-paced-due-date-editor', 'release-date-editor', 'grading-editor', 'publish-editor', 'staff-lock-editor', 'unit-access-editor', 'discussion-editor', 'content-visibility-editor', 'verification-access-editor', 'timed-examination-preference-editor', 'access-editor', 'settings-modal-tabs', 'show-correctness-editor', 'highlights-editor', 'highlights-enable-editor', 'course-highlights-enable', 'course-video-sharing-enable', 'summary-configuration-editor', 'tag-count']:
|
||||
% for template_name in ['course-outline', 'xblock-string-field-editor', 'basic-modal', 'modal-button', 'course-outline-modal', 'due-date-editor', 'self-paced-due-date-editor', 'release-date-editor', 'grading-editor', 'publish-editor', 'staff-lock-editor', 'unit-access-editor', 'discussion-editor', 'content-visibility-editor', 'verification-access-editor', 'timed-examination-preference-editor', 'access-editor', 'settings-modal-tabs', 'show-correctness-editor', 'highlights-editor', 'highlights-enable-editor', 'course-highlights-enable', 'course-video-sharing-enable', 'summary-configuration-editor', 'tag-count', 'subsection-share-link-modal-tabs', 'full-page-share-link-editor', 'embed-link-share-link-editor']:
|
||||
<script type="text/template" id="${template_name}-tpl">
|
||||
<%static:include path="js/${template_name}.underscore" />
|
||||
</script>
|
||||
|
||||
@@ -419,8 +419,15 @@ if (is_proctored_exam) {
|
||||
<div class="status-messages">
|
||||
<% for (var i=0; i<statusMessages.length; i++) { %>
|
||||
<div class="status-message">
|
||||
<span class="icon fa <%- statusMessages[i].iconClass %>" aria-hidden="true"></span>
|
||||
<p class="status-message-copy"><%- statusMessages[i].text %></p>
|
||||
<div>
|
||||
<span class="icon fa <%- statusMessages[i].iconClass %>" aria-hidden="true"></span>
|
||||
<p class="status-message-copy"><%- statusMessages[i].text %></p>
|
||||
</div>
|
||||
<% if (enableHideFromTOC && xblockInfo.isSequential()) { %>
|
||||
<button type="button" class="button btn-primary subsection-share-link-button">
|
||||
<span class="icon fa fa-link icon-share-link"></span><%- gettext('Share') %>
|
||||
</button>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
20
cms/templates/js/embed-link-share-link-editor.underscore
Normal file
20
cms/templates/js/embed-link-share-link-editor.underscore
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="modal-section-content">
|
||||
<div class="subsection-share-link-container">
|
||||
<div>
|
||||
<p>
|
||||
<%- gettext('Embed your subsection content directly on a page using an iframe, and view it withput the LMS header and footer.') %>
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
id="embed-link-button"
|
||||
data-clipboard-text="<%- embedLmsUrl %>"
|
||||
title="<%- gettext('Click to copy link to clipboard') %>"
|
||||
class="button btn-primary copy-link-button"
|
||||
>
|
||||
<span class="icon fa fa-clipboard icon-copy-clipboard"></span>
|
||||
<span class="copy-link-button-text"><%- gettext('Copy link') %></span>
|
||||
</button>
|
||||
</div>
|
||||
<img class="share-link-animated-svg" src="/static/studio/images/subsection-embed.svg">
|
||||
</div>
|
||||
</div>
|
||||
20
cms/templates/js/full-page-share-link-editor.underscore
Normal file
20
cms/templates/js/full-page-share-link-editor.underscore
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="modal-section-content">
|
||||
<div class="subsection-share-link-container">
|
||||
<div>
|
||||
<p>
|
||||
<%- gettext('When sharing this link with your learners, they will see the content of the subsection along with the header and footer of your LMS.') %>
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
id="full-page-link-button"
|
||||
data-clipboard-text="<%- lmsUrl %>"
|
||||
title="<%- gettext('Click to copy link to clipboard') %>"
|
||||
class="button btn-primary copy-link-button"
|
||||
>
|
||||
<span class="icon fa fa-clipboard icon-copy-clipboard"></span>
|
||||
<span class="copy-link-button-text"><%- gettext('Copy link') %></span>
|
||||
</button>
|
||||
</div>
|
||||
<img class="share-link-animated-svg" src="/static/studio/images/subsection-full-page.svg">
|
||||
</div>
|
||||
</div>
|
||||
10
cms/templates/js/subsection-share-link-modal-tabs.underscore
Normal file
10
cms/templates/js/subsection-share-link-modal-tabs.underscore
Normal file
@@ -0,0 +1,10 @@
|
||||
<ul class="subsection-share-link-tabs-header">
|
||||
<% _.each(tabs, function(tab) { %>
|
||||
<li class="subsection-share-link-tab-buttons">
|
||||
<button type="button" class="subsection-share-link-tab-button" data-tab="<%- tab.name %>"><%- tab.displayName %></button>
|
||||
</li>
|
||||
<% }); %>
|
||||
</ul>
|
||||
<% _.each(tabs, function(tab) { %>
|
||||
<div class='subsection-share-link-tab <%- tab.name %>'></div>
|
||||
<% }); %>
|
||||
Reference in New Issue
Block a user