- Introduction of eveai-listview (to select objects) that is sortable, filterable, ...

- npm build does now also include building css files.
- Source javascript and css are now defined in the source directories (eveai_app or eveai_chat_client), and automatically built for use with nginx
- eveai.css is now split into several more manageable files (per control type)
This commit is contained in:
Josako
2025-07-11 15:25:28 +02:00
parent 42635a583c
commit acad28b623
92 changed files with 6339 additions and 5168 deletions

View File

@@ -0,0 +1,168 @@
#!/usr/bin/env python3
"""
Test script to verify the new list view implementation works correctly.
This script tests the specialists view to ensure it returns the expected data format.
"""
import sys
import os
import json
# Add the project root to the Python path
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)
def test_specialists_view_data_format():
"""Test that the specialists view returns data in the expected format for Tabulator."""
try:
# Import the Flask app and required modules
from eveai_app import create_app
from common.models.interaction import Specialist
from flask import url_for
# Create the Flask app
app = create_app()
with app.app_context():
# Test the data format that would be returned by the specialists view
specialists_query = Specialist.query.order_by(Specialist.id)
all_specialists = specialists_query.all()
# Prepare data for Tabulator (same logic as in the view)
specialists_data = []
for specialist in all_specialists:
specialists_data.append({
'id': specialist.id,
'name': specialist.name,
'type': specialist.type,
'type_version': specialist.type_version,
'active': specialist.active
})
# Column definitions
columns = [
{'title': 'ID', 'field': 'id', 'type': 'number', 'width': 80},
{'title': 'Name', 'field': 'name', 'type': 'text', 'dynamicValues': True},
{'title': 'Type', 'field': 'type', 'type': 'text', 'dynamicValues': True},
{'title': 'Type Version', 'field': 'type_version', 'type': 'text'},
{'title': 'Active', 'field': 'active', 'type': 'boolean', 'formatter': 'tickCross'}
]
# Action definitions
actions = [
{'value': 'edit_specialist', 'text': 'Edit Specialist', 'class': 'btn-primary', 'requiresSelection': True},
{'value': 'execute_specialist', 'text': 'Execute Specialist', 'class': 'btn-primary', 'requiresSelection': True},
{'value': 'create_specialist', 'text': 'Register Specialist', 'class': 'btn-success', 'position': 'right', 'requiresSelection': False}
]
# Initial sort configuration
initial_sort = [{'column': 'id', 'dir': 'asc'}]
# Test that data can be serialized to JSON (required for template)
try:
json.dumps(specialists_data)
json.dumps(columns)
json.dumps(actions)
json.dumps(initial_sort)
print("✓ All data structures can be serialized to JSON")
except Exception as e:
print(f"✗ JSON serialization failed: {e}")
return False
# Test data structure validation
if not isinstance(specialists_data, list):
print("✗ specialists_data should be a list")
return False
if specialists_data and not isinstance(specialists_data[0], dict):
print("✗ specialists_data items should be dictionaries")
return False
if not isinstance(columns, list):
print("✗ columns should be a list")
return False
if not isinstance(actions, list):
print("✗ actions should be a list")
return False
print(f"✓ Found {len(specialists_data)} specialists")
print(f"✓ Configured {len(columns)} columns")
print(f"✓ Configured {len(actions)} actions")
print("✓ Data structure validation passed")
# Test that required fields are present in data
if specialists_data:
required_fields = ['id', 'name', 'type', 'type_version', 'active']
sample_data = specialists_data[0]
for field in required_fields:
if field not in sample_data:
print(f"✗ Required field '{field}' missing from data")
return False
print("✓ All required fields present in data")
# Test column configuration
for column in columns:
if 'title' not in column or 'field' not in column:
print(f"✗ Column missing required 'title' or 'field': {column}")
return False
print("✓ Column configuration validation passed")
# Test action configuration
for action in actions:
required_action_fields = ['value', 'text']
for field in required_action_fields:
if field not in action:
print(f"✗ Action missing required field '{field}': {action}")
return False
print("✓ Action configuration validation passed")
return True
except Exception as e:
print(f"✗ Test failed with exception: {e}")
import traceback
traceback.print_exc()
return False
def test_template_files_exist():
"""Test that the required template files exist."""
template_files = [
'eveai_app/templates/eveai_list_view.html',
'eveai_app/templates/interaction/specialists.html'
]
for template_file in template_files:
full_path = os.path.join(project_root, template_file)
if not os.path.exists(full_path):
print(f"✗ Template file missing: {template_file}")
return False
else:
print(f"✓ Template file exists: {template_file}")
return True
def main():
"""Run all tests."""
print("Testing new list view implementation...")
print("=" * 50)
# Test template files
print("\n1. Testing template files...")
template_test_passed = test_template_files_exist()
# Test data format
print("\n2. Testing data format...")
data_test_passed = test_specialists_view_data_format()
# Summary
print("\n" + "=" * 50)
if template_test_passed and data_test_passed:
print("✓ All tests passed! The list view implementation appears to be working correctly.")
return 0
else:
print("✗ Some tests failed. Please check the implementation.")
return 1
if __name__ == "__main__":
sys.exit(main())