Coverage for src / lexigram / admin / cli / generators / admin_action.py: 0%
27 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-11 02:25 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-11 02:25 +0800
1"""Admin action generator for creating custom admin UI actions."""
3from __future__ import annotations
5from pathlib import Path
6from typing import Any
8from lexigram.codegen.base import GenerationResult, GeneratorBase
11class AdminActionGenerator(GeneratorBase):
12 """Generator for creating custom admin UI actions."""
14 name = "admin_action"
15 description = "Generate a custom admin action"
16 default_output_dir = "src/admin/actions"
18 def __init__(self, output_dir: str = "src/admin/actions") -> None:
19 super().__init__(
20 output_dir=output_dir,
21 template_root=Path(__file__).parent.parent / "templates",
22 )
24 def generate(
25 self,
26 name: str,
27 **options: Any,
28 ) -> GenerationResult:
29 """Generate an admin action."""
30 action_type = options.get("type", "row")
31 target = options.get("target", "dialog")
32 dry_run = bool(options.get("dry_run", False))
33 force = bool(options.get("force", False))
35 action_name = name.capitalize()
36 action_filename = f"{self._to_snake_case(name)}_action.py"
37 file_path = self.output_dir / action_filename
39 if file_path.exists() and not force:
40 return GenerationResult(files_skipped=[file_path])
42 context = {
43 "action_name": action_name,
44 "action_name_snake": self._to_snake_case(name),
45 "package_name": self._get_package_name(self.output_dir),
46 "action_type": action_type,
47 "target": target,
48 }
50 content = self.render_template("admin_action.py.jinja2", context)
52 if dry_run:
53 return GenerationResult(files_created=[file_path])
55 self.output_dir.mkdir(parents=True, exist_ok=True)
56 file_path.write_text(content)
58 return GenerationResult(files_created=[file_path])