From ecf94bf84e0736b0eb9c8742dbeb177194c8984f Mon Sep 17 00:00:00 2001
From: pacnpal <183241239+pacnpal@users.noreply.github.com>
Date: Thu, 6 Feb 2025 20:06:10 -0500
Subject: [PATCH] Add version control context processor and integrate map
functionality with dedicated JavaScript
---
history_tracking/context_processors.py | 43 ++++
history_tracking/managers.py | 12 +-
.../includes/version_control_ui.html | 94 ++++++++
history_tracking/utils.py | 79 +++---
memory-bank/activeContext.md | 132 ++++++----
.../features/version-control/README.md | 228 ++++++++++++++++++
.../implementation_checklist.md | 159 ++++++++++++
.../version-control/template_integration.md | 86 +++++++
.../version-control/ui_improvements.md | 110 +++++++++
parks/models.py | 91 ++++++-
parks/templates/parks/park_detail.html | 200 +++++++++++++++
static/css/version-control.css | 181 ++++++++++++++
static/js/map-init.js | 20 ++
static/js/version-control.js | 155 ++++++++++++
templates/base.html | 169 +++++++++++++
thrillwiki/settings.py | 1 +
16 files changed, 1671 insertions(+), 89 deletions(-)
create mode 100644 history_tracking/context_processors.py
create mode 100644 history_tracking/templates/history_tracking/includes/version_control_ui.html
create mode 100644 memory-bank/features/version-control/README.md
create mode 100644 memory-bank/features/version-control/implementation_checklist.md
create mode 100644 memory-bank/features/version-control/template_integration.md
create mode 100644 memory-bank/features/version-control/ui_improvements.md
create mode 100644 parks/templates/parks/park_detail.html
create mode 100644 static/css/version-control.css
create mode 100644 static/js/map-init.js
create mode 100644 static/js/version-control.js
create mode 100644 templates/base.html
diff --git a/history_tracking/context_processors.py b/history_tracking/context_processors.py
new file mode 100644
index 00000000..07c12c9a
--- /dev/null
+++ b/history_tracking/context_processors.py
@@ -0,0 +1,43 @@
+from typing import Dict, Any
+from django.http import HttpRequest
+from .signals import get_current_branch
+from .models import VersionBranch, ChangeSet
+
+def version_control(request: HttpRequest) -> Dict[str, Any]:
+ """
+ Add version control information to the template context
+ """
+ current_branch = get_current_branch()
+ context = {
+ 'vcs_enabled': True,
+ 'current_branch': current_branch,
+ 'recent_changes': []
+ }
+
+ if current_branch:
+ # Get recent changes for the current branch
+ recent_changes = ChangeSet.objects.filter(
+ branch=current_branch,
+ status='applied'
+ ).order_by('-created_at')[:5]
+
+ context.update({
+ 'recent_changes': recent_changes,
+ 'branch_name': current_branch.name,
+ 'branch_metadata': current_branch.metadata
+ })
+
+ # Get available branches for switching
+ context['available_branches'] = VersionBranch.objects.filter(
+ is_active=True
+ ).order_by('-created_at')
+
+ # Check if current page is versioned
+ if hasattr(request, 'resolver_match') and request.resolver_match:
+ view_func = request.resolver_match.func
+ if hasattr(view_func, 'view_class'):
+ view_class = view_func.view_class
+ context['page_is_versioned'] = hasattr(view_class, 'model') and \
+ hasattr(view_class.model, 'history')
+
+ return {'version_control': context}
\ No newline at end of file
diff --git a/history_tracking/managers.py b/history_tracking/managers.py
index c4ef39c8..16dd2f19 100644
--- a/history_tracking/managers.py
+++ b/history_tracking/managers.py
@@ -1,8 +1,9 @@
-from typing import Optional, List, Dict, Any, Tuple
+from typing import Optional, List, Dict, Any, Tuple, Union
from django.db import transaction
from django.core.exceptions import ValidationError
from django.utils import timezone
from django.contrib.auth import get_user_model
+from django.contrib.auth.models import AbstractUser
from django.contrib.contenttypes.models import ContentType
from .models import VersionBranch, VersionTag, ChangeSet
@@ -11,10 +12,8 @@ User = get_user_model()
class BranchManager:
"""Manages version control branch operations"""
- @transaction.atomic
def create_branch(self, name: str, parent: Optional[VersionBranch] = None,
- user: Optional[User] = None) -> VersionBranch:
- """Create a new version branch"""
+ user: Optional['User'] = None) -> VersionBranch:
branch = VersionBranch.objects.create(
name=name,
parent=parent,
@@ -29,7 +28,7 @@ class BranchManager:
@transaction.atomic
def merge_branches(self, source: VersionBranch, target: VersionBranch,
- user: Optional[User] = None) -> Tuple[bool, List[Dict[str, Any]]]:
+ user: Optional['User'] = None) -> Tuple[bool, List[Dict[str, Any]]]:
"""
Merge source branch into target branch
Returns: (success, conflicts)
@@ -66,9 +65,8 @@ class BranchManager:
class ChangeTracker:
"""Tracks and manages changes across the system"""
- @transaction.atomic
def record_change(self, instance: Any, change_type: str,
- branch: VersionBranch, user: Optional[User] = None,
+ branch: VersionBranch, user: Optional['User'] = None,
metadata: Optional[Dict] = None) -> ChangeSet:
"""Record a change in the system"""
if not hasattr(instance, 'history'):
diff --git a/history_tracking/templates/history_tracking/includes/version_control_ui.html b/history_tracking/templates/history_tracking/includes/version_control_ui.html
new file mode 100644
index 00000000..5a643a2a
--- /dev/null
+++ b/history_tracking/templates/history_tracking/includes/version_control_ui.html
@@ -0,0 +1,94 @@
+{% if version_control.vcs_enabled and version_control.page_is_versioned %}
+
+
+
+
+
Version Control
+ {% if version_control.current_branch %}
+
+ Current Branch:
+ {{ version_control.branch_name }}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+ {% if version_control.available_branches %}
+
+ {% for branch in version_control.available_branches %}
+
+ {% endfor %}
+ {% endif %}
+
+
+
+
+
+ {% if version_control.recent_changes %}
+
+
Recent Changes
+
+ {% for change in version_control.recent_changes %}
+
+
+
+ {{ change.description }}
+
+ {{ change.created_at|date:"M d, Y H:i" }}
+ {% if change.created_by %}
+ by {{ change.created_by.username }}
+ {% endif %}
+
+
+
+ {{ change.status|title }}
+
+
+
+ {% endfor %}
+
+
+ {% endif %}
+
+
+
+
+
+
+
+
+
+
+{% endif %}
\ No newline at end of file
diff --git a/history_tracking/utils.py b/history_tracking/utils.py
index e3f11ef6..a4956b6a 100644
--- a/history_tracking/utils.py
+++ b/history_tracking/utils.py
@@ -1,17 +1,53 @@
-from typing import Dict, Any, List, Optional
+from typing import Dict, Any, List, Optional, TypeVar, Type, Union, cast
from django.core.exceptions import ValidationError
from .models import VersionBranch, ChangeSet
from django.utils import timezone
from django.contrib.auth import get_user_model
+from django.contrib.auth.models import AbstractUser
+from django.db.models import Model
-User = get_user_model()
+UserModel = TypeVar('UserModel', bound=AbstractUser)
+User = cast(Type[UserModel], get_user_model())
+
+def _handle_source_target_resolution(change: ChangeSet) -> Dict[str, Any]:
+ resolved = {}
+ for record in change.historical_records.all():
+ resolved[f"{record.instance_type}_{record.instance_pk}"] = record
+ return resolved
+def _handle_manual_resolution(
+ conflict_id: str,
+ source_change: ChangeSet,
+ manual_resolutions: Dict[str, str],
+ user: Optional[UserModel]
+) -> Dict[str, Any]:
+ manual_content = manual_resolutions.get(conflict_id)
+ if not manual_content:
+ raise ValidationError(f"Manual resolution missing for conflict {conflict_id}")
+
+ resolved = {}
+ base_record = source_change.historical_records.first()
+ if base_record:
+ new_record = base_record.__class__(
+ **{
+ **base_record.__dict__,
+ 'id': base_record.id,
+ 'history_date': timezone.now(),
+ 'history_user': user,
+ 'history_change_reason': 'Manual conflict resolution',
+ 'history_type': '~'
+ }
+ )
+ for field, value in manual_content.items():
+ setattr(new_record, field, value)
+ resolved[f"{new_record.instance_type}_{new_record.instance_pk}"] = new_record
+ return resolved
def resolve_conflicts(
source_branch: VersionBranch,
target_branch: VersionBranch,
resolutions: Dict[str, str],
manual_resolutions: Dict[str, str],
- user: Optional[User] = None
+ user: Optional[UserModel] = None
) -> ChangeSet:
"""
Resolve merge conflicts between branches
@@ -37,40 +73,14 @@ def resolve_conflicts(
target_change = ChangeSet.objects.get(pk=target_id)
if resolution_type == 'source':
- # Use source branch version
- for record in source_change.historical_records.all():
- resolved_content[f"{record.instance_type}_{record.instance_pk}"] = record
-
+ resolved_content.update(_handle_source_target_resolution(source_change))
elif resolution_type == 'target':
- # Use target branch version
- for record in target_change.historical_records.all():
- resolved_content[f"{record.instance_type}_{record.instance_pk}"] = record
-
+ resolved_content.update(_handle_source_target_resolution(target_change))
elif resolution_type == 'manual':
- # Use manual resolution
- manual_content = manual_resolutions.get(conflict_id)
- if not manual_content:
- raise ValidationError(f"Manual resolution missing for conflict {conflict_id}")
-
- # Create new historical record with manual content
- base_record = source_change.historical_records.first()
- if base_record:
- new_record = base_record.__class__(
- **{
- **base_record.__dict__,
- 'id': base_record.id,
- 'history_date': timezone.now(),
- 'history_user': user,
- 'history_change_reason': 'Manual conflict resolution',
- 'history_type': '~'
- }
- )
- # Apply manual changes
- for field, value in manual_content.items():
- setattr(new_record, field, value)
- resolved_content[f"{new_record.instance_type}_{new_record.instance_pk}"] = new_record
+ resolved_content.update(_handle_manual_resolution(
+ conflict_id, source_change, manual_resolutions, user
+ ))
- # Create resolution changeset
resolution_changeset = ChangeSet.objects.create(
branch=target_branch,
created_by=user,
@@ -83,7 +93,6 @@ def resolve_conflicts(
status='applied'
)
- # Add resolved records to changeset
for record in resolved_content.values():
resolution_changeset.historical_records.add(record)
diff --git a/memory-bank/activeContext.md b/memory-bank/activeContext.md
index 94e6e0e3..b2c110e2 100644
--- a/memory-bank/activeContext.md
+++ b/memory-bank/activeContext.md
@@ -1,58 +1,99 @@
# Active Development Context
-## Recently Completed
-- Implemented Version Control System enhancement
- - Core models and database schema
- - Business logic layer with managers
- - HTMX-based frontend integration
- - API endpoints and URL configuration
- - Signal handlers for automatic tracking
- - Documentation updated in `memory-bank/features/version-control/`
+## Current Implementation Status
+Version Control System has been implemented with core functionality and initial integration:
-## Current Status
-The Version Control System has been fully implemented according to the implementation plan and technical guide. The system provides:
-- Branch management
-- Change tracking
-- Version tagging
-- Merge operations with conflict resolution
-- Real-time UI updates via HTMX
+### Completed
+1. Core VCS Components:
+ - Base models (VersionBranch, VersionTag, ChangeSet)
+ - Business logic (BranchManager, ChangeTracker, MergeStrategy)
+ - UI components and templates
+ - Asset integration (JS/CSS)
-## Next Steps
-1. Testing
- - Create comprehensive test suite
- - Test branch operations
- - Test merge scenarios
- - Test conflict resolution
+2. Initial Integration:
+ - Park model VCS integration
+ - ParkArea model VCS integration
+ - Base template VCS support
+ - Park detail template integration
+ - Version control context processor
-2. Monitoring
- - Implement performance metrics
- - Track merge success rates
- - Monitor system health
+3. Documentation:
+ - Technical implementation guide
+ - Template integration guide
+ - Implementation checklist
+ - Base README
-3. Documentation
- - Create user guide
- - Document API endpoints
- - Add inline code documentation
+### In Progress
+1. Model Integration:
+ - [ ] Rides system
+ - [ ] Reviews system
+ - [ ] Companies system
-4. Future Enhancements
- - Branch locking mechanism
- - Advanced merge strategies
- - Custom diff viewers
- - Performance optimizations
+2. Template Updates:
+ - [ ] Park list view
+ - [ ] Ride detail/list views
+ - [ ] Review detail/list views
+ - [ ] Company detail/list views
+
+## Immediate Next Steps
+1. Model Integration (Priority)
+ ```python
+ # Add to rides/models.py:
+ class Ride(HistoricalModel):
+ # Update save method
+ def save(self, *args, **kwargs):
+ from history_tracking.signals import get_current_branch, ChangesetContextManager
+ # Add version control logic
+ ```
+
+2. Template Updates
+ ```html
+
+ {% if version_control.vcs_enabled %}
+ {% include "history_tracking/includes/version_status.html" %}
+ {% endif %}
+ ```
+
+3. Testing Setup
+ - Create test cases for model integration
+ - Verify UI functionality
+ - Test version control operations
## Active Issues
-None at present, awaiting testing phase to identify any issues.
+1. Need to ensure consistent version control behavior across models
+2. Must handle relationships between versioned models
+3. Need to implement proper cleanup for old versions
-## Recent Decisions
-- Used GenericForeignKey for flexible history tracking
-- Implemented HTMX for real-time updates
-- Structured change tracking with atomic changesets
-- Integrated with django-simple-history
+## Technical Dependencies
+- django-simple-history: Base history tracking
+- HTMX: UI interactions
+- Alpine.js: Frontend reactivity
+- Custom VCS components
-## Technical Debt
-- Need comprehensive test suite
-- Performance monitoring to be implemented
-- Documentation needs to be expanded
+## Integration Strategy
+1. Roll out model integration one app at a time
+2. Update templates to include version control UI
+3. Add list view version indicators
+4. Implement relationship handling
+
+## Monitoring Points
+- Track version control operation performance
+- Monitor database size with version history
+- Watch for merge conflicts
+- Track user interaction patterns
+
+## Code Standards
+- All versioned models inherit from HistoricalModel
+- Consistent save method implementation
+- Proper branch context management
+- Standard version control UI components
+
+## Documentation Status
+- [x] Technical implementation
+- [x] Template integration guide
+- [ ] API documentation
+- [ ] User guide
+- [ ] Admin documentation
## Current Branch
main
@@ -60,4 +101,5 @@ main
## Environment
- Django with HTMX integration
- PostgreSQL database
-- django-simple-history for base tracking
\ No newline at end of file
+- django-simple-history
+- Custom VCS extensions
\ No newline at end of file
diff --git a/memory-bank/features/version-control/README.md b/memory-bank/features/version-control/README.md
new file mode 100644
index 00000000..a58f9259
--- /dev/null
+++ b/memory-bank/features/version-control/README.md
@@ -0,0 +1,228 @@
+# ThrillWiki Version Control System
+
+## Overview
+The ThrillWiki Version Control System (VCS) provides comprehensive version tracking, branching, and merging capabilities for all content in the system. It builds upon django-simple-history while adding powerful versioning features.
+
+## Features
+- Full version history tracking
+- Branch-based development
+- Version tagging
+- Merge operations with conflict resolution
+- Real-time collaborative editing
+- Automatic change tracking
+
+## Model Integration
+
+### Making Models Version-Controlled
+To add version control to any model, inherit from `HistoricalModel`:
+
+```python
+from history_tracking.models import HistoricalModel
+
+class YourModel(HistoricalModel):
+ # Your model fields here
+ name = models.CharField(max_length=255)
+
+ class Meta:
+ # Your meta options
+```
+
+This automatically provides:
+- Full version history
+- Change tracking
+- Branch support
+- Merge capabilities
+
+### Example Integration (from parks/models.py)
+```python
+from history_tracking.models import HistoricalModel
+
+class Park(HistoricalModel):
+ name = models.CharField(max_length=255)
+ description = models.TextField()
+
+ def save(self, *args, **kwargs):
+ # Changes will be automatically tracked
+ super().save(*args, **kwargs)
+```
+
+## Usage Guide
+
+### Basic Version Control Operations
+
+1. Creating a Branch
+```python
+from history_tracking.managers import BranchManager
+
+# Create a new feature branch
+branch_manager = BranchManager()
+feature_branch = branch_manager.create_branch(
+ name="feature/new-park-details",
+ user=request.user
+)
+```
+
+2. Recording Changes
+```python
+from history_tracking.signals import ChangesetContextManager
+
+# Making changes in a specific branch
+with ChangesetContextManager(branch=feature_branch, user=request.user):
+ park = Park.objects.get(id=1)
+ park.description = "Updated description"
+ park.save() # Change is automatically tracked in the branch
+```
+
+3. Merging Changes
+```python
+# Merge feature branch back to main
+success, conflicts = branch_manager.merge_branches(
+ source=feature_branch,
+ target=main_branch,
+ user=request.user
+)
+
+if not success:
+ # Handle merge conflicts
+ for conflict in conflicts:
+ # Resolve conflicts through UI or programmatically
+ pass
+```
+
+4. Working with Tags
+```python
+from history_tracking.models import VersionTag
+
+# Tag a specific version
+VersionTag.objects.create(
+ name="v1.0.0",
+ branch=main_branch,
+ content_type=ContentType.objects.get_for_model(park),
+ object_id=park.id,
+ created_by=user
+)
+```
+
+## UI Integration
+
+### HTMX Components
+The system provides HTMX-powered components for real-time version control:
+
+1. Version Control Panel
+```html
+{% include "history_tracking/version_control_panel.html" %}
+```
+
+2. Branch Selection
+```html
+
+
+```
+
+3. Change History
+```html
+
+
+```
+
+## Best Practices
+
+1. Branch Management
+- Create feature branches for significant changes
+- Use descriptive branch names (e.g., "feature/new-park-system")
+- Clean up merged branches
+- Regularly sync with main branch
+
+2. Change Tracking
+- Make atomic, related changes
+- Provide clear change descriptions
+- Group related changes in a single changeset
+- Review changes before merging
+
+3. Conflict Resolution
+- Resolve conflicts promptly
+- Communicate with team members about overlapping changes
+- Test after resolving conflicts
+- Document resolution decisions
+
+4. Performance
+- Use changesets for bulk operations
+- Index frequently queried fields
+- Clean up old branches and tags
+- Monitor system performance
+
+## Error Handling
+
+1. Common Issues
+```python
+try:
+ branch_manager.merge_branches(source, target)
+except ValidationError as e:
+ # Handle validation errors
+except MergeConflict as e:
+ # Handle merge conflicts
+```
+
+2. Conflict Resolution
+```python
+from history_tracking.utils import resolve_conflicts
+
+resolved = resolve_conflicts(
+ source_branch=source,
+ target_branch=target,
+ resolutions={
+ 'conflict_id': 'resolution_type', # 'source', 'target', or 'manual'
+ },
+ manual_resolutions={
+ 'conflict_id': 'manual resolution content'
+ },
+ user=request.user
+)
+```
+
+## System Maintenance
+
+1. Regular Tasks
+- Clean up old branches
+- Archive old versions
+- Verify data integrity
+- Monitor system health
+
+2. Monitoring
+```python
+from history_tracking.utils import get_system_metrics
+
+metrics = get_system_metrics()
+# Check branch counts, merge success rates, etc.
+```
+
+## Security Considerations
+
+1. Access Control
+- All VCS operations require authentication
+- Branch operations are logged
+- Merge operations require proper permissions
+- Changes are tracked with user attribution
+
+2. Data Protection
+- Historical data is preserved
+- Audit logs are maintained
+- Sensitive data is handled securely
+- Backups include version history
+
+## Support and Troubleshooting
+
+For issues or questions:
+1. Check the logs for detailed error messages
+2. Review the conflict resolution documentation
+3. Verify branch and change permissions
+4. Contact the development team for assistance
+
+## Contributing
+When contributing to the VCS:
+1. Follow the established branching pattern
+2. Document significant changes
+3. Add tests for new features
+4. Update technical documentation
\ No newline at end of file
diff --git a/memory-bank/features/version-control/implementation_checklist.md b/memory-bank/features/version-control/implementation_checklist.md
new file mode 100644
index 00000000..1a3c01ba
--- /dev/null
+++ b/memory-bank/features/version-control/implementation_checklist.md
@@ -0,0 +1,159 @@
+# Version Control System Implementation Checklist
+
+## Core Implementation ✓
+- [x] Models
+ - [x] VersionBranch
+ - [x] VersionTag
+ - [x] ChangeSet
+ - [x] Generic relationships for flexibility
+
+- [x] Managers
+ - [x] BranchManager
+ - [x] ChangeTracker
+ - [x] MergeStrategy
+
+- [x] UI Components
+ - [x] Version Control Panel
+ - [x] Branch List
+ - [x] History View
+ - [x] Merge Panel
+ - [x] Branch Creation Form
+
+## Asset Integration ✓
+- [x] JavaScript
+ - [x] Version Control core functionality
+ - [x] HTMX integration
+ - [x] Event handling
+
+- [x] CSS
+ - [x] Version control styles
+ - [x] Component styles
+ - [x] Responsive design
+
+## Template Integration
+- [x] Base Template Updates
+ - [x] Required JS/CSS includes
+ - [x] Version control status bar
+ - [x] HTMX setup
+
+- [x] Park System
+ - [x] Park detail template
+ - [ ] Park list template
+ - [ ] Area detail template
+
+- [ ] Rides System
+ - [ ] Ride detail template
+ - [ ] Ride list template
+
+- [ ] Reviews System
+ - [ ] Review detail template
+ - [ ] Review list template
+
+- [ ] Companies System
+ - [ ] Company detail template
+ - [ ] Company list template
+
+## Model Integration
+- [x] Park Model
+ - [x] VCS integration
+ - [x] Save method override
+ - [x] Version info methods
+
+- [x] ParkArea Model
+ - [x] VCS integration
+ - [x] Save method override
+ - [x] Version info methods
+
+- [ ] Ride Model
+ - [ ] VCS integration
+ - [ ] Save method override
+ - [ ] Version info methods
+
+- [ ] Review Model
+ - [ ] VCS integration
+ - [ ] Save method override
+ - [ ] Version info methods
+
+- [ ] Company Model
+ - [ ] VCS integration
+ - [ ] Save method override
+ - [ ] Version info methods
+
+## Documentation
+- [x] README creation
+- [x] Implementation guide
+- [x] Template integration guide
+- [ ] API documentation
+- [ ] User guide
+
+## Testing Requirements
+- [ ] Unit Tests
+ - [ ] Model tests
+ - [ ] Manager tests
+ - [ ] View tests
+ - [ ] Form tests
+
+- [ ] Integration Tests
+ - [ ] Branch operations
+ - [ ] Merge operations
+ - [ ] Change tracking
+ - [ ] UI interactions
+
+- [ ] UI Tests
+ - [ ] Component rendering
+ - [ ] User interactions
+ - [ ] Responsive design
+ - [ ] Browser compatibility
+
+## Monitoring Setup
+- [ ] Performance Metrics
+ - [ ] Branch operation timing
+ - [ ] Merge success rates
+ - [ ] Change tracking overhead
+ - [ ] UI responsiveness
+
+- [ ] Error Tracking
+ - [ ] Operation failures
+ - [ ] Merge conflicts
+ - [ ] UI errors
+ - [ ] Performance issues
+
+## Next Steps
+1. Complete model integrations:
+ - Update Ride model
+ - Update Review model
+ - Update Company model
+
+2. Template implementations:
+ - Create remaining detail templates
+ - Add version control to list views
+ - Implement version indicators
+
+3. Testing:
+ - Write comprehensive test suite
+ - Set up CI/CD integration
+ - Perform load testing
+
+4. Documentation:
+ - Complete API documentation
+ - Create user guide
+ - Add examples and tutorials
+
+5. Monitoring:
+ - Set up performance monitoring
+ - Configure error tracking
+ - Create dashboards
+
+## Known Issues
+1. Need to implement proper error handling in JavaScript
+2. Add loading states to UI components
+3. Implement proper caching for version history
+4. Add batch operations for multiple changes
+5. Implement proper cleanup for old versions
+
+## Future Enhancements
+1. Add visual diff viewer
+2. Implement branch locking
+3. Add commenting on changes
+4. Create change approval workflow
+5. Add version comparison tool
\ No newline at end of file
diff --git a/memory-bank/features/version-control/template_integration.md b/memory-bank/features/version-control/template_integration.md
new file mode 100644
index 00000000..4e8c796f
--- /dev/null
+++ b/memory-bank/features/version-control/template_integration.md
@@ -0,0 +1,86 @@
+# Version Control UI Template Integration
+
+## Templates Requiring VCS Integration
+
+### Park System
+- [x] parks/templates/parks/park_detail.html - Completed
+- [ ] parks/templates/parks/park_list.html - Add version status indicators
+- [ ] parks/templates/parks/park_area_detail.html - Add version control UI
+
+### Rides System
+- [ ] rides/templates/rides/ride_detail.html - Add version control UI
+- [ ] rides/templates/rides/ride_list.html - Add version status indicators
+
+### Reviews System
+- [ ] reviews/templates/reviews/review_detail.html - Add version control UI
+- [ ] reviews/templates/reviews/review_list.html - Add version status indicators
+
+### Company System
+- [ ] companies/templates/companies/company_detail.html - Add version control UI
+- [ ] companies/templates/companies/company_list.html - Add version status indicators
+
+## Integration Guidelines
+
+### Detail Templates
+For detail templates, add the version control UI below the main title:
+
+```html
+
+
{{ object.name }}
+
+
+{% include "history_tracking/includes/version_control_ui.html" %}
+
+
+```
+
+### List Templates
+For list templates, add version indicators in the list items:
+
+```html
+{% for item in object_list %}
+
+{% endfor %}
+```
+
+## Integration Steps
+
+1. Update base template to include necessary JavaScript
+```html
+
+
+```
+
+2. Add version control UI to detail views
+- Include the version control UI component
+- Add branch switching functionality
+- Display version history
+
+3. Add version indicators to list views
+- Show current branch
+- Indicate if changes are pending
+- Show version status
+
+4. Update view classes
+- Ensure models inherit from HistoricalModel
+- Add version control context
+- Handle branch switching
+
+5. Test integration
+- Verify UI appears correctly
+- Test branch switching
+- Verify history tracking
+- Test merge functionality
+
+## Next Steps
+1. Create park area detail template with version control
+2. Update ride detail template
+3. Add version control to review system
+4. Integrate with company templates
\ No newline at end of file
diff --git a/memory-bank/features/version-control/ui_improvements.md b/memory-bank/features/version-control/ui_improvements.md
new file mode 100644
index 00000000..0ab8899f
--- /dev/null
+++ b/memory-bank/features/version-control/ui_improvements.md
@@ -0,0 +1,110 @@
+# Version Control System UI Improvements
+
+## Recent Improvements
+
+### 1. Template Structure Enhancement
+- Moved map initialization to dedicated JavaScript file
+- Implemented data attribute pattern for passing data to JavaScript
+- Improved template organization and maintainability
+
+### 2. JavaScript Organization
+- Created separate `map-init.js` for map functionality
+- Established pattern for external JavaScript files
+- Improved error handling and script loading
+
+### 3. Asset Management
+```javascript
+// Static Asset Organization
+/static/
+ /js/
+ version-control.js // Core VCS functionality
+ map-init.js // Map initialization logic
+ /css/
+ version-control.css // VCS styles
+```
+
+## Best Practices Established
+
+### 1. Data Passing Pattern
+```html
+
+
+
+```
+
+### 2. JavaScript Separation
+```javascript
+// Modular JavaScript organization
+document.addEventListener('DOMContentLoaded', function() {
+ // Initialize components
+ const mapContainer = document.getElementById('map');
+ if (mapContainer) {
+ // Component-specific logic
+ }
+});
+```
+
+### 3. Template Structure
+```html
+{% block content %}
+
+{% endblock %}
+
+{% block extra_js %}
+ {{ block.super }}
+
+
+{% endblock %}
+```
+
+## Integration Guidelines
+
+### 1. Adding New Components
+1. Create dedicated JavaScript file in `/static/js/`
+2. Use data attributes for configuration
+3. Follow established loading pattern
+4. Update base template if needed
+
+### 2. Version Control UI
+1. Include version control UI component
+2. Add necessary data attributes
+3. Ensure proper script loading
+4. Follow established patterns
+
+### 3. Static Asset Management
+1. Keep JavaScript files modular
+2. Use proper static file organization
+3. Follow naming conventions
+4. Maintain clear dependencies
+
+## Next Steps
+
+1. Apply this pattern to other templates:
+ - Ride detail template
+ - Review detail template
+ - Company detail template
+
+2. Implement consistent error handling:
+ ```javascript
+ function handleError(error) {
+ console.error('Component error:', error);
+ // Handle error appropriately
+ }
+ ```
+
+3. Add performance monitoring:
+ ```javascript
+ // Add timing measurements
+ const startTime = performance.now();
+ // Component initialization
+ const endTime = performance.now();
+ console.debug(`Component initialized in ${endTime - startTime}ms`);
+ ```
+
+4. Documentation updates:
+ - Add JavaScript patterns to technical guide
+ - Update template integration guide
+ - Document asset organization
\ No newline at end of file
diff --git a/parks/models.py b/parks/models.py
index d6ed5903..d15fffc1 100644
--- a/parks/models.py
+++ b/parks/models.py
@@ -73,7 +73,50 @@ class Park(HistoricalModel):
def save(self, *args: Any, **kwargs: Any) -> None:
if not self.slug:
self.slug = slugify(self.name)
- super().save(*args, **kwargs)
+
+ # Get the branch from context or use default
+ from history_tracking.signals import get_current_branch
+ current_branch = get_current_branch()
+
+ if current_branch:
+ # Save in the context of the current branch
+ super().save(*args, **kwargs)
+ else:
+ # If no branch context, save in main branch
+ from history_tracking.models import VersionBranch
+ main_branch, _ = VersionBranch.objects.get_or_create(
+ name='main',
+ defaults={'metadata': {'type': 'default_branch'}}
+ )
+
+ from history_tracking.signals import ChangesetContextManager
+ with ChangesetContextManager(branch=main_branch):
+ super().save(*args, **kwargs)
+
+ def get_version_info(self) -> dict:
+ """Get version control information for this park"""
+ from history_tracking.models import VersionBranch, ChangeSet
+ from django.contrib.contenttypes.models import ContentType
+
+ content_type = ContentType.objects.get_for_model(self)
+ latest_changes = ChangeSet.objects.filter(
+ content_type=content_type,
+ object_id=self.pk,
+ status='applied'
+ ).order_by('-created_at')[:5]
+
+ active_branches = VersionBranch.objects.filter(
+ changesets__content_type=content_type,
+ changesets__object_id=self.pk,
+ is_active=True
+ ).distinct()
+
+ return {
+ 'latest_changes': latest_changes,
+ 'active_branches': active_branches,
+ 'current_branch': get_current_branch(),
+ 'total_changes': latest_changes.count()
+ }
def get_absolute_url(self) -> str:
return reverse("parks:park_detail", kwargs={"slug": self.slug})
@@ -134,7 +177,51 @@ class ParkArea(HistoricalModel):
def save(self, *args: Any, **kwargs: Any) -> None:
if not self.slug:
self.slug = slugify(self.name)
- super().save(*args, **kwargs)
+
+ # Get the branch from context or use default
+ from history_tracking.signals import get_current_branch
+ current_branch = get_current_branch()
+
+ if current_branch:
+ # Save in the context of the current branch
+ super().save(*args, **kwargs)
+ else:
+ # If no branch context, save in main branch
+ from history_tracking.models import VersionBranch
+ main_branch, _ = VersionBranch.objects.get_or_create(
+ name='main',
+ defaults={'metadata': {'type': 'default_branch'}}
+ )
+
+ from history_tracking.signals import ChangesetContextManager
+ with ChangesetContextManager(branch=main_branch):
+ super().save(*args, **kwargs)
+
+ def get_version_info(self) -> dict:
+ """Get version control information for this park area"""
+ from history_tracking.models import VersionBranch, ChangeSet
+ from django.contrib.contenttypes.models import ContentType
+
+ content_type = ContentType.objects.get_for_model(self)
+ latest_changes = ChangeSet.objects.filter(
+ content_type=content_type,
+ object_id=self.pk,
+ status='applied'
+ ).order_by('-created_at')[:5]
+
+ active_branches = VersionBranch.objects.filter(
+ changesets__content_type=content_type,
+ changesets__object_id=self.pk,
+ is_active=True
+ ).distinct()
+
+ return {
+ 'latest_changes': latest_changes,
+ 'active_branches': active_branches,
+ 'current_branch': get_current_branch(),
+ 'total_changes': latest_changes.count(),
+ 'parent_park_branch': self.park.get_version_info()['current_branch']
+ }
def get_absolute_url(self) -> str:
return reverse(
diff --git a/parks/templates/parks/park_detail.html b/parks/templates/parks/park_detail.html
new file mode 100644
index 00000000..fbcfee01
--- /dev/null
+++ b/parks/templates/parks/park_detail.html
@@ -0,0 +1,200 @@
+{% extends "base.html" %}
+{% load static %}
+
+{% block title %}{{ park.name }} - ThrillWiki{% endblock %}
+
+{% block content %}
+
+
+
+
+
+ {% include "history_tracking/includes/version_control_ui.html" %}
+
+
+