Add version control context processor and integrate map functionality with dedicated JavaScript

This commit is contained in:
pacnpal
2025-02-06 20:06:10 -05:00
parent 939eaed201
commit d3141ab320
16 changed files with 1671 additions and 89 deletions

View File

@@ -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)