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:
@@ -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"):
|
||||
# 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(client_def_file, 'r', encoding='utf-8') as f:
|
||||
client_def = json.load(f)
|
||||
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']:
|
||||
# KRITISCHER CHECK: bottomPanelsDetail.json MUSS Objekt sein (nicht Array)!
|
||||
if isinstance(content, list):
|
||||
layout_errors.append(
|
||||
f"{client_def_file.stem}: bottomPanelsDetail.{panel_key}.{key} "
|
||||
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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user