mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 15:11:09 -05:00
145 lines
5.1 KiB
Python
145 lines
5.1 KiB
Python
from django.shortcuts import render, get_object_or_404
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.core.paginator import Paginator
|
|
from django.db import transaction
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.utils import timezone
|
|
from django.contrib import messages
|
|
from django.views.decorators.http import require_http_methods
|
|
from django.core.exceptions import PermissionDenied
|
|
from typing import Dict, Any
|
|
|
|
from .models import VersionBranch, ChangeSet, VersionTag, CommentThread
|
|
from .managers import ChangeTracker
|
|
from .comparison import ComparisonEngine
|
|
from .state_machine import ApprovalStateMachine
|
|
|
|
ITEMS_PER_PAGE = 20
|
|
|
|
@login_required
|
|
def version_comparison(request: HttpRequest) -> HttpResponse:
|
|
"""View for comparing different versions"""
|
|
versions = VersionTag.objects.all().order_by('-created_at')
|
|
|
|
version1_id = request.GET.get('version1')
|
|
version2_id = request.GET.get('version2')
|
|
page_number = request.GET.get('page', 1)
|
|
|
|
diff_result = None
|
|
if version1_id and version2_id:
|
|
try:
|
|
version1 = get_object_or_404(VersionTag, id=version1_id)
|
|
version2 = get_object_or_404(VersionTag, id=version2_id)
|
|
|
|
# Get comparison results
|
|
engine = ComparisonEngine()
|
|
diff_result = engine.compute_enhanced_diff(version1, version2)
|
|
|
|
# Paginate changes
|
|
paginator = Paginator(diff_result['changes'], ITEMS_PER_PAGE)
|
|
diff_result['changes'] = paginator.get_page(page_number)
|
|
|
|
# Add comments to changes
|
|
for change in diff_result['changes']:
|
|
anchor_id = change['metadata']['comment_anchor_id']
|
|
change['comments'] = CommentThread.objects.filter(
|
|
anchor__contains={'id': anchor_id}
|
|
).prefetch_related('comments')
|
|
|
|
except Exception as e:
|
|
messages.error(request, f"Error comparing versions: {str(e)}")
|
|
|
|
context = {
|
|
'versions': versions,
|
|
'selected_version1': version1_id,
|
|
'selected_version2': version2_id,
|
|
'diff_result': diff_result
|
|
}
|
|
|
|
return render(request, 'history_tracking/version_comparison.html', context)
|
|
|
|
@login_required
|
|
@require_http_methods(["POST"])
|
|
@transaction.atomic
|
|
def submit_for_approval(request: HttpRequest, changeset_id: int) -> HttpResponse:
|
|
"""Submit a changeset for approval"""
|
|
changeset = get_object_or_404(ChangeSet, pk=changeset_id)
|
|
|
|
if not request.user.has_perm('history_tracking.submit_for_approval'):
|
|
raise PermissionDenied("You don't have permission to submit changes for approval")
|
|
|
|
try:
|
|
# Initialize approval workflow
|
|
state_machine = ApprovalStateMachine(changeset)
|
|
stages_config = [
|
|
{
|
|
'name': 'Technical Review',
|
|
'required_roles': ['tech_reviewer']
|
|
},
|
|
{
|
|
'name': 'Final Approval',
|
|
'required_roles': ['approver']
|
|
}
|
|
]
|
|
|
|
state_machine.initialize_workflow(stages_config)
|
|
changeset.status = 'pending_approval'
|
|
changeset.save()
|
|
|
|
messages.success(request, "Changes submitted for approval successfully")
|
|
|
|
except Exception as e:
|
|
messages.error(request, f"Error submitting for approval: {str(e)}")
|
|
|
|
return render(request, 'history_tracking/approval_status.html', {
|
|
'changeset': changeset
|
|
})
|
|
|
|
@login_required
|
|
def approval_status(request: HttpRequest, changeset_id: int) -> HttpResponse:
|
|
"""View approval status of a changeset"""
|
|
changeset = get_object_or_404(ChangeSet, pk=changeset_id)
|
|
state_machine = ApprovalStateMachine(changeset)
|
|
current_stage = state_machine.get_current_stage()
|
|
|
|
context = {
|
|
'changeset': changeset,
|
|
'current_stage': current_stage,
|
|
'can_approve': state_machine.can_user_approve(request.user),
|
|
'pending_approvers': state_machine.get_pending_approvers()
|
|
}
|
|
|
|
return render(request, 'history_tracking/approval_status.html', context)
|
|
|
|
@login_required
|
|
@require_http_methods(["POST"])
|
|
@transaction.atomic
|
|
def approve_changes(request: HttpRequest, changeset_id: int) -> HttpResponse:
|
|
"""Submit an approval decision"""
|
|
changeset = get_object_or_404(ChangeSet, pk=changeset_id)
|
|
state_machine = ApprovalStateMachine(changeset)
|
|
|
|
try:
|
|
decision = request.POST.get('decision', 'approve')
|
|
comment = request.POST.get('comment', '')
|
|
stage_id = request.POST.get('stage_id')
|
|
|
|
success = state_machine.submit_approval(
|
|
user=request.user,
|
|
decision=decision,
|
|
comment=comment,
|
|
stage_id=stage_id
|
|
)
|
|
|
|
if success:
|
|
messages.success(request, f"Successfully {decision}d changes")
|
|
else:
|
|
messages.error(request, "Failed to submit approval")
|
|
|
|
except Exception as e:
|
|
messages.error(request, f"Error processing approval: {str(e)}")
|
|
|
|
return render(request, 'history_tracking/approval_status.html', {
|
|
'changeset': changeset
|
|
})
|