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

1"""Detail view for the resource controller.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Any 

6 

7from starlette.requests import Request 

8from starlette.responses import HTMLResponse, Response 

9 

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 

14 

15if TYPE_CHECKING: 

16 from lexigram.admin.controllers.resource import ResourceController 

17 

18 

19 

20class ResourceDetailMixin: 

21 """Detail view and rendering.""" 

22 

23 # Host attributes provided by sibling mixins on ResourceController. 

24 meta: ResourceMeta 

25 

26 get_data_source: Any 

27 

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") 

32 

33 data_source = self.get_data_source() 

34 item = await data_source.find_one(item_id) 

35 

36 if item is None: 

37 from lexigram.admin.lib.template import render_error_page 

38 

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) 

45 

46 if ctx.is_htmx: 

47 return HTMLResponse(self.render_detail_partial(ctx, item)) 

48 

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""" 

62 

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)))