Source code for smarter.apps.dashboard.views.views.dashboard

# pylint: disable=W0613
"""
Main dashboard view.

This module provides the primary authenticated dashboard view that renders the
React-based dashboard page. Responses are lightly cached on a per-user basis
(``DASHBOARD_CACHE_TIMEOUT`` seconds) to keep the UI snappy without serving
stale data.

Unauthenticated requests are redirected to the login page.

Attributes:
    DASHBOARD_CACHE_TIMEOUT (int): Per-user response cache lifetime in seconds
        (default: ``10``).

Classes:
    DashboardView: Authenticated, lightly cached view that renders the React
        dashboard page.

Example:
    Wire up the view in your URL configuration::

        from smarter.apps.dashboard.views.views.dashboard import DashboardView

        urlpatterns = [
            path("", DashboardView.as_view(), name="dashboard"),
        ]
"""

from django.conf import settings
from django.http import HttpResponse
from django.http.request import HttpRequest
from django.shortcuts import redirect, render

from smarter.common.utils import is_authenticated_request
from smarter.lib import logging
from smarter.lib.django.shortcuts import reverse
from smarter.lib.django.views import SmarterAuthenticatedNeverCachedWebView

logger = logging.getLogger(__name__)
DASHBOARD_CACHE_TIMEOUT = 10  # 10 seconds. keeps the dashboard snappy while avoiding appearing stale.


[docs] class DashboardView(SmarterAuthenticatedNeverCachedWebView): """ Authenticated, per-user cached view that renders the React dashboard page. Extends :class:`~smarter.lib.django.views.SmarterAuthenticatedWebView`. Two decorators are applied at dispatch time: On a ``GET`` request the view redirects unauthenticated users to the login page, otherwise it builds a context dictionary containing API URLs for the "My Resources" and "Service Health" React widgets, then renders ``react/dashboard.html``. Attributes: template_path (str): Set at request time to ``"react/dashboard.html"``. """ # template_path = "dashboard/authenticated.html" template_path = "react/dashboard.html" @property def formatted_class_name(self) -> str: """Returns the class name in a formatted string along with the name of this view.""" class_name = f"{__name__}.{DashboardView.__name__}[{id(self)}]" return self.formatted_text(class_name)
[docs] def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: """ Handle GET requests to render the dashboard page for authenticated users. :param request: The incoming HTTP GET request from the client. :type request: django.http.HttpRequest :param args: Additional positional arguments forwarded by the URL dispatcher. :param kwargs: Additional keyword arguments forwarded by the URL dispatcher. :returns: An HTTP response with the rendered dashboard page for authenticated users, or a redirect to the login page for unauthenticated users. :rtype: django.http.HttpResponse or django.http.HttpResponseRedirect """ if not is_authenticated_request(request): return redirect(reverse("login_view")) # pylint: disable=C0415 from smarter.apps.dashboard.views.views.api.urls import ( DashboardApiReverseNames, ) from smarter.apps.dashboard.views.views.urls import ( DashboardReverseNames, # avoid circular import ) context = { "react_dashboard": { "root_id": "smarter-dashboard-root", "csrf_cookie_name": settings.CSRF_COOKIE_NAME, # this is the CSRF token cookie that should be included in the header of the POST request from the frontend. "django_session_cookie_name": settings.SESSION_COOKIE_NAME, # this is the Django session. "cookie_domain": settings.SESSION_COOKIE_DOMAIN, "my_resources_api_url": reverse( DashboardReverseNames.namespace, DashboardApiReverseNames.namespace, DashboardApiReverseNames.my_resources, ), "service_health_api_url": reverse( DashboardReverseNames.namespace, DashboardApiReverseNames.namespace, DashboardApiReverseNames.service_health, ), } } self.template_path = "react/dashboard.html" logger.debug( "%s.get() Rendering dashboard with context: %s", self.formatted_class_name, logging.formatted_json(context) ) return render(request, self.template_path, context=context)