Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def _get_upstream_link_good_and_syncable(downstream):
error_message=None,
downstream_customized=[],
has_top_level_parent=False,
upstream_name=downstream.upstream_display_name,
)


Expand Down
3 changes: 3 additions & 0 deletions cms/lib/xblock/upstream_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class UpstreamLink:
"""
upstream_ref: str | None # Reference to the upstream content, e.g., a serialized library block usage key.
upstream_key: LibraryUsageLocatorV2 | LibraryContainerLocator | None # parsed opaque key version of upstream_ref
upstream_name: str | None # Display name of the upstream content.
downstream_key: str | None # Key of the downstream object.
version_synced: int | None # Version of the upstream to which the downstream was last synced.
version_available: int | None # Latest version of the upstream that's available, or None if it couldn't be loaded.
Expand Down Expand Up @@ -223,6 +224,7 @@ def try_get_for_block(cls, downstream: XBlock, log_error: bool = True) -> t.Self
)
return cls(
upstream_ref=getattr(downstream, "upstream", None),
upstream_name=getattr(downstream, "upstream_display_name", None),
upstream_key=None,
downstream_key=str(getattr(downstream, "usage_key", "")),
version_synced=getattr(downstream, "upstream_version", None),
Expand Down Expand Up @@ -307,6 +309,7 @@ def get_for_block(cls, downstream: XBlock) -> t.Self:
result = cls(
upstream_ref=downstream.upstream,
upstream_key=upstream_key,
upstream_name=downstream.upstream_display_name,
downstream_key=str(downstream.usage_key),
version_synced=downstream.upstream_version,
version_available=version_available,
Expand Down
26 changes: 26 additions & 0 deletions cms/static/sass/course-unit-mfe-iframe-bundle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,32 @@ body,
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: flex;

.library-info-icon {
width: 32px;
height: 26px;
margin-top: 2px;
margin-right: 5px;
display: flex;
justify-content: center;
background-color: white;
color: $primary;
border: 1px solid #A9A6A4FF;
border-radius: 4px;

&.two-icons {
width: 60px;
}

&.sync-state {
&:hover {
background-color: $primary;
border-color: $primary;
color: white;
}
}
}
}

.xblock-display-name {
Expand Down
57 changes: 43 additions & 14 deletions cms/templates/studio_xblock_wrapper.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<%page expression_filter="h"/>
<%!
from django.utils.translation import gettext as _
from openedx.core.djangolib.markup import Text
from cms.djangoapps.contentstore.helpers import xblock_studio_url
from cms.djangoapps.contentstore.utils import is_visible_to_specific_partition_groups, get_editor_page_base_url, determine_label
from lms.lib.utils import is_unit
Expand Down Expand Up @@ -112,21 +113,49 @@
% else:
% if upstream_info.upstream_ref:
% if upstream_info.error_message:
<!-- "broken link" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:link_off:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%235f6368&icon.query=link -->
<svg role="img" data-tooltip="${_("Sourced from a library - but the upstream link is broken/invalid.")}" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" style="vertical-align: middle; padding-bottom: 4px;">
<path d="m770-302-60-62q40-11 65-42.5t25-73.5q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 57-29.5 105T770-302ZM634-440l-80-80h86v80h-6ZM792-56 56-792l56-56 736 736-56 56ZM440-280H280q-83 0-141.5-58.5T80-480q0-69 42-123t108-71l74 74h-24q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h65l79 80H320Z"/>
</svg>
<span class="sr-only">${_("Sourced from a library - but the upstream link is broken/invalid.")}</span>
<div class="library-info-icon two-icons" data-tooltip="${_("The referenced library or library object is not available.")}">
<!-- "library" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:newsstand:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24 -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M80-160v-80h800v80H80Zm80-160v-320h80v320h-80Zm160 0v-480h80v480h-80Zm160 0v-480h80v480h-80Zm280 0L600-600l70-40 160 280-70 40Z"/>
</svg>
<!-- "broken link" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:link_off:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%235f6368&icon.query=link -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="m770-302-60-62q40-11 65-42.5t25-73.5q0-50-35-85t-85-35H520v-80h160q83 0 141.5 58.5T880-480q0 57-29.5 105T770-302ZM634-440l-80-80h86v80h-6ZM792-56 56-792l56-56 736 736-56 56ZM440-280H280q-83 0-141.5-58.5T80-480q0-69 42-123t108-71l74 74h-24q-50 0-85 35t-35 85q0 50 35 85t85 35h160v80ZM320-440v-80h65l79 80H320Z"/>
</svg>
<span class="sr-only">${_("The referenced library or library object is not available.")}</span>
</div>
% elif upstream_info.ready_to_sync:
<button class="library-info-icon two-icons library-sync-button sync-state" data-tooltip="${Text(_("The linked {upstream_name} has updates available.")).format(upstream_name=upstream_info.upstream_name)}">
<!-- "library" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:newsstand:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24 -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M80-160v-80h800v80H80Zm80-160v-320h80v320h-80Zm160 0v-480h80v480h-80Zm160 0v-480h80v480h-80Zm280 0L600-600l70-40 160 280-70 40Z"/>
</svg>
<!-- "sync" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:sync:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%235f6368&icon.query=sync&icon.platform=web -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M160-160v-80h110l-16-14q-52-46-73-105t-21-119q0-111 66.5-197.5T400-790v84q-72 26-116 88.5T240-478q0 45 17 87.5t53 78.5l10 10v-98h80v240H160Zm400-10v-84q72-26 116-88.5T720-482q0-45-17-87.5T650-648l-10-10v98h-80v-240h240v80H690l16 14q49 49 71.5 106.5T800-482q0 111-66.5 197.5T560-170Z"/>
</svg>
<span class="sr-only">${_("The linked library object has updates available.")}</span>
</button>
% elif len(upstream_info.downstream_customized) > 0:
<div class="library-info-icon two-icons" data-tooltip="${_("This library reference has course overrides applied.")}">
<!-- "library" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:newsstand:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24 -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M80-160v-80h800v80H80Zm80-160v-320h80v320h-80Zm160 0v-480h80v480h-80Zm160 0v-480h80v480h-80Zm280 0L600-600l70-40 160 280-70 40Z"/>
</svg>
<!-- "call split" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:call_split:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24&icon.color=%235f6368&icon.query=fork -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M440-160v-304L240-664v104h-80v-240h240v80H296l224 224v336h-80Zm154-376-58-58 128-126H560v-80h240v240h-80v-104L594-536Z"/>
</svg>
<span class="sr-only">${_("This library reference has course overrides applied.")}</span>
</div>
% else:
<!-- "library" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:newsstand:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24 -->
<svg role="img" data-tooltip="${_("Sourced from a library - but has been modified locally." if len(upstream_info.downstream_customized) > 0 else "Sourced from a library.")}" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle; padding-bottom: 4px;">
<path d="M80-160v-80h800v80H80Zm80-160v-320h80v320h-80Zm160 0v-480h80v480h-80Zm160 0v-480h80v480h-80Zm280 0L600-600l70-40 160 280-70 40Z"/>
</svg>
% if len(upstream_info.downstream_customized) > 0:
<span class="sr-only">${_("Sourced from a library - but has been modified locally.")}</span>
% else:
<span class="sr-only">${_("Sourced from a library.")}</span>
% endif
<div class="library-info-icon" data-tooltip="${Text(_("This is referenced via {upstream_name}")).format(upstream_name=upstream_info.upstream_name)}">
<!-- "library" icon from https://fonts.google.com/icons?selected=Material+Symbols+Outlined:newsstand:FILL@0;wght@400;GRAD@0;opsz@24&icon.size=24 -->
<svg role="img" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 -960 960 960" fill="currentColor" style="vertical-align: middle;">
<path d="M80-160v-80h800v80H80Zm80-160v-320h80v320h-80Zm160 0v-480h80v480h-80Zm160 0v-480h80v480h-80Zm280 0L600-600l70-40 160 280-70 40Z"/>
</svg>
<span class="sr-only">${_("This item is linked to a library item.")}</span>
</div>
% endif
% endif
<span class="xblock-display-name">${label}</span>
Expand Down
Loading