diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html
index a29e146bf..cfc2e655d 100644
--- a/src-ui/src/app/components/document-list/document-list.component.html
+++ b/src-ui/src/app/components/document-list/document-list.component.html
@@ -152,7 +152,7 @@
{{d.title | documentTitle}}
-
+
|
diff --git a/src-ui/src/app/components/manage/settings/settings.component.html b/src-ui/src/app/components/manage/settings/settings.component.html
index 688100100..367b4ea20 100644
--- a/src-ui/src/app/components/manage/settings/settings.component.html
+++ b/src-ui/src/app/components/manage/settings/settings.component.html
@@ -19,7 +19,7 @@
You need to reload the page after applying a new language.
@@ -34,7 +34,7 @@
diff --git a/src-ui/src/app/components/manage/settings/settings.component.ts b/src-ui/src/app/components/manage/settings/settings.component.ts
index 5089c880f..f9a84e53b 100644
--- a/src-ui/src/app/components/manage/settings/settings.component.ts
+++ b/src-ui/src/app/components/manage/settings/settings.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';
+import { Component, Inject, LOCALE_ID, OnInit, Renderer2 } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
@@ -44,7 +44,8 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
public savedViewService: SavedViewService,
private documentListViewService: DocumentListViewService,
private toastService: ToastService,
- private settings: SettingsService
+ private settings: SettingsService,
+ @Inject(LOCALE_ID) public currentLocale: string
) { }
ngOnInit() {
diff --git a/src-ui/src/app/services/settings.service.ts b/src-ui/src/app/services/settings.service.ts
index d2a190c1f..041fb51ca 100644
--- a/src-ui/src/app/services/settings.service.ts
+++ b/src-ui/src/app/services/settings.service.ts
@@ -71,7 +71,7 @@ export class SettingsService {
getLanguageOptions(): LanguageOption[] {
return [
- {code: "en-us", name: $localize`English`, englishName: "English"},
+ {code: "en-US", name: $localize`English (US)`, englishName: "English (US)"},
{code: "de", name: $localize`German`, englishName: "German"},
{code: "nl", name: $localize`Dutch`, englishName: "Dutch"},
{code: "fr", name: $localize`French`, englishName: "French"}
diff --git a/src-ui/src/locale/messages.de.xlf b/src-ui/src/locale/messages.de.xlf
index 80cfefab9..a898e4630 100644
--- a/src-ui/src/locale/messages.de.xlf
+++ b/src-ui/src/locale/messages.de.xlf
@@ -449,12 +449,20 @@
2
+
+ Filter by:
+ Filtern nach:
+
+ src/app/components/manage/tag-list/tag-list.component.html
+ 8
+
+
Name
Name
src/app/components/manage/tag-list/tag-list.component.html
- 13
+ 9
@@ -462,7 +470,7 @@
Farbe
src/app/components/manage/tag-list/tag-list.component.html
- 14
+ 20
@@ -470,7 +478,7 @@
Zuweisung
src/app/components/manage/tag-list/tag-list.component.html
- 15
+ 21
@@ -478,7 +486,7 @@
Anzahl Dokumente
src/app/components/manage/tag-list/tag-list.component.html
- 16
+ 22
@@ -486,7 +494,7 @@
Aktionen
src/app/components/manage/tag-list/tag-list.component.html
- 17
+ 23
@@ -494,7 +502,7 @@
Dokumente
src/app/components/manage/tag-list/tag-list.component.html
- 32
+ 38
@@ -502,7 +510,7 @@
Bearbeiten
src/app/components/manage/tag-list/tag-list.component.html
- 37
+ 43
@@ -542,7 +550,7 @@
Gespeicherte Ansicht "" gelöscht.
src/app/components/manage/settings/settings.component.ts
- 62
+ 63
@@ -550,7 +558,7 @@
Einstellungen erfolgreich gespeichert.
src/app/components/manage/settings/settings.component.ts
- 78
+ 79
@@ -558,7 +566,7 @@
Benutze Systemsprache
src/app/components/manage/settings/settings.component.ts
- 82
+ 83
@@ -566,7 +574,7 @@
Benutze Datumsformat der Anzeigesprache
src/app/components/manage/settings/settings.component.ts
- 86
+ 87
@@ -574,7 +582,7 @@
Fehler beim Speichern der Einstellungen auf dem Server:
src/app/components/manage/settings/settings.component.ts
- 102
+ 103
@@ -814,7 +822,7 @@
Letzter Kontakt
src/app/components/manage/correspondent-list/correspondent-list.component.html
- 15
+ 22
@@ -1114,14 +1122,6 @@
46
-
- Filter by:
- Filtern nach:
-
- src/app/components/document-list/filter-editor/filter-editor.component.html
- 4
-
-
Filter tags
Tags filtern
@@ -1670,9 +1670,9 @@
12
-
- English
- Englisch
+
+ English (US)
+ Englisch (US)
src/app/services/settings.service.ts
74
@@ -1907,7 +1907,7 @@
Automatisch
src/app/components/manage/generic-list/generic-list.component.ts
- 33
+ 39
@@ -1915,7 +1915,7 @@
Möchten Sie dieses Element wirklich löschen?
src/app/components/manage/generic-list/generic-list.component.ts
- 76
+ 97
@@ -1923,7 +1923,7 @@
Assoziierte Dokumente werden nicht gelöscht.
src/app/components/manage/generic-list/generic-list.component.ts
- 83
+ 104
@@ -1931,7 +1931,7 @@
Löschen
src/app/components/manage/generic-list/generic-list.component.ts
- 85
+ 106
@@ -1939,7 +1939,7 @@
Fehler beim Löschen des Elements:
src/app/components/manage/generic-list/generic-list.component.ts
- 93
+ 114
diff --git a/src-ui/src/locale/messages.fr.xlf b/src-ui/src/locale/messages.fr.xlf
index ee97f7ce0..4f09eab72 100644
--- a/src-ui/src/locale/messages.fr.xlf
+++ b/src-ui/src/locale/messages.fr.xlf
@@ -449,12 +449,20 @@
2
+
+ Filter by:
+ Filtrer par :
+
+ src/app/components/manage/tag-list/tag-list.component.html
+ 8
+
+
Name
Nom
src/app/components/manage/tag-list/tag-list.component.html
- 13
+ 9
@@ -462,7 +470,7 @@
Couleur
src/app/components/manage/tag-list/tag-list.component.html
- 14
+ 20
@@ -470,7 +478,7 @@
Rapprochement
src/app/components/manage/tag-list/tag-list.component.html
- 15
+ 21
@@ -478,7 +486,7 @@
Nombre de documents
src/app/components/manage/tag-list/tag-list.component.html
- 16
+ 22
@@ -486,7 +494,7 @@
Actions
src/app/components/manage/tag-list/tag-list.component.html
- 17
+ 23
@@ -494,7 +502,7 @@
Documents
src/app/components/manage/tag-list/tag-list.component.html
- 32
+ 38
@@ -502,7 +510,7 @@
Éditer
src/app/components/manage/tag-list/tag-list.component.html
- 37
+ 43
@@ -542,7 +550,7 @@
Vue "" supprimée.
src/app/components/manage/settings/settings.component.ts
- 62
+ 63
@@ -550,7 +558,7 @@
Paramètres enregistrés avec succès.
src/app/components/manage/settings/settings.component.ts
- 78
+ 79
@@ -558,7 +566,7 @@
Utiliser la langue du système
src/app/components/manage/settings/settings.component.ts
- 82
+ 83
@@ -566,7 +574,7 @@
Utiliser le format de date de la langue d'affichage
src/app/components/manage/settings/settings.component.ts
- 86
+ 87
@@ -574,7 +582,7 @@
Une erreur s'est produite lors de l'enregistrement des paramètres sur le serveur :
src/app/components/manage/settings/settings.component.ts
- 102
+ 103
@@ -814,7 +822,7 @@
Dernière correspondance
src/app/components/manage/correspondent-list/correspondent-list.component.html
- 15
+ 22
@@ -1114,14 +1122,6 @@
46
-
- Filter by:
- Filtrer par :
-
- src/app/components/document-list/filter-editor/filter-editor.component.html
- 4
-
-
Filter tags
Filtrer les étiquettes
@@ -1670,9 +1670,9 @@
12
-
- English
- Anglais
+
+ English (US)
+ Anglais (US)
src/app/services/settings.service.ts
74
@@ -1907,7 +1907,7 @@
Automatique
src/app/components/manage/generic-list/generic-list.component.ts
- 33
+ 39
@@ -1915,7 +1915,7 @@
Voulez-vous vraiment supprimer cet élément ?
src/app/components/manage/generic-list/generic-list.component.ts
- 76
+ 97
@@ -1923,7 +1923,7 @@
Les documents associés ne seront pas supprimés.
src/app/components/manage/generic-list/generic-list.component.ts
- 83
+ 104
@@ -1931,7 +1931,7 @@
Supprimer
src/app/components/manage/generic-list/generic-list.component.ts
- 85
+ 106
@@ -1939,7 +1939,7 @@
Une erreur s'est produite lors de la suppression de l'élément :
src/app/components/manage/generic-list/generic-list.component.ts
- 93
+ 114
diff --git a/src-ui/src/locale/messages.nl_NL.xlf b/src-ui/src/locale/messages.nl_NL.xlf
index 39545c0e2..3753bc92c 100644
--- a/src-ui/src/locale/messages.nl_NL.xlf
+++ b/src-ui/src/locale/messages.nl_NL.xlf
@@ -449,12 +449,20 @@
2
+
+ Filter by:
+ Filter op:
+
+ src/app/components/manage/tag-list/tag-list.component.html
+ 8
+
+
Name
Naam
src/app/components/manage/tag-list/tag-list.component.html
- 13
+ 9
@@ -462,7 +470,7 @@
Kleur
src/app/components/manage/tag-list/tag-list.component.html
- 14
+ 20
@@ -470,7 +478,7 @@
Overeenkomend
src/app/components/manage/tag-list/tag-list.component.html
- 15
+ 21
@@ -478,7 +486,7 @@
Aantal documenten
src/app/components/manage/tag-list/tag-list.component.html
- 16
+ 22
@@ -486,7 +494,7 @@
Acties
src/app/components/manage/tag-list/tag-list.component.html
- 17
+ 23
@@ -494,7 +502,7 @@
Documenten
src/app/components/manage/tag-list/tag-list.component.html
- 32
+ 38
@@ -502,7 +510,7 @@
Bewerk
src/app/components/manage/tag-list/tag-list.component.html
- 37
+ 43
@@ -542,7 +550,7 @@
Opgeslagen view "" verwijderd.
src/app/components/manage/settings/settings.component.ts
- 62
+ 63
@@ -550,7 +558,7 @@
Instellingen succesvol opgeslagen.
src/app/components/manage/settings/settings.component.ts
- 78
+ 79
@@ -558,7 +566,7 @@
Gebruik de systeemtaal
src/app/components/manage/settings/settings.component.ts
- 82
+ 83
@@ -566,7 +574,7 @@
Datumopmaak van weergavetaal gebruiken
src/app/components/manage/settings/settings.component.ts
- 86
+ 87
@@ -574,7 +582,7 @@
Fout bij het opslaan van de instellingen:
src/app/components/manage/settings/settings.component.ts
- 102
+ 103
@@ -814,7 +822,7 @@
Laatste correspondentie
src/app/components/manage/correspondent-list/correspondent-list.component.html
- 15
+ 22
@@ -1114,14 +1122,6 @@
46
-
- Filter by:
- Filter op:
-
- src/app/components/document-list/filter-editor/filter-editor.component.html
- 4
-
-
Filter tags
Etiketten filteren
@@ -1670,9 +1670,9 @@
12
-
- English
- Engels
+
+ English (US)
+ Engels (US)
src/app/services/settings.service.ts
74
@@ -1907,7 +1907,7 @@
Automatisch
src/app/components/manage/generic-list/generic-list.component.ts
- 33
+ 39
@@ -1915,7 +1915,7 @@
Wil je dit element echt verwijderen?
src/app/components/manage/generic-list/generic-list.component.ts
- 76
+ 97
@@ -1923,7 +1923,7 @@
Geassocieerde documenten zullen niet verwijderd worden.
src/app/components/manage/generic-list/generic-list.component.ts
- 83
+ 104
@@ -1931,7 +1931,7 @@
Verwijderen
src/app/components/manage/generic-list/generic-list.component.ts
- 85
+ 106
@@ -1939,7 +1939,7 @@
Fout bij het verwijderen van het element:
src/app/components/manage/generic-list/generic-list.component.ts
- 93
+ 114
diff --git a/src/documents/management/commands/document_consumer.py b/src/documents/management/commands/document_consumer.py
index 595bd39cd..9ba1b1a87 100644
--- a/src/documents/management/commands/document_consumer.py
+++ b/src/documents/management/commands/document_consumer.py
@@ -70,31 +70,6 @@ def _consume(filepath):
"Error while consuming document: {}".format(e))
-def _test_inotify(directory):
- if not INotify:
- return False
-
- test_file = os.path.join(directory, "__inotify_test_file__")
- inotify = INotify()
- descriptor = None
- try:
- inotify_flags = flags.CLOSE_WRITE | flags.MOVED_TO
- descriptor = inotify.add_watch(directory, inotify_flags)
- Path(test_file).touch()
- events = inotify.read(timeout=1000)
- return len(events) == 1
- except Exception as e:
- logger.warning(
- f"Error while checking inotify availability: {str(e)}")
- return False
- finally:
- if descriptor:
- inotify.rm_watch(descriptor)
- inotify.close()
- if os.path.isfile(test_file):
- os.unlink(test_file)
-
-
def _consume_wait_unmodified(file, num_tries=20, wait_time=1):
mtime = -1
current_try = 0
@@ -178,25 +153,17 @@ class Command(BaseCommand):
if options["oneshot"]:
return
- if settings.CONSUMER_POLLING == 0:
- if _test_inotify(directory):
- self.handle_inotify(directory, recursive)
- else:
- logger.warning(
- f"Inotify notifications are not available on {directory}, "
- f"falling back to polling every 10 seconds")
- self.handle_polling(
- directory, recursive, 10)
+ if settings.CONSUMER_POLLING == 0 and INotify:
+ self.handle_inotify(directory, recursive)
else:
- self.handle_polling(
- directory, recursive, settings.CONSUMER_POLLING)
+ self.handle_polling(directory, recursive)
logger.debug("Consumer exiting.")
- def handle_polling(self, directory, recursive, timeout):
+ def handle_polling(self, directory, recursive):
logging.getLogger(__name__).info(
f"Polling directory for changes: {directory}")
- self.observer = PollingObserver(timeout=timeout)
+ self.observer = PollingObserver(timeout=settings.CONSUMER_POLLING)
self.observer.schedule(Handler(), directory, recursive=recursive)
self.observer.start()
try:
diff --git a/src/documents/models.py b/src/documents/models.py
index 928b8aa4d..86878dd7e 100755
--- a/src/documents/models.py
+++ b/src/documents/models.py
@@ -63,12 +63,6 @@ class MatchingModel(models.Model):
def __str__(self):
return self.name
- def save(self, *args, **kwargs):
-
- self.match = self.match.lower()
-
- models.Model.save(self, *args, **kwargs)
-
class Correspondent(MatchingModel):
diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py
index 5f81b83b6..2b332a873 100644
--- a/src/documents/tests/test_api.py
+++ b/src/documents/tests/test_api.py
@@ -228,6 +228,12 @@ class TestDocumentApi(DirectoriesMixin, APITestCase):
self.assertEqual(len(results), 2)
self.assertCountEqual([results[0]['id'], results[1]['id']], [doc1.id, doc3.id])
+ response = self.client.get("/api/documents/?tags__id__in={},{}".format(tag_2.id, tag_3.id))
+ self.assertEqual(response.status_code, 200)
+ results = response.data['results']
+ self.assertEqual(len(results), 2)
+ self.assertCountEqual([results[0]['id'], results[1]['id']], [doc2.id, doc3.id])
+
response = self.client.get("/api/documents/?tags__id__all={},{}".format(tag_2.id, tag_3.id))
self.assertEqual(response.status_code, 200)
results = response.data['results']
@@ -923,6 +929,14 @@ class TestBulkEdit(DirectoriesMixin, APITestCase):
doc2 = Document.objects.get(id=self.doc2.id)
self.assertEqual(doc2.correspondent, self.c1)
+ def test_api_no_correspondent(self):
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "set_correspondent",
+ "parameters": {}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
def test_api_invalid_document_type(self):
self.assertEqual(self.doc2.document_type, self.dt1)
response = self.client.post("/api/documents/bulk_edit/", json.dumps({
@@ -935,6 +949,14 @@ class TestBulkEdit(DirectoriesMixin, APITestCase):
doc2 = Document.objects.get(id=self.doc2.id)
self.assertEqual(doc2.document_type, self.dt1)
+ def test_api_no_document_type(self):
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "set_document_type",
+ "parameters": {}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
def test_api_add_invalid_tag(self):
self.assertEqual(list(self.doc2.tags.all()), [self.t1])
response = self.client.post("/api/documents/bulk_edit/", json.dumps({
@@ -946,6 +968,14 @@ class TestBulkEdit(DirectoriesMixin, APITestCase):
self.assertEqual(list(self.doc2.tags.all()), [self.t1])
+ def test_api_add_tag_no_tag(self):
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "add_tag",
+ "parameters": {}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
def test_api_delete_invalid_tag(self):
self.assertEqual(list(self.doc2.tags.all()), [self.t1])
response = self.client.post("/api/documents/bulk_edit/", json.dumps({
@@ -957,6 +987,14 @@ class TestBulkEdit(DirectoriesMixin, APITestCase):
self.assertEqual(list(self.doc2.tags.all()), [self.t1])
+ def test_api_delete_tag_no_tag(self):
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "remove_tag",
+ "parameters": {}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
def test_api_modify_invalid_tags(self):
self.assertEqual(list(self.doc2.tags.all()), [self.t1])
response = self.client.post("/api/documents/bulk_edit/", json.dumps({
@@ -966,6 +1004,21 @@ class TestBulkEdit(DirectoriesMixin, APITestCase):
}), content_type='application/json')
self.assertEqual(response.status_code, 400)
+ def test_api_modify_tags_no_tags(self):
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "modify_tags",
+ "parameters": {"remove_tags": [1123123]}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
+ response = self.client.post("/api/documents/bulk_edit/", json.dumps({
+ "documents": [self.doc2.id],
+ "method": "modify_tags",
+ "parameters": {'add_tags': [self.t2.id, 1657]}
+ }), content_type='application/json')
+ self.assertEqual(response.status_code, 400)
+
def test_api_selection_data_empty(self):
response = self.client.post("/api/documents/selection_data/", json.dumps({
"documents": []
diff --git a/src/documents/tests/test_management_consumer.py b/src/documents/tests/test_management_consumer.py
index 0680e7f56..b6a61a167 100644
--- a/src/documents/tests/test_management_consumer.py
+++ b/src/documents/tests/test_management_consumer.py
@@ -7,9 +7,8 @@ from unittest import mock
from django.conf import settings
from django.core.management import call_command, CommandError
-from django.test import override_settings, TransactionTestCase, TestCase
+from django.test import override_settings, TransactionTestCase
-from documents.management.commands.document_consumer import _test_inotify
from documents.models import Tag
from documents.consumer import ConsumerError
from documents.management.commands import document_consumer
@@ -261,27 +260,3 @@ class TestConsumerTags(DirectoriesMixin, ConsumerMixin, TransactionTestCase):
@override_settings(CONSUMER_POLLING=1)
def test_consume_file_with_path_tags_polling(self):
self.test_consume_file_with_path_tags()
-
-
-class TestInotify(DirectoriesMixin, TestCase):
-
- def test_inotify(self):
- self.assertTrue(_test_inotify(self.dirs.consumption_dir))
-
- @mock.patch("documents.management.commands.document_consumer.Path.touch")
- def test_inotify_error(self, m):
- m.side_effect = OSError("Permission error")
- self.assertFalse(_test_inotify(self.dirs.consumption_dir))
-
- @mock.patch("documents.management.commands.document_consumer.Command.handle_polling")
- @mock.patch("documents.management.commands.document_consumer.Command.handle_inotify")
- @mock.patch("documents.management.commands.document_consumer._test_inotify")
- def test_polling_fallback(self, test_inotify, handle_inotify, handle_polling):
- test_inotify.return_value = False
-
- cmd = document_consumer.Command()
- cmd.handle(directory=settings.CONSUMPTION_DIR, oneshot=False)
-
- test_inotify.assert_called_once()
- handle_polling.assert_called_once()
- handle_inotify.assert_not_called()
diff --git a/src/documents/tests/test_parsers.py b/src/documents/tests/test_parsers.py
index 805e4beac..392c0504f 100644
--- a/src/documents/tests/test_parsers.py
+++ b/src/documents/tests/test_parsers.py
@@ -120,3 +120,4 @@ class TestParserAvailability(TestCase):
self.assertTrue(is_file_ext_supported('.pdf'))
self.assertFalse(is_file_ext_supported('.hsdfh'))
+ self.assertFalse(is_file_ext_supported(''))
diff --git a/src/documents/views.py b/src/documents/views.py
index eb9078f75..b99bf11c7 100755
--- a/src/documents/views.py
+++ b/src/documents/views.py
@@ -159,6 +159,9 @@ class DocumentViewSet(RetrieveModelMixin,
"added",
"archive_serial_number")
+ def get_queryset(self):
+ return Document.objects.distinct()
+
def get_serializer(self, *args, **kwargs):
fields_param = self.request.query_params.get('fields', None)
if fields_param:
From 96a572b7a681bd9a9bd5c3c323054711e5feb531 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com>
Date: Mon, 25 Jan 2021 23:29:16 -0800
Subject: [PATCH 08/26] Refactor, missed import
---
src-ui/src/app/app-routing.module.ts | 6 +++---
.../app/components/manage/settings/settings.component.ts | 2 +-
src-ui/src/app/guards/dirty-form.guard.ts | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts
index d85026081..f49c5cd71 100644
--- a/src-ui/src/app/app-routing.module.ts
+++ b/src-ui/src/app/app-routing.module.ts
@@ -11,7 +11,7 @@ import { SettingsComponent } from './components/manage/settings/settings.compone
import { TagListComponent } from './components/manage/tag-list/tag-list.component';
import { NotFoundComponent } from './components/not-found/not-found.component';
import { SearchComponent } from './components/search/search.component';
-import { FormDirtyGuard } from './guards/dirty-form.guard';
+import { DirtyFormGuard } from './guards/dirty-form.guard';
const routes: Routes = [
{path: '', redirectTo: 'dashboard', pathMatch: 'full'},
@@ -20,13 +20,13 @@ const routes: Routes = [
{path: 'documents', component: DocumentListComponent },
{path: 'view/:id', component: DocumentListComponent },
{path: 'search', component: SearchComponent },
- {path: 'documents/:id', component: DocumentDetailComponent, canDeactivate: [FormDirtyGuard] },
+ {path: 'documents/:id', component: DocumentDetailComponent, canDeactivate: [DirtyFormGuard] },
{path: 'tags', component: TagListComponent },
{path: 'documenttypes', component: DocumentTypeListComponent },
{path: 'correspondents', component: CorrespondentListComponent },
{path: 'logs', component: LogsComponent },
- {path: 'settings', component: SettingsComponent, canDeactivate: [FormDirtyGuard] },
+ {path: 'settings', component: SettingsComponent, canDeactivate: [DirtyFormGuard] },
]},
{path: '404', component: NotFoundComponent},
diff --git a/src-ui/src/app/components/manage/settings/settings.component.ts b/src-ui/src/app/components/manage/settings/settings.component.ts
index f9a84e53b..aa73969f0 100644
--- a/src-ui/src/app/components/manage/settings/settings.component.ts
+++ b/src-ui/src/app/components/manage/settings/settings.component.ts
@@ -1,4 +1,4 @@
-import { Component, Inject, LOCALE_ID, OnInit, Renderer2 } from '@angular/core';
+import { Component, Inject, LOCALE_ID, OnInit, OnDestroy, Renderer2 } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
diff --git a/src-ui/src/app/guards/dirty-form.guard.ts b/src-ui/src/app/guards/dirty-form.guard.ts
index b0b50ac7f..2b9f1b4a2 100644
--- a/src-ui/src/app/guards/dirty-form.guard.ts
+++ b/src-ui/src/app/guards/dirty-form.guard.ts
@@ -6,7 +6,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component';
@Injectable({ providedIn: 'root' })
-export class FormDirtyGuard extends DirtyCheckGuard {
+export class DirtyFormGuard extends DirtyCheckGuard {
constructor(private modalService: NgbModal) {
super();
}
From d672455ad80fe30c71699ee8d6207cf471fbd904 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com>
Date: Mon, 25 Jan 2021 23:32:02 -0800
Subject: [PATCH 09/26] Cleanup
---
.../common/confirm-dialog/confirm-dialog.component.ts | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts
index 4287b66d0..454c9a3d4 100644
--- a/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts
+++ b/src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts
@@ -9,6 +9,8 @@ import { Subject } from 'rxjs';
})
export class ConfirmDialogComponent implements OnInit {
+ constructor(public activeModal: NgbActiveModal) { }
+
@Output()
public confirmClicked = new EventEmitter()
@@ -35,10 +37,6 @@ export class ConfirmDialogComponent implements OnInit {
subject: Subject
- constructor(public activeModal: NgbActiveModal) {
- this.confirmClicked.asObservable()
- }
-
delayConfirm(seconds: number) {
this.confirmButtonEnabled = false
this.seconds = seconds
@@ -61,8 +59,8 @@ export class ConfirmDialogComponent implements OnInit {
}
confirm() {
+ this.confirmClicked.emit()
this.subject?.next(true)
this.subject?.complete()
- this.confirmClicked.emit()
}
}
From 07faba3983ba2133e9d35e62a1b56ea8843be7d3 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com>
Date: Mon, 25 Jan 2021 23:39:16 -0800
Subject: [PATCH 10/26] Confirm button text
---
src-ui/src/app/guards/dirty-form.guard.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src-ui/src/app/guards/dirty-form.guard.ts b/src-ui/src/app/guards/dirty-form.guard.ts
index 2b9f1b4a2..79cb34d6c 100644
--- a/src-ui/src/app/guards/dirty-form.guard.ts
+++ b/src-ui/src/app/guards/dirty-form.guard.ts
@@ -17,7 +17,7 @@ export class DirtyFormGuard extends DirtyCheckGuard {
modal.componentInstance.messageBold = $localize`You have unsaved changes.`
modal.componentInstance.message = $localize`Are you sure you want to leave?`
modal.componentInstance.btnClass = "btn-warning"
- modal.componentInstance.btnCaption = $localize`Ok`
+ modal.componentInstance.btnCaption = $localize`Leave page`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
modal.close()
From 1576e07011e589fca8010585e131ecb6a046ae28 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+nikonratm@users.noreply.github.com>
Date: Tue, 26 Jan 2021 20:46:28 -0800
Subject: [PATCH 11/26] Dont warn on navigate for documents
---
src-ui/src/app/app-routing.module.ts | 2 +-
.../document-detail.component.html | 2 +-
.../document-detail.component.ts | 20 +++++++++++++++++++
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts
index f49c5cd71..ee75b3312 100644
--- a/src-ui/src/app/app-routing.module.ts
+++ b/src-ui/src/app/app-routing.module.ts
@@ -20,7 +20,7 @@ const routes: Routes = [
{path: 'documents', component: DocumentListComponent },
{path: 'view/:id', component: DocumentListComponent },
{path: 'search', component: SearchComponent },
- {path: 'documents/:id', component: DocumentDetailComponent, canDeactivate: [DirtyFormGuard] },
+ {path: 'documents/:id', component: DocumentDetailComponent },
{path: 'tags', component: TagListComponent },
{path: 'documenttypes', component: DocumentTypeListComponent },
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html
index c0fc4af6d..d5c8c862e 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.html
+++ b/src-ui/src/app/components/document-detail/document-detail.component.html
@@ -38,7 +38,7 @@
More like this
-
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts
index f03270547..4effb6179 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.ts
@@ -75,8 +75,7 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
@ViewChild('nav') nav: NgbNav
@ViewChild('pdfPreview') set pdfPreview(element) {
// this gets called when compontent added or removed from DOM
- if (element && element.nativeElement.offsetParent !== null) { // its visible
-
+ if (element && element.nativeElement.offsetParent !== null && this.nav?.activeId == 4) { // its visible
setTimeout(()=> this.nav?.select(1));
}
}
From 8c853e56e4c376f5db45a84ac0d123643922c742 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Wed, 16 Feb 2022 13:43:25 -0800
Subject: [PATCH 23/26] Reset networkActive & error after switchmap pipes
complete
---
.../components/document-detail/document-detail.component.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts
index 4effb6179..5f6e7f369 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.ts
@@ -222,13 +222,14 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
this.networkActive = true
this.store.next(this.documentForm.value)
this.documentsService.update(this.document).pipe(switchMap(updateResult => {
- this.error = null
return this.documentListViewService.getNext(this.documentId).pipe(map(nextDocId => ({nextDocId, updateResult})))
})).pipe(switchMap(({nextDocId, updateResult}) => {
if (nextDocId) return this.openDocumentService.closeDocument(this.document, true).pipe(map(closeResult => ({updateResult, nextDocId, closeResult})))
}))
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(({updateResult, nextDocId, closeResult}) => {
+ this.error = null
+ this.networkActive = false
if (closeResult) {
this.router.navigate(['documents', nextDocId])
this.titleInput?.focus()
From 9bc48fed73ecda6921b7fa322170fdb2550bbe09 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Wed, 16 Feb 2022 14:34:19 -0800
Subject: [PATCH 24/26] Check for live changes on document detail title
---
.../document-detail.component.html | 2 +-
.../document-detail.component.ts | 17 +++++++++++++++--
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html
index 52710aca2..4acd7a904 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.html
+++ b/src-ui/src/app/components/document-detail/document-detail.component.html
@@ -56,7 +56,7 @@
Details
-
+
= new Subject()
previewUrl: string
downloadUrl: string
downloadOriginalUrl: string
@@ -91,7 +92,19 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
private documentListViewService: DocumentListViewService,
private documentTitlePipe: DocumentTitlePipe,
private toastService: ToastService,
- private settings: SettingsService) { }
+ private settings: SettingsService) {
+ this.titleSubject.pipe(
+ debounceTime(200),
+ distinctUntilChanged(),
+ takeUntil(this.unsubscribeNotifier)
+ ).subscribe(titleValue => {
+ this.documentForm.patchValue({'title': titleValue})
+ })
+ }
+
+ titleKeyUp(event) {
+ this.titleSubject.next(event.target?.value)
+ }
get useNativePdfViewer(): boolean {
return this.settings.get(SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER)
From 66b9a99e7170235e6fc5b0a2833a6f140f5703a5 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Thu, 17 Feb 2022 23:04:38 -0800
Subject: [PATCH 25/26] Correct runtime issue(s) with saveEditNext
---
.../document-detail.component.ts | 36 +++++++++----------
.../app/services/open-documents.service.ts | 4 +--
2 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts
index 8037cf44b..85b221307 100644
--- a/src-ui/src/app/components/document-detail/document-detail.component.ts
+++ b/src-ui/src/app/components/document-detail/document-detail.component.ts
@@ -124,14 +124,18 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
this.route.paramMap.pipe(switchMap(paramMap => {
const documentId = +paramMap.get('id')
- return this.documentsService.get(documentId).pipe(map(doc => ({doc, documentId})))
- })).pipe(switchMap(({doc, documentId}) => {
- this.previewUrl = this.documentsService.getPreviewUrl(documentId)
- this.downloadUrl = this.documentsService.getDownloadUrl(documentId)
- this.downloadOriginalUrl = this.documentsService.getDownloadUrl(documentId, true)
+ return this.documentsService.get(documentId)
+ })).pipe(switchMap((doc) => {
+ this.documentId = doc.id
+ this.previewUrl = this.documentsService.getPreviewUrl(this.documentId)
+ this.downloadUrl = this.documentsService.getDownloadUrl(this.documentId)
+ this.downloadOriginalUrl = this.documentsService.getDownloadUrl(this.documentId, true)
this.suggestions = null
- if (this.openDocumentService.getOpenDocument(documentId)) {
- this.updateComponent(this.openDocumentService.getOpenDocument(documentId))
+ if (this.openDocumentService.getOpenDocument(this.documentId)) {
+ this.updateComponent(this.openDocumentService.getOpenDocument(this.documentId))
+ } else {
+ this.openDocumentService.openDocument(doc)
+ this.updateComponent(doc)
}
// Initialize dirtyCheck
@@ -147,17 +151,11 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
this.isDirty$ = dirtyCheck(this.documentForm, this.store.asObservable())
- return this.isDirty$.pipe(map(dirty => ({doc, documentId, dirty})))
+ return this.isDirty$.pipe(map(dirty => ({doc, dirty})))
}))
.pipe(takeUntil(this.unsubscribeNotifier))
- .subscribe(({doc, documentId, dirty}) => {
- this.documentId = documentId
- this.openDocumentService.setDirty(documentId, dirty)
-
- if (!this.openDocumentService.getOpenDocument(documentId)) {
- this.openDocumentService.openDocument(doc)
- this.updateComponent(doc)
- }
+ .subscribe(({doc, dirty}) => {
+ this.openDocumentService.setDirty(doc.id, dirty)
}, error => {this.router.navigate(['404'])})
}
@@ -237,13 +235,13 @@ export class DocumentDetailComponent implements OnInit, OnDestroy, DirtyComponen
this.documentsService.update(this.document).pipe(switchMap(updateResult => {
return this.documentListViewService.getNext(this.documentId).pipe(map(nextDocId => ({nextDocId, updateResult})))
})).pipe(switchMap(({nextDocId, updateResult}) => {
- if (nextDocId) return this.openDocumentService.closeDocument(this.document, true).pipe(map(closeResult => ({updateResult, nextDocId, closeResult})))
+ if (nextDocId && updateResult) return this.openDocumentService.closeDocument(this.document).pipe(map(closeResult => ({updateResult, nextDocId, closeResult})))
}))
- .pipe(takeUntil(this.unsubscribeNotifier))
+ .pipe(first())
.subscribe(({updateResult, nextDocId, closeResult}) => {
this.error = null
this.networkActive = false
- if (closeResult) {
+ if (closeResult && updateResult && nextDocId) {
this.router.navigate(['documents', nextDocId])
this.titleInput?.focus()
}
diff --git a/src-ui/src/app/services/open-documents.service.ts b/src-ui/src/app/services/open-documents.service.ts
index ad811da86..c44f4cd75 100644
--- a/src-ui/src/app/services/open-documents.service.ts
+++ b/src-ui/src/app/services/open-documents.service.ts
@@ -63,10 +63,10 @@ export class OpenDocumentsService {
else this.dirtyDocuments.delete(documentId)
}
- closeDocument(doc: PaperlessDocument, force: boolean = false): Observable {
+ closeDocument(doc: PaperlessDocument): Observable {
let index = this.openDocuments.findIndex(d => d.id == doc.id)
if (index == -1) return of(true);
- if (force || !this.dirtyDocuments.has(doc.id)) {
+ if (!this.dirtyDocuments.has(doc.id)) {
this.openDocuments.splice(index, 1)
this.save()
return of(true)
From c9baa76afdcca09de60140ac562ee5d29cf379e5 Mon Sep 17 00:00:00 2001
From: Michael Shamoon <4887959+shamoon@users.noreply.github.com>
Date: Thu, 17 Feb 2022 23:05:14 -0800
Subject: [PATCH 26/26] clear 'dirty' documents when closing all
---
src-ui/src/app/services/open-documents.service.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src-ui/src/app/services/open-documents.service.ts b/src-ui/src/app/services/open-documents.service.ts
index c44f4cd75..92802c765 100644
--- a/src-ui/src/app/services/open-documents.service.ts
+++ b/src-ui/src/app/services/open-documents.service.ts
@@ -102,6 +102,7 @@ export class OpenDocumentsService {
modal.componentInstance.buttonsEnabled = false
modal.close()
this.openDocuments.splice(0, this.openDocuments.length)
+ this.dirtyDocuments.clear()
this.save()
})
const subject = new Subject()
@@ -109,6 +110,7 @@ export class OpenDocumentsService {
return subject.asObservable()
} else {
this.openDocuments.splice(0, this.openDocuments.length)
+ this.dirtyDocuments.clear()
this.save()
return of(true)
}
|