Enhance layout validation in EntityValidator; add critical checks for bottomPanelsDetail.json and detail.json files, and improve error/warning reporting

This commit is contained in:
2026-01-25 10:28:19 +01:00
parent eaeba65487
commit fb6ef2b960

View File

@@ -293,44 +293,91 @@ class EntityValidator:
"""Prüfe Layout-Dateien auf häufige Fehler."""
print_header("5. LAYOUT-STRUKTUR VALIDIERUNG")
layouts_path = self.metadata_path / "clientDefs"
if not layouts_path.exists():
print_warning("Keine clientDefs gefunden")
return True
layouts_base = self.custom_path / "layouts"
layout_errors = []
layout_warnings = []
checked_layouts = 0
for client_def_file in layouts_path.glob("*.json"):
try:
with open(client_def_file, 'r', encoding='utf-8') as f:
client_def = json.load(f)
# 1. Prüfe bottomPanelsDetail.json Dateien (KRITISCH: Muss Objekt sein, kein Array!)
if layouts_base.exists():
for bottom_panel_file in layouts_base.rglob("bottomPanelsDetail.json"):
try:
with open(bottom_panel_file, 'r', encoding='utf-8') as f:
content = json.load(f)
# Prüfe auf häufige Layout-Fehler in bottomPanels
bottom_panels = client_def.get('bottomPanelsDetail', {})
for panel_key, panel_def in bottom_panels.items():
checked_layouts += 1
entity_name = bottom_panel_file.parent.name
# Prüfe auf unnötige false-Elemente
if isinstance(panel_def, dict):
for key, value in panel_def.items():
if value is False and key not in ['disabled', 'sticked']:
layout_errors.append(
f"{client_def_file.stem}: bottomPanelsDetail.{panel_key}.{key} "
f"sollte nicht 'false' sein"
)
except Exception:
pass # JSON-Fehler bereits gemeldet
# KRITISCHER CHECK: bottomPanelsDetail.json MUSS Objekt sein (nicht Array)!
if isinstance(content, list):
layout_errors.append(
f"{entity_name}/bottomPanelsDetail.json: FEHLER - Ist Array statt Objekt! "
f"EspoCRM 7.x erfordert Objekt-Format mit Keys wie 'contacts', '_tabBreak_0', etc."
)
elif isinstance(content, dict):
# Prüfe auf false-Werte in falschen Kontexten
for key, value in content.items():
if isinstance(value, dict):
for subkey, subvalue in value.items():
if subvalue is False and subkey not in ['disabled', 'sticked']:
layout_warnings.append(
f"{entity_name}/bottomPanelsDetail.json: {key}.{subkey} "
f"sollte nicht 'false' sein"
)
except Exception:
pass # JSON-Fehler bereits in validate_json_syntax gemeldet
# 2. Prüfe detail.json Dateien auf deprecated false-Platzhalter
if layouts_base.exists():
for detail_file in layouts_base.rglob("detail.json"):
try:
with open(detail_file, 'r', encoding='utf-8') as f:
content = json.load(f)
entity_name = detail_file.parent.name
# Prüfe ob content ein Array von Panels ist
if isinstance(content, list):
for panel_idx, panel in enumerate(content):
if not isinstance(panel, dict):
continue
rows = panel.get('rows', [])
for row_idx, row in enumerate(rows):
if not isinstance(row, list):
continue
for cell_idx, cell in enumerate(row):
# KRITISCH: false als Platzhalter ist deprecated in EspoCRM 7.x!
if cell is False:
layout_errors.append(
f"{entity_name}/detail.json: Panel {panel_idx}, Row {row_idx}, "
f"Cell {cell_idx} verwendet 'false' als Platzhalter. "
f"In EspoCRM 7.x muss '{{}}' (leeres Objekt) verwendet werden!"
)
except Exception:
pass # JSON-Fehler bereits gemeldet
# Ergebnisse ausgeben
if layout_errors:
print_warning(f"{len(layout_errors)} Layout-Strukturprobleme:")
for err in layout_errors[:5]:
print(f" {Colors.YELLOW}{Colors.END} {err}")
if len(layout_errors) > 5:
print(f" {Colors.YELLOW}...{Colors.END} und {len(layout_errors) - 5} weitere")
self.warnings.extend(layout_errors)
else:
print_success(f"{checked_layouts} Layout-Definitionen geprüft")
print_error(f"{len(layout_errors)} KRITISCHE Layout-Fehler gefunden:")
for err in layout_errors:
print(f" {Colors.RED}{Colors.END} {err}")
self.errors.extend(layout_errors)
return False
if layout_warnings:
print_warning(f"{len(layout_warnings)} Layout-Warnungen:")
for warn in layout_warnings[:5]:
print(f" {Colors.YELLOW}{Colors.END} {warn}")
if len(layout_warnings) > 5:
print(f" {Colors.YELLOW}...{Colors.END} und {len(layout_warnings) - 5} weitere")
self.warnings.extend(layout_warnings)
if not layout_errors and not layout_warnings:
print_success(f"{checked_layouts} Layout-Dateien geprüft, keine Fehler")
elif not layout_errors:
print_success(f"{checked_layouts} Layout-Dateien geprüft, keine kritischen Fehler")
return True