From a23be0c173e7488b7ef23f73c94f0eb03b60287b Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 28 Jun 2021 15:43:08 -0400 Subject: [PATCH 01/17] set up code for adding new attributes --- frontend/components/Documents.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/frontend/components/Documents.js b/frontend/components/Documents.js index 4eb241d4..12484167 100644 --- a/frontend/components/Documents.js +++ b/frontend/components/Documents.js @@ -13,6 +13,7 @@ const Documents = () => { "year": "", "text": "" }); + const [newAttributes, setNewAttributes] = useState([{"name": "", "value": ""}]); const [loading, setLoading] = useState(true); const [addingDoc, setAddingDoc] = useState(false); const [showModal, setShowModal] = useState(false); @@ -151,6 +152,27 @@ const Documents = () => { onChange={handleTextInputChange} required> +

Attributes

+
+ { + newAttributes.map((attribute, i) => { + return ( + <> +
+ +
+
+ +
+
+ {newAttributes.length !== 1 && } + {newAttributes.length - 1 === i && } +
+ + ); + }) + } +
} - {newAttributes.length - 1 === i && } +
+ + handleAttributeInputChange(event,i)} + placeholder="value" value={attribute.value}/>
- - ); - }) - } - + {newAttributes.length !== 1 && +
+ +
} + {newAttributes.length - 1 === i && +
+ +
} + + ); + }) + } - @@ -192,12 +223,9 @@ const Documents = () => {

This page displays all the documents stored in backend.

- { - addingDoc - ?
- Currently adding document... Please do not close this tab. -
- : null + {addingDoc &&
+ Currently adding document... Please do not close this tab. +
} {addDocModal()} { From 407f27c5e1321004b594c40df024e43c75cccee3 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Fri, 9 Jul 2021 17:02:04 -0400 Subject: [PATCH 03/17] create api endpoints to add corpus and get all corpora and add link to react component --- backend/app/views.py | 46 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/backend/app/views.py b/backend/app/views.py index 5e427379..f599e536 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -27,12 +27,14 @@ from django.shortcuts import render from .models import ( Document, - Gender + Gender, + Corpus ) from .serializers import ( DocumentSerializer, SimpleDocumentSerializer, - GenderSerializer + GenderSerializer, + CorpusSerializer ) @@ -173,3 +175,43 @@ def all_genders(request): gender_objs = Gender.objects.all() serializer = GenderSerializer(gender_objs, many=True) return Response(serializer.data) + + +@api_view(['POST']) +def add_corpus(request): + """ + API endpoint for adding a corpus instance + """ + attributes = request.data + fields = { + 'title': attributes['title'], + 'description': attributes['description'] + } + new_corpus_obj = Corpus.objects.create(**fields) + serializer = CorpusSerializer(new_corpus_obj) + return Response(serializer.data) + + +@api_view(['GET']) +def all_corpora(request): + """ + API Endpoint to get all the corpora + """ + corpus_objs = Corpus.objects.all() + serializer = CorpusSerializer(corpus_objs, many=True) + return Response(serializer.data) + + +def corpora(request): + """ + Corpora page + """ + + context = { + 'page_metadata': { + 'title': 'Corpora' + }, + 'component_name': 'Corpora' + } + + return render(request, 'index.html', context) From 5f545312fa5edc392ea989e976e5b915f270410c Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Fri, 9 Jul 2021 17:27:22 -0400 Subject: [PATCH 04/17] add nw_attributes to serializer --- backend/app/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/serializers.py b/backend/app/serializers.py index 44a9cb66..79fbb11a 100644 --- a/backend/app/serializers.py +++ b/backend/app/serializers.py @@ -40,7 +40,7 @@ class DocumentSerializer(serializers.ModelSerializer): class Meta: model = Document - fields = ['id', 'author', 'title', 'year', 'text', 'word_count'] + fields = ['id', 'author', 'title', 'year', 'text', 'word_count', 'new_attributes'] class SimpleDocumentSerializer(serializers.ModelSerializer): From 554fec48e8ef5902783083afb342fb85e584151b Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Fri, 9 Jul 2021 17:27:44 -0400 Subject: [PATCH 05/17] add new_attributes to database --- backend/app/views.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/app/views.py b/backend/app/views.py index 5e427379..e9d36acc 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -101,11 +101,17 @@ def add_document(request): API endpoint for adding a piece of document """ attributes = request.data + new_attributes = {} + for attribute in attributes['newAttributes']: + key, value = attribute['name'], attribute['value'] + if key and value: + new_attributes[key] = value fields = { 'title': attributes['title'], 'author': attributes['author'], 'year': attributes['year'] if attributes['year'] != '' else None, - 'text': attributes['text'] + 'text': attributes['text'], + 'new_attributes': new_attributes } new_text_obj = Document.objects.create_document(**fields) serializer = DocumentSerializer(new_text_obj) From 5dadd6581c0911cce76679733238107a7cdcc87b Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Fri, 9 Jul 2021 17:28:11 -0400 Subject: [PATCH 06/17] update frontend to catch any edge cases with creating document and displaying --- frontend/components/Documents.js | 15 ++++++++++----- frontend/components/SingleDocument.js | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/frontend/components/Documents.js b/frontend/components/Documents.js index 7fe873ee..72956863 100644 --- a/frontend/components/Documents.js +++ b/frontend/components/Documents.js @@ -90,7 +90,8 @@ const Documents = () => { title: newDocData.title, year: newDocData.year, author: newDocData.author, - text: newDocData.text + text: newDocData.text, + newAttributes: newAttributes }) }; fetch("api/add_document", requestOptions) @@ -114,7 +115,7 @@ const Documents = () => {
{doc.title}

- {doc.author} + {doc.author ? doc.author : "Unknown"}
Year Published: {doc.year ? doc.year : "Unknown"}
@@ -163,7 +164,7 @@ const Documents = () => {

+ onChange={handleTitleInputChange} required/>
@@ -194,13 +195,17 @@ const Documents = () => { handleAttributeInputChange(event,i)} - placeholder="name" value={attribute.name}/> + placeholder="name" value={attribute.name} + required={newAttributes[i]["value"] + ? true : false}/>
handleAttributeInputChange(event,i)} - placeholder="value" value={attribute.value}/> + placeholder="value" value={attribute.value} + required={newAttributes[i]["name"] + ? true : false}/>
{newAttributes.length !== 1 &&
diff --git a/frontend/components/SingleDocument.js b/frontend/components/SingleDocument.js index b1d8c123..d95029c8 100644 --- a/frontend/components/SingleDocument.js +++ b/frontend/components/SingleDocument.js @@ -26,7 +26,7 @@ const SingleDocument = ({id}) => { :

{docData.title}

- Author: {docData.author} + Author: {docData.author ? docData.author : "Unknown"}
Year Published {docData.year ? docData.year : "Unknown"}
From 11d20bfd91969e5e332b23354417043180ab77a1 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 14:25:38 -0400 Subject: [PATCH 07/17] add paths for api endpoints and corpora page --- backend/config/urls.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/config/urls.py b/backend/config/urls.py index 5e7f5118..1d1b7eb4 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -30,11 +30,14 @@ path('api/add_document', views.add_document), path('api/document/', views.get_document), path('api/all_genders', views.all_genders), + path('api/all_corpora', views.all_corpora), + path('api/add_corpus', views.add_corpus), # View paths path('', views.index, name='index'), path('example', views.example, name='example'), path('example/', views.example_id, name='example_id'), path('documents', views.documents, name='documents'), - path('document/', views.single_document, name='document') + path('document/', views.single_document, name='document'), + path('corpora', views.corpora, name='corpora') ] From 1fcd254b8aeeee7531d4aa2267058c477e3890b8 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 14:37:17 -0400 Subject: [PATCH 08/17] add API endpoint to update the documents in a corpus --- backend/app/views.py | 14 ++++++++++++++ backend/config/urls.py | 1 + 2 files changed, 15 insertions(+) diff --git a/backend/app/views.py b/backend/app/views.py index f599e536..7db1ac54 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -192,6 +192,20 @@ def add_corpus(request): return Response(serializer.data) +@api_view(['POST']) +def update_corpus_docs(request): + """ + API endpoint for updating the documents in a corpus + """ + corpus_data = request.data + corpus_id = corpus_data['id'] + docs_list = corpus_data['documents'] + corpus_obj = Corpus.objects.get(id=corpus_id) + corpus_obj.documents.set(docs_list) + serializer = CorpusSerializer(corpus_obj) + return Response(serializer.data) + + @api_view(['GET']) def all_corpora(request): """ diff --git a/backend/config/urls.py b/backend/config/urls.py index 1d1b7eb4..7312944d 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -32,6 +32,7 @@ path('api/all_genders', views.all_genders), path('api/all_corpora', views.all_corpora), path('api/add_corpus', views.add_corpus), + path('api/update_corpus_docs', views.update_corpus_docs), # View paths path('', views.index, name='index'), From 4d3147b721e447bb04b31fceecd412094fe2d799 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 15:13:35 -0400 Subject: [PATCH 09/17] update api to take in a list of document ids --- backend/app/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/views.py b/backend/app/views.py index 7db1ac54..5f502709 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -199,9 +199,9 @@ def update_corpus_docs(request): """ corpus_data = request.data corpus_id = corpus_data['id'] - docs_list = corpus_data['documents'] + doc_ids = corpus_data['documents'] corpus_obj = Corpus.objects.get(id=corpus_id) - corpus_obj.documents.set(docs_list) + corpus_obj.documents.set(Document.objects.filter(id__in=doc_ids)) serializer = CorpusSerializer(corpus_obj) return Response(serializer.data) From 017edab79225db144ca121004eb48c149be92f8c Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 15:22:39 -0400 Subject: [PATCH 10/17] add api endpoint to delete given corpus --- backend/app/views.py | 11 +++++++++++ backend/config/urls.py | 1 + 2 files changed, 12 insertions(+) diff --git a/backend/app/views.py b/backend/app/views.py index 5f502709..0121a6a5 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -206,6 +206,17 @@ def update_corpus_docs(request): return Response(serializer.data) +@api_view(['POST']) +def delete_corpus(request): + """ + API endpoint for deleting a corpus + """ + corpus_id = request.data['id'] + corpus_obj = Corpus.objects.get(id=corpus_id) + corpus_obj.delete() + return Response() + + @api_view(['GET']) def all_corpora(request): """ diff --git a/backend/config/urls.py b/backend/config/urls.py index 7312944d..9347e425 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -33,6 +33,7 @@ path('api/all_corpora', views.all_corpora), path('api/add_corpus', views.add_corpus), path('api/update_corpus_docs', views.update_corpus_docs), + path('api/delete_corpus', views.delete_corpus), # View paths path('', views.index, name='index'), From 2d0f0b34b17296d4a58ab7d5f71d4d0cdc881d6c Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 15:26:13 -0400 Subject: [PATCH 11/17] move corpora page to another branch --- backend/app/views.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/backend/app/views.py b/backend/app/views.py index 0121a6a5..2913ced2 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -225,18 +225,3 @@ def all_corpora(request): corpus_objs = Corpus.objects.all() serializer = CorpusSerializer(corpus_objs, many=True) return Response(serializer.data) - - -def corpora(request): - """ - Corpora page - """ - - context = { - 'page_metadata': { - 'title': 'Corpora' - }, - 'component_name': 'Corpora' - } - - return render(request, 'index.html', context) From 3d7f16f15f8490a94904e083d00af63e20d0f581 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 15:33:27 -0400 Subject: [PATCH 12/17] create api endpoint to get a corpus based on ID --- backend/app/views.py | 12 +++++++++++- backend/config/urls.py | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/backend/app/views.py b/backend/app/views.py index 2913ced2..6c837795 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -220,8 +220,18 @@ def delete_corpus(request): @api_view(['GET']) def all_corpora(request): """ - API Endpoint to get all the corpora + API endpoint to get all the corpora """ corpus_objs = Corpus.objects.all() serializer = CorpusSerializer(corpus_objs, many=True) return Response(serializer.data) + + +@api_view(['GET']) +def get_corpus(request, corpus_id): + """ + API endpoint to get a corpus based on id + """ + corpus_obj = Corpus.objects.get(id=corpus_id) + serializer = CorpusSerializer(corpus_obj) + return Response(serializer.data) diff --git a/backend/config/urls.py b/backend/config/urls.py index 9347e425..e6791788 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -34,6 +34,7 @@ path('api/add_corpus', views.add_corpus), path('api/update_corpus_docs', views.update_corpus_docs), path('api/delete_corpus', views.delete_corpus), + path('api/corpus/', views.get_corpus), # View paths path('', views.index, name='index'), @@ -41,5 +42,4 @@ path('example/', views.example_id, name='example_id'), path('documents', views.documents, name='documents'), path('document/', views.single_document, name='document'), - path('corpora', views.corpora, name='corpora') ] From f29f329c96662f67136e04ccfab18fed8794e738 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 12 Jul 2021 15:34:31 -0400 Subject: [PATCH 13/17] remove trailing comma --- backend/config/urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/config/urls.py b/backend/config/urls.py index e6791788..69add938 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -41,5 +41,5 @@ path('example', views.example, name='example'), path('example/', views.example_id, name='example_id'), path('documents', views.documents, name='documents'), - path('document/', views.single_document, name='document'), + path('document/', views.single_document, name='document') ] From 96ea5651b8ec0cd343b9dc777ecc990c9171c725 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Wed, 14 Jul 2021 16:41:02 -0400 Subject: [PATCH 14/17] update the way newAttributes state is set --- frontend/components/Documents.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/components/Documents.js b/frontend/components/Documents.js index 72956863..4a86f9da 100644 --- a/frontend/components/Documents.js +++ b/frontend/components/Documents.js @@ -59,10 +59,11 @@ const Documents = () => { const handleAttributeInputChange = (event, index) => { const {name, value} = event.target; - console.log(name, value); - const attributesList = [...newAttributes]; - attributesList[index][name] = value; - setNewAttributes(attributesList); + setNewAttributes(prevAttributes => { + return prevAttributes.map((attribute, i) => { + return i === index ? {...attribute, [name]:value} : attribute; + }); + }); }; const handleAddAttribute = () => { From a32d70d57f0f56ecba88b52c9343e220bb2b76ca Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Wed, 14 Jul 2021 22:09:37 -0400 Subject: [PATCH 15/17] update the way attributes are removed from the state --- frontend/components/Documents.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/components/Documents.js b/frontend/components/Documents.js index 4a86f9da..8740f38f 100644 --- a/frontend/components/Documents.js +++ b/frontend/components/Documents.js @@ -71,9 +71,9 @@ const Documents = () => { }; const handleRemoveAttribute = (index) => { - const attributesList = [...newAttributes]; - attributesList.splice(index, 1); - setNewAttributes(attributesList); + setNewAttributes(previousAttributes => ( + previousAttributes.filter((attribute, idx) => idx !== index) + )); }; const handleSubmit = (event) => { From dc62d8d4e0b9716f0c8d5c7918a56322b5eda0e2 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 19 Jul 2021 17:09:22 -0400 Subject: [PATCH 16/17] update delete_corpus to be a DELETE request --- backend/app/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/app/views.py b/backend/app/views.py index 6c837795..4b3c2465 100644 --- a/backend/app/views.py +++ b/backend/app/views.py @@ -206,15 +206,15 @@ def update_corpus_docs(request): return Response(serializer.data) -@api_view(['POST']) +@api_view(['DELETE']) def delete_corpus(request): """ API endpoint for deleting a corpus """ corpus_id = request.data['id'] corpus_obj = Corpus.objects.get(id=corpus_id) - corpus_obj.delete() - return Response() + res = corpus_obj.delete() + return Response(res) @api_view(['GET']) From 667858150daddc3acf012d9ed9d80d8dd8b80e16 Mon Sep 17 00:00:00 2001 From: Peihua Huang Date: Mon, 19 Jul 2021 17:14:17 -0400 Subject: [PATCH 17/17] create __hash__ function that's based on its parent class or else the __eq__ method would make the model have no __hash__ method --- backend/app/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/app/models.py b/backend/app/models.py index e84b8be7..da5bdf96 100644 --- a/backend/app/models.py +++ b/backend/app/models.py @@ -539,3 +539,6 @@ def __eq__(self, other): return False return list(self.documents.values_list('pk', flat=True)) == list(other.documents.values_list('pk', flat=True)) + + def __hash__(self): + return super().__hash__()