Coverage for src/lexigram/admin/controllers/resource/detail.py: 0%
27 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:18 +0800
1"""Detail view for the resource controller."""
3from __future__ import annotations
5from typing import TYPE_CHECKING, Any
7from starlette.requests import Request
8from starlette.responses import HTMLResponse, Response
10from lexigram.admin.controllers.resource.meta import ResourceMeta, T
11from lexigram.admin.data.data_source import IDataSource as DataSourceProtocol
12from lexigram.admin.state.context import AdminContext, AdminContextManager
13from lexigram.ui import el, render_to_string
15if TYPE_CHECKING:
16 from lexigram.admin.controllers.resource import ResourceController
20class ResourceDetailMixin:
21 """Detail view and rendering."""
23 # Host attributes provided by sibling mixins on ResourceController.
24 meta: ResourceMeta
26 get_data_source: Any
28 async def detail(self, request: Request) -> Response:
29 """View single resource."""
30 async with AdminContextManager(request) as ctx:
31 item_id = request.path_params.get("id")
33 data_source = self.get_data_source()
34 item = await data_source.find_one(item_id)
36 if item is None:
37 from lexigram.admin.lib.template import render_error_page
39 html = render_error_page(
40 status_code=404,
41 title="Not Found",
42 message=f"{self.meta.label} not found",
43 )
44 return HTMLResponse(html, status_code=404)
46 if ctx.is_htmx:
47 return HTMLResponse(self.render_detail_partial(ctx, item))
49 return HTMLResponse(self.render_detail(ctx, item))
50 def render_detail(self, ctx: AdminContext, item: T) -> str:
51 """Render full detail page. Override in subclass."""
52 return f"""
53<!DOCTYPE html>
54<html>
55<head><title>{self.meta.label}</title></head>
56<body>
57 <h1>{self.meta.label}</h1>
58 {self.render_detail_partial(ctx, item)}
59</body>
60</html>
61"""
63 def render_detail_partial(self, ctx: AdminContext, item: T) -> str:
64 """Render detail content. Override in subclass."""
65 return render_to_string(el("pre", str(item)))