From 2990bf106c52e66761d065e5bc90cea589921b81 Mon Sep 17 00:00:00 2001 From: goose-life <32566441+goose-life@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:20:14 +0200 Subject: [PATCH] add element_id to DocumentAPISerializer, use instead of DocumentDiffSerializer --- indigo_api/serializers.py | 12 +--------- indigo_api/views/documents.py | 23 +++++++++++++++---- .../indigo/views/document_editor.js | 7 +++--- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/indigo_api/serializers.py b/indigo_api/serializers.py index 3a4c3fa8f..4361ba238 100644 --- a/indigo_api/serializers.py +++ b/indigo_api/serializers.py @@ -439,6 +439,7 @@ class DocumentAPISerializer(serializers.Serializer): xml = serializers.CharField() language = serializers.CharField(min_length=3, max_length=3) provision_eid = serializers.CharField(allow_blank=True) + element_id = serializers.CharField(required=False, allow_null=True, allow_blank=True) def validate_xml(self, xml): """ mostly copied from DocumentSerializer.validate() @@ -714,14 +715,3 @@ def get_url(self, instance): 'work_id': instance.amended_work.pk, 'pk': instance.pk, }) - - -class DocumentDiffSerializer(serializers.Serializer): - """ Helper to handle input elements for the /document/xxx/diff API - """ - document = DocumentSerializer(required=True) - element_id = serializers.CharField(required=False, allow_null=True) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields['document'].instance = self.instance diff --git a/indigo_api/views/documents.py b/indigo_api/views/documents.py index 294232800..8e081bbb7 100644 --- a/indigo_api/views/documents.py +++ b/indigo_api/views/documents.py @@ -24,6 +24,7 @@ from django_filters.rest_framework import DjangoFilterBackend from cobalt import StructuredDocument +from lxml import etree import lxml.html.diff from indigo.analysis.differ import AKNHTMLDiffer @@ -31,7 +32,7 @@ from indigo.plugins import plugins from indigo.xmlutils import parse_html_str from ..models import Document, Annotation, DocumentActivity, Task, Language, Work -from ..serializers import DocumentSerializer, RenderSerializer, ParseSerializer, DocumentAPISerializer, VersionSerializer, AnnotationSerializer, DocumentActivitySerializer, TaskSerializer, DocumentDiffSerializer +from ..serializers import DocumentSerializer, RenderSerializer, ParseSerializer, DocumentAPISerializer, VersionSerializer, AnnotationSerializer, DocumentActivitySerializer, TaskSerializer from ..renderers import AkomaNtosoRenderer, PDFRenderer, EPUBRenderer, HTMLRenderer, ZIPRenderer from indigo_api.exporters import HTMLExporter from ..authz import DocumentPermissions, AnnotationPermissions, ModelPermissions, RelatedDocumentPermissions, \ @@ -424,7 +425,8 @@ def manipulate_xml(self): class DocumentDiffView(DocumentResourceView, APIView): def post(self, request, document_id): - serializer = DocumentDiffSerializer(instance=self.document, data=self.request.data) + serializer = DocumentAPISerializer(instance=self.document, data=self.request.data) + serializer.use_full_xml = False serializer.is_valid(raise_exception=True) differ = AKNHTMLDiffer() @@ -433,10 +435,23 @@ def post(self, request, document_id): # set this up to be the modified document remote_doc = Document.objects.get(pk=local_doc.pk) - serializer.fields['document'].update_document(local_doc, serializer.validated_data['document']) + # this will set the local_doc's content as the in provision mode, + # and update it with the latest unsaved changes regardless + serializer.set_content() local_doc.content = differ.preprocess_xml_str(local_doc.document_xml).decode('utf-8') - remote_doc.content = differ.preprocess_xml_str(remote_doc.document_xml).decode('utf-8') + + provision_eid = serializer.validated_data.get('provision_eid') + if provision_eid: + portion = remote_doc.get_portion(provision_eid) + # the same structure as the 'xml' we're getting from the browser: akn/portion/portionBody/element + remote_xml = etree.tostring(portion.root, encoding='unicode') + remote_doc.work.work_uri.doctype = 'portion' + remote_doc.content = differ.preprocess_xml_str(remote_xml) + + else: + # full document mode + remote_doc.content = differ.preprocess_xml_str(remote_doc.document_xml).decode('utf-8') element_id = serializer.validated_data.get('element_id') if element_id: diff --git a/indigo_app/static/javascript/indigo/views/document_editor.js b/indigo_app/static/javascript/indigo/views/document_editor.js index 6d7594f88..443d10312 100644 --- a/indigo_app/static/javascript/indigo/views/document_editor.js +++ b/indigo_app/static/javascript/indigo/views/document_editor.js @@ -262,13 +262,12 @@ }, renderComparisonDiff: function() { - var self = this, - data = {}; + let self = this; if (!this.comparisonDocumentId) return; - data.document = this.document.toJSON(); - data.document.content = this.document.content.toXml(); + const data = this.document.content.toSimplifiedJSON(); + // slight difference to provision_eid -- doesn't treat the document XML as a portion data.element_id = this.xmlElement.getAttribute('eId'); if (!data.element_id && this.xmlElement.tagName !== "akomaNtoso") {