Browse Source

Merge branch 'master' into DIV-1165

# Conflicts:
#	edivorce/apps/core/urls.py
#	edivorce/apps/core/views/api.py
pull/170/head
ariannedee 5 years ago
parent
commit
ebbf71da1e
18 changed files with 221 additions and 204 deletions
  1. +21
    -0
      edivorce/apps/core/models.py
  2. +1
    -1
      edivorce/apps/core/static/css/main.css
  3. +3
    -2
      edivorce/apps/core/static/css/main.scss
  4. +6
    -6
      edivorce/apps/core/templates/dashboard/sign_file_options.html
  5. +3
    -3
      edivorce/apps/core/templates/partials/tooltips/affidavit.html
  6. +8
    -0
      edivorce/apps/core/templates/partials/tooltips/affidavit_38.html
  7. +9
    -0
      edivorce/apps/core/templates/partials/tooltips/joint_family_claim.html
  8. +1
    -1
      edivorce/apps/core/templates/partials/tooltips/swear_affirm.html
  9. +0
    -82
      edivorce/apps/core/tests/test_api.py
  10. +15
    -18
      edivorce/apps/core/tests/test_logic.py
  11. +3
    -2
      edivorce/apps/core/urls.py
  12. +2
    -33
      edivorce/apps/core/views/api.py
  13. +1
    -0
      edivorce/apps/core/views/graphql.py
  14. +1
    -6
      vue/README.md
  15. +8
    -7
      vue/src/components/Uploader/Image.vue
  16. +51
    -13
      vue/src/components/Uploader/ItemTile.vue
  17. +6
    -3
      vue/src/components/Uploader/ProgressBar.vue
  18. +82
    -27
      vue/src/components/Uploader/Uploader.vue

+ 21
- 0
edivorce/apps/core/models.py View File

@ -1,3 +1,5 @@
import re
from django.contrib import admin
from django.db import models
from django.db.models import F
@ -176,6 +178,9 @@ class Document(models.Model):
def get_file_url(self):
return reverse('document', kwargs={'filename': self.filename, 'doc_type': self.doc_type, 'party_code': self.party_code, 'size': self.size})
def get_content_type(self):
return Document.content_type_from_filename(self.filename)
def update_sort_orders(self):
q = self.get_documents_in_form().filter(sort_order__gt=self.sort_order)
q.update(sort_order=F('sort_order') - 1)
@ -191,6 +196,22 @@ class Document(models.Model):
def get_documents_in_form(self):
return Document.objects.filter(bceid_user=self.bceid_user, doc_type=self.doc_type, party_code=self.party_code)
@staticmethod
def content_type_from_filename(filename):
content_types = {
"pdf": "application/pdf",
"gif": "image/gif",
"png": "image/png",
"jpe": "image/jpeg",
"jpg": "image/jpeg",
"jpeg": "image/jpeg"
}
extension = re.split(r'[\._]', filename.lower())[-1]
content_type = content_types.get(extension)
if not content_type:
return "application/unknown"
return content_type
class DontLog:
def log_addition(self, *args):


+ 1
- 1
edivorce/apps/core/static/css/main.css
File diff suppressed because it is too large
View File


+ 3
- 2
edivorce/apps/core/static/css/main.scss View File

@ -1549,8 +1549,9 @@ textarea {
h1 {
color: $color-blue-dark;
max-width: 500px;
margin: 0 auto;
max-width: 600px;
margin: 70px auto;
font-size: 48px;
}
h2,
h3 {


+ 6
- 6
edivorce/apps/core/templates/dashboard/sign_file_options.html View File

@ -24,12 +24,12 @@
<div class="list-item-description">
<p>You must both go together to the registry or to a commissioner for taking affidavits to swear/affirm and sign the affidavit(s). This option
costs less (less filing fees) and is typically faster and easier for both of you.</p>
<p>There are strict rules for when you can swear/affirm and sign your Affidavit — Desk Order Divorce (Form 38). You must do it:</p>
<p>There are strict rules for when you can swear/affirm and sign your {% include "partials/tooltips/affidavit_38.html" %}. You must do it:</p>
<ul>
<li>At the same time as you are filing your Notice of Joint Family Claim (You can file the Notice and swear/affirm and sign your affidavit at
<li>At the same time as you are filing your {% include "partials/tooltips/joint_family_claim.html" %} (You can file the Notice and swear/affirm and sign your affidavit at
the registry (or virtually with the registry) at the same time.)</li>
<p style="margin-top: 20px">OR</p>
<li>After you've filed your Notice of Joint Family Claim. (You can file the Notice first, and then come back into this tool or go to the
<li>After you've filed your {% include "partials/tooltips/joint_family_claim.html" %}. (You can file the Notice first, and then come back into this tool or go to the
registry to file your affidavit(s).)
</li>
</ul>
@ -39,13 +39,13 @@
<div class="list-item-description">
<p>You can each swear/affirm and sign your own version of the affidavit (you can go separately to the registry or a commissioner for taking
affidavits to swear/affirm and sign the affidavit(s)).</p>
<p>There are strict rules for when you can swear/affirm and sign your Affidavit — Desk Order Divorce (Form 38). You must:</p>
<p>There are strict rules for when you can swear/affirm and sign your {% include "partials/tooltips/affidavit_38.html" %}. You must:</p>
<ul>
<li>Swear/affirm and sign one person’s affidavit(s) at the same time as you are filing your Notice of Joint Family Claim (You can file the
<li>Swear/affirm and sign one person’s affidavit(s) at the same time as you are filing your {% include "partials/tooltips/joint_family_claim.html" %} (You can file the
Notice and swear your affidavit at the registry (or virtually with the registry) at the same time.) This would allow one party to
swear/affirm and sign their affidavit(s) before the Notice has been filed.</li>
<p style="margin-top: 20px">OR</p>
<li>Swear/affirm and sign both parties’ affidavit(s) after you've filed your Notice of Joint Family Claim. (You can file the Notice first,
<li>Swear/affirm and sign both parties’ affidavit(s) after you've filed your {% include "partials/tooltips/joint_family_claim.html" %}. (You can file the Notice first,
and then come back into this tool or go to the registry to file your affidavit(s).)</li>
</ul>
</div>


+ 3
- 3
edivorce/apps/core/templates/partials/tooltips/affidavit.html View File

@ -1,8 +1,8 @@
<span class="tooltip-link" data-toggle="tooltip" data-placement="right"
data-html="true"
title="
<b>Affidavit - Desk Order Divorce Form (F38)</b>
<b>Affidavit</b>
<br /><br />
This form sets out all the facts of your marriage and separation for the court and gives information about parenting time if you have children.
It requires swearing/affirming and signatures by both you and your spouse in front of a commissioner.">
An affidavit is a written document that contains facts that you must swear under oath (usually on a Bible or other religious book)
or affirm (non-religious promise) to be true.">
affidavit(s)<i class="fa fa-question-circle" aria-hidden="true"></i></span>

+ 8
- 0
edivorce/apps/core/templates/partials/tooltips/affidavit_38.html View File

@ -0,0 +1,8 @@
<span class="tooltip-link" data-toggle="tooltip" data-placement="right"
data-html="true"
title="
<b>Affidavit - Desk Order Divorce Form (F38)</b>
<br /><br />
This form sets out all the facts of your marriage and separation for the court and gives information about parenting time if you have children.
It requires swearing/affirming and signatures by both you and your spouse in front of a commissioner.">
Affidavit — Desk Order Divorce (Form 38)<i class="fa fa-question-circle" aria-hidden="true"></i></span>

+ 9
- 0
edivorce/apps/core/templates/partials/tooltips/joint_family_claim.html View File

@ -0,0 +1,9 @@
<span class="tooltip-link" data-toggle="{% if hover %}tooltip-hover{% else %}tooltip{% endif %}" data-placement="right"
data-html="true"
title="
<b>Notice of Joint Family Claim Form (F1)</b>
<br /><br />
This form starts your divorce proceeding. It gives the court details about you and your spouse, your marriage and separation, and what you're asking the court for.
<br /><br />
- Does not require signatures when filed online.">
Notice of Joint Family Claim<i class="fa fa-question-circle" aria-hidden="true"></i></span>

+ 1
- 1
edivorce/apps/core/templates/partials/tooltips/swear_affirm.html View File

@ -6,7 +6,7 @@
An &quot;affidavit&quot; is a written document that contains facts that you must swear under oath (usually on a Bible or other religious book) or affirm
(non-religious promise) to be true. After you swear or affirm, the affidavit is evidence of the facts it sets out, just as if you took the
stand in a courtroom to provide those facts.
<br/>
<br /><br />
To swear or affirm an affidavit, you must meet with a commissioner for taking oaths. The
commissioner (often a lawyer, notary public or registry clerk) will check your photo id to make sure you are who you say you are, ask you if
you understand the contents of your affidavit, then ask you to swear or affirm that the contents are true. The commissioner will then watch


+ 0
- 82
edivorce/apps/core/tests/test_api.py View File

@ -98,61 +98,6 @@ class APITest(APITestCase):
self.assertIn('Doc type not supported', json_response['doc_type'][0])
self.assertIn('Ensure this value is less than or equal to 2', json_response['party_code'][0])
def test_get_documents_meta_must_be_logged_in(self):
url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code})
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
def test_get_documents_meta_no_documents(self):
url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code})
self.client.force_authenticate(self.user)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 0)
def test_get_documents_meta_some_documents(self):
url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code})
self.client.force_authenticate(self.user)
doc_1 = self._create_document()
doc_2 = self._create_document()
self._create_document(party_code=1)
self._create_document(doc_type='CSA')
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 2)
self._response_data_equals_document(json_response[0], doc_1)
self._response_data_equals_document(json_response[1], doc_2)
def test_get_documents_meta_different_doc_type_party_code(self):
url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code})
self.client.force_authenticate(self.user)
returned_doc = self._create_document()
self._create_document(doc_type='CSA')
self._create_document(party_code=1)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 1)
self._response_data_equals_document(json_response[0], returned_doc)
def test_get_documents_meta_different_user(self):
url = reverse('documents-meta', kwargs={'doc_type': self.default_doc_type, 'party_code': self.default_party_code})
self.client.force_authenticate(self.user)
self._create_document()
self._create_document()
self.client.force_authenticate(self.another_user)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 0)
def test_get_file(self):
document = self._create_document()
self.assertEqual(Document.objects.count(), 1)
@ -247,33 +192,6 @@ class APITest(APITestCase):
'Rotation must be 0, 90, 180, or 270',
status_code=status.HTTP_400_BAD_REQUEST)
def test_missing_redis_document_deletes_all_documents(self):
doc_1 = self._create_document()
self._create_document()
self._create_document()
another_doc = self._create_document(party_code=2)
self.assertEqual(Document.objects.count(), 4)
url = reverse('documents-meta', kwargs={'doc_type': doc_1.doc_type, 'party_code': doc_1.party_code})
self.client.force_authenticate(self.user)
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 3)
# Delete file from Redis
doc_1.file.delete()
response = self.client.get(url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
json_response = json.loads(response.content)
self.assertEqual(len(json_response), 0)
# All files in for that doc_type/party_code/user were deleted
self.assertEqual(Document.objects.count(), 1)
self.assertEqual(Document.objects.first(), another_doc)
def _create_document(self, doc_type=None, party_code=None):
if not doc_type:
doc_type = self.default_doc_type


+ 15
- 18
edivorce/apps/core/tests/test_logic.py View File

@ -5,7 +5,7 @@ from django.test import TestCase
from edivorce.apps.core.models import BceidUser, UserResponse
from edivorce.apps.core.utils.conditional_logic import get_cleaned_response_value, get_num_children_living_with
from edivorce.apps.core.utils.user_response import get_data_for_user
from edivorce.apps.core.views.api import _content_type_from_filename
from edivorce.apps.core.models import Document
class ConditionalLogicTestCase(TestCase):
@ -56,20 +56,17 @@ class ConditionalLogicTestCase(TestCase):
class ViewLogic(TestCase):
def test_content_type_from_filename(self):
self.assertEqual(_content_type_from_filename('test_file1.pdf'), 'application/pdf')
self.assertEqual(_content_type_from_filename('redis_key_test_file1_pdf'), 'application/pdf')
self.assertEqual(_content_type_from_filename('test_file2.png'), 'image/png')
self.assertEqual(_content_type_from_filename('redis_key_test_file2_png'), 'image/png')
self.assertEqual(_content_type_from_filename('Test File 3.GIF'), 'image/gif')
self.assertEqual(_content_type_from_filename('redis_key_test_file_3_GIF'), 'image/gif')
self.assertEqual(_content_type_from_filename('Test_File--4.JPEG'), 'image/jpeg')
self.assertEqual(_content_type_from_filename('redis_key_test_file_4_jpeg'), 'image/jpeg')
self.assertEqual(_content_type_from_filename('TestFile5.jpe'), 'image/jpeg')
self.assertEqual(_content_type_from_filename('redis_key_test_file_5_jpe'), 'image/jpeg')
self.assertEqual(_content_type_from_filename('testFile6.jpeg'), 'image/jpeg')
self.assertEqual(_content_type_from_filename('redis_key_testfile_6_jpeg'), 'image/jpeg')
with self.assertRaises(TypeError):
_content_type_from_filename('test_file7.HEIC')
with self.assertRaises(TypeError):
_content_type_from_filename('redis_key_testfile_7_svg')
self.assertEqual(Document.content_type_from_filename('test_file1.pdf'), 'application/pdf')
self.assertEqual(Document.content_type_from_filename('redis_key_test_file1_pdf'), 'application/pdf')
self.assertEqual(Document.content_type_from_filename('test_file2.png'), 'image/png')
self.assertEqual(Document.content_type_from_filename('redis_key_test_file2_png'), 'image/png')
self.assertEqual(Document.content_type_from_filename('Test File 3.GIF'), 'image/gif')
self.assertEqual(Document.content_type_from_filename('redis_key_test_file_3_GIF'), 'image/gif')
self.assertEqual(Document.content_type_from_filename('Test_File--4.JPEG'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('redis_key_test_file_4_jpeg'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('TestFile5.jpe'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('redis_key_test_file_5_jpe'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('testFile6.jpeg'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('redis_key_testfile_6_jpeg'), 'image/jpeg')
self.assertEqual(Document.content_type_from_filename('test_file7.HEIC'), 'application/unknown')
self.assertEqual(Document.content_type_from_filename('redis_key_testfile_7_svgg'), 'application/unknown')

+ 3
- 2
edivorce/apps/core/urls.py View File

@ -7,10 +7,11 @@ urlpatterns = [
# url(r'^guide$', styleguide.guide),
url(r'^api/response$', api.UserResponseHandler.as_view()),
url(r'^api/documents/$', api.DocumentCreateView.as_view(), name='documents'),
path('api/documents/<doc_type>/<int:party_code>/', api.DocumentMetaDataView.as_view(), name='documents-meta'),
path('api/documents/<doc_type>/<int:party_code>/<int:size>/<filename>', api.DocumentView.as_view(), name='document'),
path('api/documents/<file_key>/', api.get_document_file_by_key, name='file_by_key'),
# we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image
path('api/documents/<doc_type>/<int:party_code>/<filename>x/<int:size>/', api.DocumentView.as_view(), name='document'),
# url(r'^login/headers$', system.headers),
url(r'^login$', main.login, name="login"),


+ 2
- 33
edivorce/apps/core/views/api.py View File

@ -59,21 +59,6 @@ class DocumentCreateView(CreateAPIView):
queryset = Document.objects.all()
class DocumentMetaDataView(ListAPIView):
serializer_class = DocumentMetadataSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
doc_type = self.kwargs['doc_type']
party_code = self.kwargs['party_code']
q = Document.objects.filter(doc_type=doc_type, party_code=party_code, bceid_user=self.request.user).order_by('sort_order')
for doc in q:
if not doc.file_exists():
q.delete()
return Document.objects.none()
return q
class DocumentView(RetrieveUpdateDestroyAPIView):
serializer_class = DocumentMetadataSerializer
permission_classes = [permissions.IsAuthenticated]
@ -91,7 +76,7 @@ class DocumentView(RetrieveUpdateDestroyAPIView):
def retrieve(self, request, *args, **kwargs):
""" Return the file instead of meta data """
document = self.get_object()
content_type = _content_type_from_filename(document.filename)
content_type = Document.content_type_from_filename(document.filename)
# If file doesn't exist anymore, delete it
try:
@ -106,21 +91,5 @@ def get_document_file_by_key(request, file_key):
file = Document.get_file(file_key)
if not file:
return HttpResponseNotFound()
content_type = _content_type_from_filename(file.name)
content_type = Document.content_type_from_filename(file.name)
return HttpResponse(file, content_type=content_type)
def _content_type_from_filename(filename):
content_types = {
"pdf": "application/pdf",
"gif": "image/gif",
"png": "image/png",
"jpe": "image/jpeg",
"jpg": "image/jpeg",
"jpeg": "image/jpeg"
}
extension = re.split(r'[\._]', filename.lower())[-1]
content_type = content_types.get(extension)
if not content_type:
raise TypeError(f'Filetype "{extension}" not supported')
return content_type

+ 1
- 0
edivorce/apps/core/views/graphql.py View File

@ -16,6 +16,7 @@ class PrivateGraphQLView(GraphQLView):
class DocumentType(graphene_django.DjangoObjectType):
file_url = graphene.String(source='get_file_url')
content_type = graphene.String(source='get_content_type')
class Meta:
model = Document


+ 1
- 6
vue/README.md View File

@ -5,12 +5,7 @@
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
### Compile and minify
```
npm run build
```


+ 8
- 7
vue/src/components/Uploader/Image.vue View File

@ -92,11 +92,12 @@ export default {
i.fa-file-pdf-o, i.fa-frown-o {
display: block;
font-size: 105px;
margin-left: 32px;
margin-top: 15px;
position: absolute;
top: 0;
font-size: 48px;
margin-left: 60px;
}
i.fa-file-pdf-o {
color: #D5D5D5;
}
i.fa-frown-o {
@ -112,7 +113,7 @@ export default {
}
&.valid:hover {
background-color: #6484d3;
background-color: #365EBE;
cursor: pointer;
button.btn-remove {
@ -129,7 +130,7 @@ export default {
}
&:hover img {
opacity: 0.3;
opacity: 0.12;
}
}


+ 51
- 13
vue/src/components/Uploader/ItemTile.vue View File

@ -1,11 +1,16 @@
<template>
<div class="item-tile" v-if="file.progress === '100.00' || file.error">
<div :class="['item-tile', file.error ? 'error': '']" v-if="file.progress === '100.00' || file.error">
<uploaded-image :file="file" :image-style="imageStyle" @imageclick="showPreview" @removeclick="$emit('remove')" />
<div class="bottom-wrapper">
<div class="item-text">
{{file.name}} <span class="no-wrap">({{ Math.round(file.size/1024/1024 * 100) / 100 }} MB)</span>
<div class="filename-text">
{{file.name}}
</div>
<div class="size-text">
({{ Math.round(file.size/1024/1024 * 100) / 100 }} MB)
</div>
</div>
<div class="button-wrapper">
<div class="button-wrapper" v-if="file.error || file.type !== 'application/pdf'">
<div v-if="!file.active && file.success && !isPdf">
<button type="button" @click.prevent="$emit('moveup')" :disabled="index === 0" aria-label="Move down one position">
<i class="fa fa-chevron-circle-left"></i>
@ -68,35 +73,62 @@ export default {
.item-tile {
margin-bottom: 5px;
position: relative;
border: none !important;
.item-text {
text-align: center;
min-height: 75px;
max-height: 75px;
overflow: hidden;
padding: 5px;
line-height: 1.05;
font-size: 0.95em;
.no-wrap {
white-space: nowrap;
padding: 7px 10px;
font-size: 16px;
line-height: 24px;
min-height: 87px;
.filename-text {
min-height: 25px;
max-height: 50px;
overflow: hidden;
overflow-wrap: anywhere;;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.size-text {
min-height: 25px;
max-height: 25px;
}
}
.button-wrapper {
margin-top: -4px;
text-align: center;
min-height: 32px;
}
.bottom-wrapper {
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
border: 1px solid silver;
border-top: none;
background-color: #F2F2F2;
margin-bottom: 10px;
.alert-danger {
background-color: inherit;
border: none;
margin-bottom: 0;
padding: 0;
padding: 2px 0 0 0;
font-weight: 700;
font-size: 16px;
line-height: 24px;
}
}
&.error {
.bottom-wrapper {
background-color: #F7D4D5;
border: 1px solid #D8292F;
border-top: none;
}
}
}
@ -137,5 +169,11 @@ export default {
margin-right: 32px;
}
}
&.error {
button.btn-remove i.fa {
color: #D8292F;
}
}
}
</style>

+ 6
- 3
vue/src/components/Uploader/ProgressBar.vue View File

@ -3,7 +3,7 @@
<div class="item-tile" v-if="file.progress !== '0.00'">
<div class="status-wrap">
<div>
Uploading... {{ file.progress}}%
Uploading...<br>{{ file.progress}}%
</div>
<div class="progress">
<div :style="'width:' + file.progress + '%'">
@ -14,7 +14,7 @@
<div class="item-tile" v-else>
<div class="status-wrap">
<div>
Waiting...
Waiting...<br><br>
</div>
<div class="progress"></div>
</div>
@ -40,14 +40,17 @@ export default {
flex-direction: column;
justify-content: center;
text-align: center;
font-size: 16px;
.progress {
width: calc(100% - 1.5px);
background-color: #F2F2F3;
height: 22px;
position: relative;
bottom: -59.5px;
bottom: -54px;
left: 1px;
border-top-left-radius: 0;
border-top-right-radius: 0;
> div {
background-color: #365EBE;


+ 82
- 27
vue/src/components/Uploader/Uploader.vue View File

@ -57,7 +57,7 @@
@rotateleft="rotateLeft(index)"
@rotateright="rotateRight(index)"/>
</div>
<div class="card upload-button" v-if="!tooBig">
<div class="upload-button" v-if="!tooBig">
<div class="upload-button-wrapper">
<i class="fa fa-plus-circle"></i>
</div>
@ -163,8 +163,6 @@ export default {
// upload is complete
if (newFile && oldFile && !newFile.active && oldFile.active) {
this.saveMetaData();
if (newFile.xhr) {
// Error Handling
const statusCode = newFile.xhr.status;
@ -173,6 +171,8 @@ export default {
const message = JSON.parse(newFile.xhr.responseText)[0];
this.showError(message);
this.$refs.upload.remove(newFile);
} else if (statusCode === 403) {
this.showError('Error: Your user session has expired. Please log in again.');
} else if (statusCode !== 200 && statusCode !== 201 ) {
// 500 server error: show the status text and a generic message
this.showError('Error: ' + newFile.xhr.statusText + '. Please try the upload again. If this doesn\'t work, try again later.');
@ -241,15 +241,19 @@ export default {
}
// Add extra data to to the file object
newFile.objectURL = ''
newFile.objectURL = '';
newFile.width = 0;
newFile.height = 0;
newFile.rotation = 0;
let URL = window.URL || window.webkitURL
if (URL && URL.createObjectURL) {
newFile.objectURL = URL.createObjectURL(newFile.file)
newFile.rotation = 0;
const img = new Image();
const self = this;
img.onload = function() {
newFile.width = this.width;
newFile.height = this.height;
newFile.width = this.width || 0;
newFile.height = this.height || 0;
self.isDirty = true;
}
img.src = newFile.objectURL;
}
@ -258,14 +262,23 @@ export default {
remove(file) {
const urlbase = `${this.$parent.proxyRootPath}api/documents`;
const encFilename = encodeURIComponent(file.name);
const url = `${urlbase}/${this.docType}/${this.party}/${file.size}/${encFilename}`;
axios.delete(url)
.then(response => {
this.$refs.upload.remove(file)
})
.catch((error) => {
this.showError('Error deleting document from the server: ' + file.name);
});
if (!file.error) {
// we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image
const url = `${urlbase}/${this.docType}/${this.party}/${encFilename}x/${file.size}/`;
axios.delete(url)
.then(response => {
const pos = this.files.findIndex(f => f.docType === file.docType && f.size === file.size);
if (pos > -1) {
this.files.splice(pos, 1);
}
})
.catch((error) => {
this.showError('Error deleting document from the server: ' + file.name);
this.$refs.upload.remove(file);
});
} else {
this.$refs.upload.remove(file);
}
},
moveUp(old_index) {
if (old_index >= 1 && this.files.length > 1) {
@ -314,18 +327,25 @@ export default {
files: allFiles
};
const graphQLData = graphQLStringify(data,{singleQuotes: false, inlineCharacterLimit: 99999});
console.log('Call API', graphQLData);
const url = `${this.$parent.proxyRootPath}api/graphql/`;
axios.post(url, {
query: `
mutation updateMetadata {
updateMetadata(input:${graphQLData}){
documents{filename size width height rotation}
documents{filename size width height rotation contentType}
}
}
`})
.then(response => {
console.log('response', response);
// check for errors in the graphQL response
if (response.data.errors && response.data.errors.length) {
response.data.errors.forEach((error) => {
console.log('error', error.message || error);
// if there was an error it's probably because the upload isn't finished yet
// mark the metadata as dirty so it will save metadata again
this.isDirty = true;
})
}
})
.catch((error) => {
this.showError('Error saving metadata');
@ -334,6 +354,39 @@ export default {
}
},
created() {
// get saved state from the server
const url = `${this.$parent.proxyRootPath}api/graphql/`;
axios.post(url, {
query: `
query getMetadata {
documents(docType:"${this.docType}",partyCode:${this.party}) {
filename size width height rotation contentType
}
}
`,
variables: null})
.then(response => {
response.data.data.documents.forEach((doc) => {
this.files.push({
name: doc.filename,
size: doc.size,
width: doc.width,
height: doc.height,
rotation: doc.rotation,
type: doc.contentType,
error: false,
success: true,
progress: '100.00',
// we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image
objectURL: `${this.$parent.proxyRootPath}api/documents/${this.docType}/${this.party}/${doc.filename}x/${doc.size}/`
});
});
})
.catch((error) => {
this.showError('Error getting metadata');
console.log('error', error);
});
// call the API to update the metadata every second, but only if
// the data has changed (throttling requests because rotating and
// re-ordering images can cause a lot of traffic and possibly
@ -368,10 +421,11 @@ export default {
text-align: left;
border: 2px #365EBE dashed;
border-radius: 6px;
padding: 18px;
padding: 18px 32px 0 18px;
margin-bottom: 5px;
&.dragging {
background-color: #F2E3F2;
background-color: #D7DFF2;
}
.cards {
@ -385,14 +439,14 @@ export default {
margin-bottom: 10px;
width: 160px;
margin-right: 18px;
&.upload-button {
display: flex;
flex-direction: column;
justify-content: center;
}
}
.upload-button {
position: absolute;
right: 16px;
top: 17px;
}
.fa-plus-circle {
font-size: 3rem;
margin-bottom: 8px;
@ -401,6 +455,7 @@ export default {
.placeholder {
text-align: center;
margin-bottom: 18px;
}
.error-top {
@ -408,7 +463,7 @@ export default {
}
.error-bottom {
margin-bottom: -10px;
margin-bottom: 8px;
}
}


Loading…
Cancel
Save