diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b639708..a263326 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -16,6 +16,13 @@ Unreleased * +0.7.4 - 2024-04-30 +****************** + +Fixed +===== +* Fixed Superset XBlock and default filters. + 0.7.3 - 2024-04-30 ****************** diff --git a/platform_plugin_aspects/__init__.py b/platform_plugin_aspects/__init__.py index 047913f..fd749fb 100644 --- a/platform_plugin_aspects/__init__.py +++ b/platform_plugin_aspects/__init__.py @@ -5,6 +5,6 @@ import os from pathlib import Path -__version__ = "0.7.3" +__version__ = "0.7.4" ROOT_DIRECTORY = Path(os.path.dirname(os.path.abspath(__file__))) diff --git a/platform_plugin_aspects/static/html/superset.html b/platform_plugin_aspects/static/html/superset.html index df2caee..d441bdb 100644 --- a/platform_plugin_aspects/static/html/superset.html +++ b/platform_plugin_aspects/static/html/superset.html @@ -10,7 +10,7 @@

{{display_name}}

{{exception}}

{% elif not superset_dashboards %}

Dashboard UUID is not set. Please set the dashboard UUID in the Studio.

- {% elif superset_url and superset_guest_token_url %} {% if xblock_id %} + {% elif superset_url %} {% if xblock_id %}
{% else %}
diff --git a/platform_plugin_aspects/static/js/embed_dashboard.js b/platform_plugin_aspects/static/js/embed_dashboard.js index fda579a..eafedb6 100644 --- a/platform_plugin_aspects/static/js/embed_dashboard.js +++ b/platform_plugin_aspects/static/js/embed_dashboard.js @@ -15,11 +15,22 @@ function getCookie(name) { } async function fetchGuestToken() { - const response = await fetch(superset_guest_token_url, { - method: 'GET', + let response; + if (window.from_xblock){ + // XBlock handler requires a POST request and a JSON body + body = JSON.stringify({}); + method = 'POST'; + }else { + body = null; + method = 'GET'; + } + + response = await fetch(window.superset_guest_token_url, { + method: method, headers: { "X-CSRFToken": getCookie("csrftoken"), - } + }, + body: body, }); if (!response.ok) { diff --git a/platform_plugin_aspects/static/js/superset.js b/platform_plugin_aspects/static/js/superset.js index 0198b6d..a29749d 100644 --- a/platform_plugin_aspects/static/js/superset.js +++ b/platform_plugin_aspects/static/js/superset.js @@ -2,11 +2,13 @@ function SupersetXBlock(runtime, element, context) { const dashboard_uuid = context.dashboard_uuid; const superset_url = context.superset_url; - const superset_guest_token_url = runtime.handlerUrl(element, 'get_superset_guest_token'); - const xblock_id = context.xblock_id + const xblock_id = context.xblock_id; + + window.superset_guest_token_url = runtime.handlerUrl(element, 'get_superset_guest_token'); + window.from_xblock = true; function initSuperset(supersetEmbeddedSdk) { - embedDashboard(dashboard_uuid, superset_url, superset_guest_token_url, xblock_id); + embedDashboard(dashboard_uuid, superset_url, xblock_id); } if (typeof require === "function") { diff --git a/platform_plugin_aspects/tests/test_utils.py b/platform_plugin_aspects/tests/test_utils.py index be480cd..b483b8b 100644 --- a/platform_plugin_aspects/tests/test_utils.py +++ b/platform_plugin_aspects/tests/test_utils.py @@ -124,7 +124,6 @@ def test_generate_superset_context(self): self.assertEqual(len(context["superset_dashboards"]), len(dashboards)) self.assertEqual(context["superset_url"], "http://superset-dummy-url/") - self.assertNotIn("superset_token", context) self.assertNotIn("exception", context) @patch("platform_plugin_aspects.utils.SupersetClient") diff --git a/platform_plugin_aspects/tests/test_views.py b/platform_plugin_aspects/tests/test_views.py index 4d5a61e..a3fad12 100644 --- a/platform_plugin_aspects/tests/test_views.py +++ b/platform_plugin_aspects/tests/test_views.py @@ -11,7 +11,7 @@ from opaque_keys.edx.keys import CourseKey from rest_framework.test import APIClient -from ..views import Course, IsCourseStaffInstructor +from ..views import DEFAULT_FILTERS_FORMAT, IsCourseStaffInstructor COURSE_ID = "course-v1:org+course+run" User = get_user_model() @@ -116,13 +116,7 @@ def test_guest_token_with_course_overview( mock_model_get.assert_called_once() mock_generate_guest_token.assert_called_once_with( user=self.user, - course=Course( - course_id=CourseKey.from_string(COURSE_ID), display_name="Course Title" - ), + course=CourseKey.from_string(COURSE_ID), dashboards=settings.ASPECTS_INSTRUCTOR_DASHBOARDS, - filters=[ - "org = 'org'", - "course_name = 'Course Title'", - "course_run = 'run'", - ], + filters=DEFAULT_FILTERS_FORMAT, ) diff --git a/platform_plugin_aspects/utils.py b/platform_plugin_aspects/utils.py index 4e1cf2b..2537495 100644 --- a/platform_plugin_aspects/utils.py +++ b/platform_plugin_aspects/utils.py @@ -31,6 +31,12 @@ def _(text): return text +DEFAULT_FILTERS_FORMAT = [ + "org = '{course_id.org}'", + "course_key = '{course_id}'", +] + + def generate_superset_context( context, dashboards, @@ -106,7 +112,9 @@ def generate_guest_token(user, course, dashboards, filters) -> str: superset_username = superset_config.get("username") superset_password = superset_config.get("password") - formatted_filters = [filter.format(course=course, user=user) for filter in filters] + formatted_filters = [ + filter.format(course_id=course, user=user) for filter in filters + ] resources = [] diff --git a/platform_plugin_aspects/views.py b/platform_plugin_aspects/views.py index 7c4b0cf..0b8dd22 100644 --- a/platform_plugin_aspects/views.py +++ b/platform_plugin_aspects/views.py @@ -16,7 +16,7 @@ from rest_framework.generics import GenericAPIView from rest_framework.response import Response -from .utils import _, generate_guest_token, get_model +from .utils import DEFAULT_FILTERS_FORMAT, _, generate_guest_token, get_model try: from openedx.core.lib.api.permissions import ( @@ -102,7 +102,7 @@ def get_object(self): # May raise a permission denied self.check_object_permissions(self.request, course) - return course + return course_key @method_decorator(cache_page(60 * 5)) def get(self, request, *args, **kwargs): @@ -111,11 +111,6 @@ def get(self, request, *args, **kwargs): """ course = self.get_object() - built_in_filters = [ - f"org = '{course.course_id.org}'", - f"course_name = '{course.display_name}'", - f"course_run = '{course.course_id.run}'", - ] dashboards = settings.ASPECTS_INSTRUCTOR_DASHBOARDS extra_filters_format = settings.SUPERSET_EXTRA_FILTERS_FORMAT @@ -124,7 +119,7 @@ def get(self, request, *args, **kwargs): user=request.user, course=course, dashboards=dashboards, - filters=built_in_filters + extra_filters_format, + filters=DEFAULT_FILTERS_FORMAT + extra_filters_format, ) except ImproperlyConfigured as exc: raise APIException() from exc diff --git a/platform_plugin_aspects/xblock.py b/platform_plugin_aspects/xblock.py index b6b27a7..2fe0374 100644 --- a/platform_plugin_aspects/xblock.py +++ b/platform_plugin_aspects/xblock.py @@ -16,7 +16,12 @@ from xblock.utils.resources import ResourceLoader from xblock.utils.studio_editable import StudioEditableXBlockMixin -from .utils import _, generate_guest_token, generate_superset_context +from .utils import ( + DEFAULT_FILTERS_FORMAT, + _, + generate_guest_token, + generate_superset_context, +) log = logging.getLogger(__name__) loader = ResourceLoader(__name__) @@ -142,7 +147,6 @@ def student_view(self, context=None): json_args={ "dashboard_uuid": self.dashboard_uuid, "superset_url": context.get("superset_url"), - "superset_token": context.get("superset_token"), "xblock_id": context.get("xblock_id"), }, ) @@ -198,9 +202,9 @@ def get_superset_guest_token( try: guest_token = generate_guest_token( user=user, - course=self.runtime.course_id, + course=self.scope_ids.usage_id.context_key, dashboards=self.dashboards(), - filters=self.filters, + filters=DEFAULT_FILTERS_FORMAT + self.filters, ) except ImproperlyConfigured as exc: raise JsonHandlerError(500, str(exc)) from exc