from django.core.management.base import BaseCommand from django.urls import get_resolver import os import json from django.template.loaders.app_directories import get_app_template_dirs class Command(BaseCommand): help = "Generate UI element map for IntroJS tours" def handle(self, *args, **kwargs): output_file = os.path.join('static', 'js', 'tours', 'ui_element_map.json') ui_map = { "pages": {}, "common_elements": { "navigation": { "inventory": "#inventory-menu, .inventory-nav, nav .inventory", "finance": "#finance-menu, .finance-nav, nav .finance", "customers": "#customers-menu, .customers-nav, nav .customers" }, "actions": { "add": ".btn-add, .add-button, button:contains('Add')", "edit": ".btn-edit, .edit-button, button:contains('Edit')", "save": ".btn-save, button[type='submit'], #save-button", "cancel": ".btn-cancel, #cancel-button, button:contains('Cancel')", "delete": ".btn-delete, .delete-button, button:contains('Delete')" }, "forms": { "search": "#search-form, .search-input, input[name='q']", "date_range": ".date-range, input[type='date']", "dropdown": "select, .dropdown, .select-field" } } } # Extract URL patterns to identify pages resolver = get_resolver() for url_pattern in resolver.url_patterns: if hasattr(url_pattern, 'name') and url_pattern.name: pattern_name = url_pattern.name # Skip admin and API URLs if pattern_name.startswith(('admin:', 'api:')): continue ui_map["pages"][pattern_name] = { "url_pattern": str(url_pattern.pattern), "elements": {} } # Scan templates for UI elements with IDs template_dirs = get_app_template_dirs('templates') for template_dir in template_dirs: for root, dirs, files in os.walk(template_dir): for file in files: if not file.endswith(('.html', '.htm')): continue try: with open(os.path.join(root, file), 'r', encoding='utf-8') as f: content = f.read() # Try to identify the page/view this template is for template_path = os.path.relpath(os.path.join(root, file), template_dir) page_key = template_path.replace('/', '_').replace('.html', '') # Create page entry if it doesn't exist if page_key not in ui_map["pages"]: ui_map["pages"][page_key] = { "template": template_path, "elements": {} } # Extract elements with IDs import re id_matches = re.findall(r'id=["\']([^"\']+)["\']', content) for id_match in id_matches: ui_map["pages"][page_key]["elements"][id_match] = f"#{id_match}" except Exception as e: self.stdout.write(self.style.WARNING(f"Error processing template {file}: {e}")) # Save UI map as JSON os.makedirs(os.path.dirname(output_file), exist_ok=True) with open(output_file, 'w', encoding='utf-8') as f: json.dump(ui_map, f, indent=2) self.stdout.write(self.style.SUCCESS(f"✅ UI element map saved to {output_file}"))