display_template.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. from __future__ import annotations
  2. from pathlib import Path
  3. from typing import TYPE_CHECKING
  4. from rich import box
  5. from rich.console import Console
  6. from rich.panel import Panel
  7. from rich.text import Text
  8. from .display_icons import IconManager
  9. from .display_settings import DisplaySettings
  10. if TYPE_CHECKING:
  11. from ..template import Template
  12. from .display_base import BaseDisplay
  13. from .display_status import StatusDisplay
  14. from .display_variable import VariableDisplay
  15. class TemplateDisplay:
  16. """Template-related rendering.
  17. Provides methods for displaying template information,
  18. file trees, and metadata.
  19. """
  20. def __init__(
  21. self,
  22. settings: DisplaySettings,
  23. base: BaseDisplay,
  24. variables: VariableDisplay,
  25. status: StatusDisplay,
  26. ):
  27. """Initialize TemplateDisplay.
  28. Args:
  29. settings: Display settings for formatting
  30. base: BaseDisplay instance
  31. variables: VariableDisplay instance for rendering variables
  32. status: StatusDisplay instance for markdown rendering
  33. """
  34. self.settings = settings
  35. self.base = base
  36. self.variables = variables
  37. self.status = status
  38. def render_template(self, template: Template, template_id: str) -> None:
  39. """Display template information panel and variables table.
  40. Args:
  41. template: Template instance to display
  42. template_id: ID of the template
  43. """
  44. self.render_template_header(template, template_id)
  45. self.render_file_tree(template)
  46. self.variables.render_variables_table(template)
  47. def render_template_header(self, template: Template, template_id: str) -> None:
  48. """Display the header for a template with library information.
  49. Args:
  50. template: Template instance
  51. template_id: ID of the template
  52. """
  53. settings = self.settings
  54. template_name = template.metadata.name or settings.TEXT_UNNAMED_TEMPLATE
  55. version = str(template.metadata.version) if template.metadata.version else settings.TEXT_VERSION_NOT_SPECIFIED
  56. schema = template.schema_version if hasattr(template, "schema_version") else "1.0"
  57. description = template.metadata.description or settings.TEXT_NO_DESCRIPTION
  58. # Get library information and format with icon/color
  59. library_name = template.metadata.library or ""
  60. library_type = template.metadata.library_type or "git"
  61. icon = IconManager.UI_LIBRARY_STATIC if library_type == "static" else IconManager.UI_LIBRARY_GIT
  62. color = "yellow" if library_type == "static" else "blue"
  63. # Create custom H1-style header with Rich markup support
  64. # Build header content with Rich formatting
  65. header_content = Text()
  66. header_content.append(template_name, style="bold white")
  67. header_content.append(" (", style="white")
  68. header_content.append("id:", style="white")
  69. header_content.append(template_id, style="dim")
  70. header_content.append(" │ ", style="dim")
  71. header_content.append("version:", style="white")
  72. header_content.append(version, style="cyan")
  73. header_content.append(" │ ", style="dim")
  74. header_content.append("schema:", style="white")
  75. header_content.append(schema, style="magenta")
  76. header_content.append(" │ ", style="dim")
  77. header_content.append("library:", style="white")
  78. header_content.append(icon + " ", style=color)
  79. header_content.append(library_name, style=color)
  80. header_content.append(")", style="white")
  81. panel = Panel(header_content, box=box.HEAVY, style="markdown.h1.border")
  82. Console().print(panel)
  83. self.base.text("")
  84. self.status.markdown(description)
  85. def render_file_tree(self, template: Template) -> None:
  86. """Display the file structure of a template.
  87. Args:
  88. template: Template instance
  89. """
  90. self.base.text("")
  91. self.base.heading("Template File Structure")
  92. def get_template_file_info(template_file):
  93. display_name = (
  94. template_file.output_path.name
  95. if hasattr(template_file, "output_path")
  96. else template_file.relative_path.name
  97. )
  98. return (template_file.relative_path, display_name, "white", None)
  99. if template.template_files:
  100. self.base.file_tree(
  101. f"{IconManager.folder()} [white]{template.id}[/white]",
  102. template.template_files,
  103. get_template_file_info,
  104. )
  105. def render_file_generation_confirmation(
  106. self,
  107. output_dir: Path,
  108. files: dict[str, str],
  109. existing_files: list[Path] | None = None,
  110. ) -> None:
  111. """Display files to be generated with confirmation prompt.
  112. Args:
  113. output_dir: Output directory path
  114. files: Dictionary of file paths to content
  115. existing_files: List of existing files that will be overwritten
  116. """
  117. self.base.text("")
  118. self.base.heading("Files to be Generated")
  119. def get_file_generation_info(file_path_str):
  120. file_path = Path(file_path_str)
  121. file_name = file_path.parts[-1] if file_path.parts else file_path.name
  122. full_path = output_dir / file_path
  123. if existing_files and full_path in existing_files:
  124. return (file_path, file_name, "yellow", "[red](will overwrite)[/red]")
  125. return (file_path, file_name, "green", None)
  126. self.base.file_tree(
  127. f"{IconManager.folder()} [cyan]{output_dir.resolve()}[/cyan]",
  128. files.keys(),
  129. get_file_generation_info,
  130. )
  131. self.base.text("")