Source code for ferrosoft.apps.ferrobase.apps

"""Django application configuration, menu registration types, and platform app metadata."""
from dataclasses import dataclass, field
from typing import Iterable, Any

from django.apps import AppConfig
from django.http import HttpRequest
from django.utils.translation import gettext_lazy as _
from django_asgi_lifespan.register import register_lifespan_manager


[docs] class FerrobaseConfig(AppConfig): """Django AppConfig for the ferrobase application. Initialises the dependency injection container on startup and registers the HTTPX lifespan manager so a single connection pool is shared across all inbound requests. """ default_auto_field = "django.db.models.BigAutoField" name = "ferrosoft.apps.ferrobase" verbose_name = _("Ferrosoft Base") container = None
[docs] def ready(self): """Wire up the DI container and register the HTTPX lifespan manager.""" # These imports have to stay here to avoid AppRegistryNotReady error. from django.conf import settings from ferrosoft.apps.ferrobase.containers import Container from ferrosoft.apps.ferrobase.context import httpx_lifespan_manager self.container = Container() self.container.config.from_dict(getattr(settings, "FERROBASE_CONTAINER", {})) self.container.wire( modules=[".services.taskqueue"], warn_unresolved=True, ) # Allow connection caching across all inbound requests. register_lifespan_manager(context_manager=httpx_lifespan_manager)
[docs] @dataclass class AppMeta: """AppMeta provides information about platform applications.""" title: Any """Human readable title of the application.""" app_name: str """Django identifier of the application.""" home_view: str """Django view name of the home page.""" icon_path: str """File path to app icon. It must be a static file if templated_icon = False, otherwise a template file.""" restricted_app_menu: bool = False """Show to the user only the menu of the app, even if the user navigates to a different app.""" templated_icon: bool = False """If true, the icon is {% include %}'d in the template (useful for SVG)."""
[docs] class SettingsMenuRegistry: """Registry of settings-page menu items with permission-based filtering.""" ITEMS = [ MenuItem( category_name="", display_name=_("My settings"), view_name="ferrobase:my_settings", ), MenuItem( category_name="", display_name=_("Account Security"), view_name="two_factor:profile", ), MenuItem( category_name=_("Core Data"), display_name=_("Business partners"), view_name="ferrobase:businesspartner_index", permissions=["ferrobase.view_businesspartner"], ), MenuItem( category_name=_("System"), display_name=_("API Tokens"), view_name="ferrobase:apitoken_index", permissions=["ferrobase.view_apitoken"], ), MenuItem( category_name=_("System"), display_name=_("ID Sequences"), view_name="ferrobase:idsequenceconfig_index", permissions=["ferrobase.view_idsequenceconfig"], ), MenuItem( category_name=_("Core Data"), display_name=_("Material"), view_name="ferrobase:material_index", permissions=["ferrobase.view_material"], ), MenuItem( category_name=_("Core Data"), display_name=_("Company Sites"), view_name="ferrobase:companysite_index", permissions=["ferrobase.view_companysite"], ), MenuItem( category_name=_("System"), display_name=_("Users"), view_name="ferrobase:user_index", permissions=["ferrobase.view_user"], ), MenuItem( category_name=_("System"), display_name=_("Groups"), view_name="ferrobase:group_index", permissions=["auth.view_group"], ), MenuItem( category_name=_("System"), display_name=_("Organizations"), view_name="ferrobase:organization_index", permissions=["ferrobase.view_organization"], ), MenuItem( category_name=_("System"), display_name=_("Subscription Plans"), view_name="ferrobase:subscriptionplan_index", permissions=["ferrobase.view_subscriptionplan"], ), MenuItem( category_name="", display_name=_("Files"), view_name="ferrobase:directory_root", permissions=["ferrobase.view_directory"], ), ]
[docs] @classmethod def add_items(cls, *items: MenuItem): """Add menu items to the registry. Args: *items: ``MenuItem`` instances to append to the shared registry. """ cls.ITEMS += items
[docs] @classmethod def get_menu( cls, request: HttpRequest, items: list[MenuItem] | None = None ) -> Iterable[MenuItem]: """Return settings menu items the requesting user is permitted to see. Args: request: The current HTTP request; its ``user`` is checked for each item's required permissions. items: Candidate menu items to filter. Defaults to the class-level registry when ``None``. Returns: Iterable[MenuItem]: Permitted items sorted by category then display name. """ return sorted( filter(cls._settings_menu_filter(request.user), items or cls.ITEMS), key=lambda item: (item.category_name, item.display_name), )
@staticmethod def _settings_menu_filter(user): def _filter(item: MenuItem): user_has_permissions = all( map( lambda perm: user.has_perm(perm), item.permissions, ) ) return user_has_permissions return _filter
PLATFORM_APPS = { "emiflow": AppMeta( title=_("Emiflow"), app_name="emiflow", home_view="emiflow:index", icon_path="ferrobase/app-icons/emiflow.svg", restricted_app_menu=True, templated_icon=True, ), "ferrobase": AppMeta( title=_("Ferrosoft"), app_name="ferrobase", home_view="ferrobase:index", icon_path="ferrobase/app-icons/ferrobase.svg", templated_icon=True, ), } INDEX_MENU = [ MenuItem( category_name="", display_name=_("Emiflow"), view_name="emiflow:index", ), MenuItem( category_name="", display_name=_("Data import"), view_name="dataimport:index", ), MenuItem( category_name="", display_name=_("Examination report"), view_name="befundung:log", ), ] MENU_ITEMS = { "dataimport": [ MenuItem( category_name="", display_name=_("Recent Imports"), view_name="dataimport:index", ), MenuItem( category_name="", display_name=_("New Import"), view_name="dataimport:job_new", ), ], "emiflow": [ MenuItem( category_name="", display_name=_("Home"), view_name="emiflow:index", ), MenuItem( category_name="", display_name=_("Transports"), view_name="emiflow:transportchain_index", ), MenuItem( category_name="", display_name=_("Treatments"), view_name="emiflow:treatment_index", ), MenuItem( category_name="", display_name=_("Reporting"), view_name="emiflow:report_index", ), MenuItem( category_name="", display_name=_("File Import"), view_name="emiflow:file_import_index", ), ], }