From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Mon, 25 Sep 2023 02:24:28 +0000 (-0700) Subject: Enhancement: settings reorganization & improvements, separate admin section (#4251) X-Git-Tag: v2.0.0-beta.1~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f3d6756fba8f219302851ddfcaf8a2b4bc729b2d;p=thirdparty%2Fpaperless-ngx.git Enhancement: settings reorganization & improvements, separate admin section (#4251) * Separate admin / manage sections * Move mail settings to its own component * Move users and groups to its own component * Move default permissions to its own settings tab * Unify list styling, add tour step, refactor components * Only patch saved views that have changed on settings save * Update messages.xlf * Remove unused methods in settings.component.ts * Drop admin section to bottom of sidebar, cleanup outdated, add docs link to dropdown * Better visually unify management list & other list pages --- diff --git a/src-ui/e2e/settings/requests/api-settings.har b/src-ui/e2e/admin/requests/api-settings.har similarity index 100% rename from src-ui/e2e/settings/requests/api-settings.har rename to src-ui/e2e/admin/requests/api-settings.har diff --git a/src-ui/e2e/settings/settings.spec.ts b/src-ui/e2e/admin/settings.spec.ts similarity index 59% rename from src-ui/e2e/settings/settings.spec.ts rename to src-ui/e2e/admin/settings.spec.ts index 1ae9afa063..92c6918d91 100644 --- a/src-ui/e2e/settings/settings.spec.ts +++ b/src-ui/e2e/admin/settings.spec.ts @@ -1,24 +1,6 @@ import { test, expect } from '@playwright/test' -const REQUESTS_HAR = 'e2e/settings/requests/api-settings.har' - -test('should post settings on save', async ({ page }) => { - await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' }) - await page.goto('/settings') - await page.getByLabel('Use system setting').click() - await page.getByRole('button', { name: 'Save' }).scrollIntoViewIfNeeded() - const updatePromise = page.waitForRequest((request) => { - const data = request.postDataJSON() - const isValid = data['settings'] != null - return ( - isValid && - request.method() === 'POST' && - request.url().includes('/api/ui_settings/') - ) - }) - await page.getByRole('button', { name: 'Save' }).click() - await updatePromise -}) +const REQUESTS_HAR = 'e2e/admin/requests/api-settings.har' test('should activate / deactivate save button when settings change', async ({ page, @@ -72,30 +54,3 @@ test('should toggle saved view options when set & saved', async ({ page }) => { await page.getByRole('button', { name: 'Save' }).click() await updatePromise }) - -test('should support tab direct navigation', async ({ page }) => { - await page.routeFromHAR(REQUESTS_HAR, { notFound: 'fallback' }) - await page.goto('/settings/general') - await expect(page.getByRole('tab', { name: 'General' })).toHaveAttribute( - 'aria-selected', - 'true' - ) - await page.goto('/settings/notifications') - await expect( - page.getByRole('tab', { name: 'Notifications' }) - ).toHaveAttribute('aria-selected', 'true') - await page.goto('/settings/savedviews') - await expect(page.getByRole('tab', { name: 'Saved Views' })).toHaveAttribute( - 'aria-selected', - 'true' - ) - await page.goto('/settings/mail') - await expect(page.getByRole('tab', { name: 'Mail' })).toHaveAttribute( - 'aria-selected', - 'true' - ) - await page.goto('/settings/usersgroups') - await expect( - page.getByRole('tab', { name: 'Users & Groups' }) - ).toHaveAttribute('aria-selected', 'true') -}) diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 98bd9af7d9..d1a98668ae 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -371,883 +371,933 @@ 176 - - File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process. + + Manage e-mail accounts and rules for automatically importing documents. src/app/app.component.ts 184 - - Check out the settings for various tweaks to the web app, toggle settings for saved views or setup e-mail checking. + + Consumption templates give you finer control over the document ingestion process. src/app/app.component.ts 192 + + File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process. + + src/app/app.component.ts + 200 + + + + Check out the settings for various tweaks to the web app and toggle settings for saved views. + + src/app/app.component.ts + 208 + + Thank you! 🙏 src/app/app.component.ts - 200 + 216 There are <em>tons</em> more features and info we didn't cover here, but this should get you started. Check out the documentation or visit the project on GitHub to learn more or to report issues. src/app/app.component.ts - 202 + 218 Lastly, on behalf of every contributor to this community-supported project, thank you for using Paperless-ngx! src/app/app.component.ts - 204 + 220 Initiating upload... src/app/app.component.ts - 273 + 289 - - Paperless-ngx + + Logs - src/app/components/app-frame/app-frame.component.html - 11 + src/app/components/admin/logs/logs.component.html + 1 - app title - - - Search documents src/app/components/app-frame/app-frame.component.html - 18 + 201 - - - Logged in as src/app/components/app-frame/app-frame.component.html - 39 + 204 - - Settings + + Loading... - src/app/components/app-frame/app-frame.component.html - 45 + src/app/components/admin/logs/logs.component.html + 11 - src/app/components/app-frame/app-frame.component.html - 181 + src/app/components/admin/logs/logs.component.html + 20 - src/app/components/app-frame/app-frame.component.html - 184 + src/app/components/admin/settings/settings.component.html + 312 - src/app/components/manage/settings/settings.component.html - 1 + src/app/components/admin/tasks/tasks.component.html + 19 - src/app/components/manage/settings/settings.component.html - 268 + src/app/components/admin/tasks/tasks.component.html + 27 - - - Logout - src/app/components/app-frame/app-frame.component.html - 50 + src/app/components/admin/users-groups/users-groups.component.html + 82 - - - Dashboard - src/app/components/app-frame/app-frame.component.html - 69 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 30 - src/app/components/app-frame/app-frame.component.html - 72 + src/app/components/common/permissions-dialog/permissions-dialog.component.html + 18 src/app/components/dashboard/dashboard.component.html - 1 + 10 - - - Documents - src/app/components/app-frame/app-frame.component.html - 76 + src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html + 7 - src/app/components/app-frame/app-frame.component.html - 79 + src/app/components/document-list/document-list.component.html + 95 - src/app/components/document-list/document-list.component.ts - 97 + src/app/components/manage/mail/mail.component.html + 82 src/app/components/manage/management-list/management-list.component.html - 82 + 46 src/app/components/manage/management-list/management-list.component.html - 82 + 46 src/app/components/manage/management-list/management-list.component.html - 82 + 46 src/app/components/manage/management-list/management-list.component.html - 82 + 46 - - Saved views + + Settings - src/app/components/app-frame/app-frame.component.html - 85 + src/app/components/admin/settings/settings.component.html + 1 - src/app/components/manage/settings/settings.component.html - 265 + src/app/components/admin/settings/settings.component.html + 274 - - - Open documents src/app/components/app-frame/app-frame.component.html - 101 + 45 - - - Close all src/app/components/app-frame/app-frame.component.html - 117 + 179 src/app/components/app-frame/app-frame.component.html - 120 + 182 - - Manage + + Start tour - src/app/components/app-frame/app-frame.component.html - 127 + src/app/components/admin/settings/settings.component.html + 2 - - Correspondents + + Open Django Admin - src/app/components/app-frame/app-frame.component.html - 131 + src/app/components/admin/settings/settings.component.html + 4 + + + General - src/app/components/app-frame/app-frame.component.html - 134 + src/app/components/admin/settings/settings.component.html + 15 - - Tags + + Appearance - src/app/components/app-frame/app-frame.component.html - 138 + src/app/components/admin/settings/settings.component.html + 18 + + + Display language - src/app/components/app-frame/app-frame.component.html - 141 + src/app/components/admin/settings/settings.component.html + 22 + + + You need to reload the page after applying a new language. - src/app/components/common/input/tags/tags.component.ts - 63 + src/app/components/admin/settings/settings.component.html + 30 + + + Date display - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 26 + src/app/components/admin/settings/settings.component.html + 37 + + + Date format - src/app/components/document-list/filter-editor/filter-editor.component.html - 26 + src/app/components/admin/settings/settings.component.html + 50 - - Document types + + Short: - src/app/components/app-frame/app-frame.component.html - 145 + src/app/components/admin/settings/settings.component.html + 56,57 + + + Medium: - src/app/components/app-frame/app-frame.component.html - 148 + src/app/components/admin/settings/settings.component.html + 60,61 - - Storage paths + + Long: - src/app/components/app-frame/app-frame.component.html - 152 + src/app/components/admin/settings/settings.component.html + 64,65 + + + Items per page - src/app/components/app-frame/app-frame.component.html - 155 + src/app/components/admin/settings/settings.component.html + 72 - - Consumption templates + + Document editor - src/app/components/app-frame/app-frame.component.html - 159 + src/app/components/admin/settings/settings.component.html + 88 - - Templates + + Use PDF viewer provided by the browser - src/app/components/app-frame/app-frame.component.html - 162 + src/app/components/admin/settings/settings.component.html + 92 - - File Tasks + + This is usually faster for displaying large PDF documents, but it might not work on some browsers. - src/app/components/app-frame/app-frame.component.html - 166 + src/app/components/admin/settings/settings.component.html + 92 + + + Sidebar - src/app/components/manage/tasks/tasks.component.html - 1 + src/app/components/admin/settings/settings.component.html + 99 - - File Tasks + + Use 'slim' sidebar (icons only) - src/app/components/app-frame/app-frame.component.html - 170 + src/app/components/admin/settings/settings.component.html + 103 - - Logs + + Dark mode - src/app/components/app-frame/app-frame.component.html - 174 + src/app/components/admin/settings/settings.component.html + 110 + + + Use system settings - src/app/components/app-frame/app-frame.component.html - 177 + src/app/components/admin/settings/settings.component.html + 113 + + + Enable dark mode - src/app/components/manage/logs/logs.component.html - 1 + src/app/components/admin/settings/settings.component.html + 114 - - Info + + Invert thumbnails in dark mode - src/app/components/app-frame/app-frame.component.html - 190 + src/app/components/admin/settings/settings.component.html + 115 + + + Theme Color - src/app/components/manage/tasks/tasks.component.html - 43 + src/app/components/admin/settings/settings.component.html + 121 - - Documentation + + Reset - src/app/components/app-frame/app-frame.component.html - 194 - - - src/app/components/app-frame/app-frame.component.html - 197 + src/app/components/admin/settings/settings.component.html + 130 - - GitHub + + Update checking - src/app/components/app-frame/app-frame.component.html - 202 + src/app/components/admin/settings/settings.component.html + 135 + + + Update checking works by pinging the public GitHub API for the latest release to determine whether a new version is available. Actual updating of the app must still be performed manually. - src/app/components/app-frame/app-frame.component.html - 205 + src/app/components/admin/settings/settings.component.html + 139,142 - - Suggest an idea + + No tracking data is collected by the app in any way. - src/app/components/app-frame/app-frame.component.html - 207 + src/app/components/admin/settings/settings.component.html + 144,146 + + + Enable update checking - src/app/components/app-frame/app-frame.component.html - 211 + src/app/components/admin/settings/settings.component.html + 146 - - is available. + + Bulk editing - src/app/components/app-frame/app-frame.component.html - 220 + src/app/components/admin/settings/settings.component.html + 150 - - Click to view. + + Show confirmation dialogs - src/app/components/app-frame/app-frame.component.html - 220 + src/app/components/admin/settings/settings.component.html + 154 - - Paperless-ngx can automatically check for updates + + Deleting documents will always ask for confirmation. - src/app/components/app-frame/app-frame.component.html - 224 + src/app/components/admin/settings/settings.component.html + 154 - - How does this work? + + Apply on close - src/app/components/app-frame/app-frame.component.html - 231,233 + src/app/components/admin/settings/settings.component.html + 155 - - Update available + + Notes - src/app/components/app-frame/app-frame.component.html - 242 + src/app/components/admin/settings/settings.component.html + 159 - - - An error occurred while saving settings. - src/app/components/app-frame/app-frame.component.ts - 104 + src/app/components/document-list/document-list.component.html + 163 - src/app/components/manage/settings/settings.component.ts - 696 + src/app/services/rest/document.service.ts + 25 - - An error occurred while saving update checking settings. + + Enable notes - src/app/components/app-frame/app-frame.component.ts - 237 + src/app/components/admin/settings/settings.component.html + 163 - - Clear + + Permissions - src/app/components/common/clearable-badge/clearable-badge.component.html - 1 + src/app/components/admin/settings/settings.component.html + 171 - src/app/components/common/date-dropdown/date-dropdown.component.html - 33 + src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html + 11 - src/app/components/common/date-dropdown/date-dropdown.component.html - 56 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 30 - - - Cancel - src/app/components/common/confirm-dialog/confirm-dialog.component.html - 12 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 2 - - - Confirmation - src/app/components/common/confirm-dialog/confirm-dialog.component.ts - 20 + src/app/components/document-detail/document-detail.component.html + 192 - - - Confirm - src/app/components/common/confirm-dialog/confirm-dialog.component.ts - 32 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 78 - src/app/components/common/permissions-dialog/permissions-dialog.component.html - 21 + src/app/components/document-list/filter-editor/filter-editor.component.html + 76 - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 323 + src/app/components/manage/mail/mail.component.html + 31 - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 363 + src/app/components/manage/mail/mail.component.html + 69 - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 401 + src/app/components/manage/management-list/management-list.component.html + 10 - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 439 + src/app/components/manage/management-list/management-list.component.html + 10 - - - now - src/app/components/common/date-dropdown/date-dropdown.component.html - 20 + src/app/components/manage/management-list/management-list.component.html + 10 - - - After - src/app/components/common/date-dropdown/date-dropdown.component.html - 28 + src/app/components/manage/management-list/management-list.component.html + 10 - - Before + + Default Permissions - src/app/components/common/date-dropdown/date-dropdown.component.html - 51 + src/app/components/admin/settings/settings.component.html + 174 - - Last 7 days + + Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI - src/app/components/common/date-dropdown/date-dropdown.component.ts - 42 + src/app/components/admin/settings/settings.component.html + 178,180 - - Last month + + Default Owner - src/app/components/common/date-dropdown/date-dropdown.component.ts - 47 + src/app/components/admin/settings/settings.component.html + 185 - - Last 3 months + + Objects without an owner can be viewed and edited by all users - src/app/components/common/date-dropdown/date-dropdown.component.ts - 52 + src/app/components/admin/settings/settings.component.html + 189 - - - Last year - src/app/components/common/date-dropdown/date-dropdown.component.ts - 57 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 25 - - Name + + Default View Permissions - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 10 + src/app/components/admin/settings/settings.component.html + 194 + + + Users: - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 9 + src/app/components/admin/settings/settings.component.html + 199 - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 10 + src/app/components/admin/settings/settings.component.html + 226 - src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html - 10 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 46 - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 10 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 65 - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 10 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 31 - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 9 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 50 + + + Groups: - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 8 + src/app/components/admin/settings/settings.component.html + 209 - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 8 + src/app/components/admin/settings/settings.component.html + 236 - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 13 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 54 - src/app/components/manage/management-list/management-list.component.html - 19 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 73 - src/app/components/manage/management-list/management-list.component.html - 19 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 39 - src/app/components/manage/management-list/management-list.component.html - 19 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 58 + + + Default Edit Permissions - src/app/components/manage/management-list/management-list.component.html - 19 + src/app/components/admin/settings/settings.component.html + 221 + + + Edit permissions also grant viewing permissions - src/app/components/manage/management-list/management-list.component.html - 35 + src/app/components/admin/settings/settings.component.html + 245 - src/app/components/manage/management-list/management-list.component.html - 35 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 79 - src/app/components/manage/management-list/management-list.component.html - 35 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 64 + + + Notifications - src/app/components/manage/management-list/management-list.component.html - 35 - - - src/app/components/manage/settings/settings.component.html - 280 - - - src/app/components/manage/settings/settings.component.html - 333 - - - src/app/components/manage/settings/settings.component.html - 371 - - - src/app/components/manage/settings/settings.component.html - 423 + src/app/components/admin/settings/settings.component.html + 253 + + + Document processing - src/app/components/manage/settings/settings.component.html - 457 + src/app/components/admin/settings/settings.component.html + 256 + + + Show notifications when new documents are detected - src/app/components/manage/tasks/tasks.component.html - 40 + src/app/components/admin/settings/settings.component.html + 260 - - Sort order + + Show notifications when document processing completes successfully - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 13 + src/app/components/admin/settings/settings.component.html + 261 + + + Show notifications when document processing fails - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 14 + src/app/components/admin/settings/settings.component.html + 262 - - Filters + + Suppress notifications on dashboard - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 18 + src/app/components/admin/settings/settings.component.html + 263 - - Process documents that match all filters specified below. + + This will suppress all messages about document processing status on the dashboard. - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 19 + src/app/components/admin/settings/settings.component.html + 263 - - Filter sources + + Saved views - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 20 + src/app/components/admin/settings/settings.component.html + 271 - - - Filter filename - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 21 + src/app/components/app-frame/app-frame.component.html + 85 - - Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. + + Show warning when closing saved views with unsaved changes - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 21 + src/app/components/admin/settings/settings.component.html + 277 - - Filter path + + Views - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 22 + src/app/components/admin/settings/settings.component.html + 281 - - - Apply to documents that match this path. Wildcards specified as * are allowed. Case insensitive.</a> - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 22 + src/app/components/document-list/document-list.component.html + 64 - - Filter mail rule + + Name - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 23 + src/app/components/admin/settings/settings.component.html + 286 - - - Apply to documents consumed via this mail rule. - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 23 + src/app/components/admin/tasks/tasks.component.html + 40 - - - Assignments - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 28 + src/app/components/admin/users-groups/users-groups.component.html + 19 - - - Assign title - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 33 + src/app/components/admin/users-groups/users-groups.component.html + 55 - - - Can include some placeholders, see <a target='_blank' href='https://docs.paperless-ngx.com/usage/#consumption-templates'>documentation</a>. src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 33 + 10 - - - Assign tags - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 34 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 9 - - - Assign document type - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 35 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html + 10 - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 32 + src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html + 10 - - - Assign correspondent - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 36 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 10 src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 34 + 10 - - - Assign storage path - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 37 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 9 - - - Assign owner - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 40 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 8 - - - Assign view permissions - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 42 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 8 - - - Users: - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 46 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 14 - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 65 + src/app/components/manage/mail/mail.component.html + 18 - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 31 + src/app/components/manage/mail/mail.component.html + 56 - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 50 + src/app/components/manage/management-list/management-list.component.html + 19 - src/app/components/manage/settings/settings.component.html - 160 + src/app/components/manage/management-list/management-list.component.html + 19 - src/app/components/manage/settings/settings.component.html - 187 + src/app/components/manage/management-list/management-list.component.html + 19 - - - Groups: - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 54 + src/app/components/manage/management-list/management-list.component.html + 19 - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 73 + src/app/components/manage/management-list/management-list.component.html + 35 - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 39 + src/app/components/manage/management-list/management-list.component.html + 35 - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 58 + src/app/components/manage/management-list/management-list.component.html + 35 - src/app/components/manage/settings/settings.component.html - 170 + src/app/components/manage/management-list/management-list.component.html + 35 + + +  Appears on - src/app/components/manage/settings/settings.component.html - 197 + src/app/components/admin/settings/settings.component.html + 291,292 - - Assign edit permissions + + Show on dashboard - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 61 + src/app/components/admin/settings/settings.component.html + 294 - - - Edit permissions also grant viewing permissions - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 79 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 10 + + + Show in sidebar - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 64 + src/app/components/admin/settings/settings.component.html + 298 - src/app/components/manage/settings/settings.component.html - 206 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 9 - - Error + + Actions - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 88 + src/app/components/admin/settings/settings.component.html + 303 - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 40 + src/app/components/admin/tasks/tasks.component.html + 44 - src/app/components/common/toasts/toasts.component.html - 14 + src/app/components/admin/users-groups/users-groups.component.html + 21 - src/app/services/toast.service.ts - 37 + src/app/components/admin/users-groups/users-groups.component.html + 58 - - - Cancel - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html - 89 + src/app/components/document-detail/document-detail.component.html + 34 - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 20 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 86 - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 22 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 17 - src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html - 16 + src/app/components/manage/mail/mail.component.html + 20 - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 34 + src/app/components/manage/mail/mail.component.html + 58 - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 41 + src/app/components/manage/management-list/management-list.component.html + 39 - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 21 + src/app/components/manage/management-list/management-list.component.html + 39 - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 23 + src/app/components/manage/management-list/management-list.component.html + 39 - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 35 + src/app/components/manage/management-list/management-list.component.html + 39 + + + + Delete + + src/app/components/admin/settings/settings.component.html + 304 - src/app/components/common/permissions-dialog/permissions-dialog.component.html - 20 + src/app/components/admin/users-groups/users-groups.component.html + 33 - src/app/components/common/select-dialog/select-dialog.component.html - 12 + src/app/components/admin/users-groups/users-groups.component.html + 70 + + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 53 + + + src/app/components/common/permissions-select/permissions-select.component.html + 9 + + + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 33 + + + src/app/components/document-detail/document-detail.component.html + 11 src/app/components/document-list/bulk-editor/bulk-editor.component.html - 6 + 138 - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 18 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 29 + + + src/app/components/manage/mail/mail.component.html + 32 + + + src/app/components/manage/mail/mail.component.html + 70 + + + src/app/components/manage/management-list/management-list.component.html + 74 + + + src/app/components/manage/management-list/management-list.component.html + 74 + + + src/app/components/manage/management-list/management-list.component.html + 74 + + + src/app/components/manage/management-list/management-list.component.html + 74 + + + src/app/components/manage/management-list/management-list.component.html + 92 + + + src/app/components/manage/management-list/management-list.component.html + 92 + + + src/app/components/manage/management-list/management-list.component.html + 92 + + + src/app/components/manage/management-list/management-list.component.html + 92 + + + src/app/components/manage/management-list/management-list.component.ts + 205 + + + + No saved views defined. + + src/app/components/admin/settings/settings.component.html + 308 Save + + src/app/components/admin/settings/settings.component.html + 323 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html 90 @@ -1292,4260 +1342,4258 @@ src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html 19 + + + Error retrieving users + + src/app/components/admin/settings/settings.component.ts + 153 + - src/app/components/manage/settings/settings.component.html - 493 + src/app/components/admin/users-groups/users-groups.component.ts + 55 - - Consume Folder + + Error retrieving groups - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts - 25 + src/app/components/admin/settings/settings.component.ts + 172 + + + src/app/components/admin/users-groups/users-groups.component.ts + 67 - - API Upload + + Saved view "" deleted. - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts - 29 + src/app/components/admin/settings/settings.component.ts + 363 - - Mail Fetch + + Settings saved - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts - 33 + src/app/components/admin/settings/settings.component.ts + 485 - - Create new consumption template + + Settings were saved successfully. - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts - 83 + src/app/components/admin/settings/settings.component.ts + 486 - - Edit consumption template + + Settings were saved successfully. Reload is required to apply some changes. - src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts - 87 + src/app/components/admin/settings/settings.component.ts + 490 - - Matching algorithm + + Reload now - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 10 + src/app/components/admin/settings/settings.component.ts + 491 + + + An error occurred while saving settings. - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 11 + src/app/components/admin/settings/settings.component.ts + 501 - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 11 + src/app/components/app-frame/app-frame.component.ts + 104 + + + Use system language - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 13 + src/app/components/admin/settings/settings.component.ts + 509 - - Matching pattern + + Use date format of display language - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 11 + src/app/components/admin/settings/settings.component.ts + 516 + + + Error while storing settings on server. - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 12 + src/app/components/admin/settings/settings.component.ts + 539 + + + File Tasks - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 12 + src/app/components/admin/tasks/tasks.component.html + 1 - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 14 + src/app/components/app-frame/app-frame.component.html + 193 - - Case insensitive + + Clear selection - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html - 12 + src/app/components/admin/tasks/tasks.component.html + 6 - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html - 13 + src/app/components/manage/management-list/management-list.component.html + 5 - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 13 + src/app/components/manage/management-list/management-list.component.html + 5 - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 15 + src/app/components/manage/management-list/management-list.component.html + 5 - - - Create new correspondent - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts - 27 + src/app/components/manage/management-list/management-list.component.html + 5 - - Edit correspondent + + - src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts - 31 + src/app/components/admin/tasks/tasks.component.html + 11 - - - Create new document type - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts - 27 + src/app/components/common/input/tags/tags.component.html + 2 - - - Edit document type - src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts - 31 + src/app/components/common/permissions-select/permissions-select.component.html + 22 - - Create new item + + Refresh - src/app/components/common/edit-dialog/edit-dialog.component.ts - 109 + src/app/components/admin/tasks/tasks.component.html + 20 - - Edit item + + Created - src/app/components/common/edit-dialog/edit-dialog.component.ts - 113 + src/app/components/admin/tasks/tasks.component.html + 41 - - - Permissions - src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html - 11 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 9 - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 30 + src/app/components/document-list/document-list.component.html + 184 - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 2 + src/app/components/document-list/filter-editor/filter-editor.component.html + 62 - src/app/components/document-detail/document-detail.component.html - 192 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 78 + src/app/services/rest/document.service.ts + 22 + + + Results - src/app/components/document-list/filter-editor/filter-editor.component.html - 76 + src/app/components/admin/tasks/tasks.component.html + 42 + + + Info - src/app/components/manage/management-list/management-list.component.html - 10 + src/app/components/admin/tasks/tasks.component.html + 43 - src/app/components/manage/management-list/management-list.component.html - 10 + src/app/components/app-frame/app-frame.component.html + 210 + + + click for full output - src/app/components/manage/management-list/management-list.component.html - 10 + src/app/components/admin/tasks/tasks.component.html + 66 + + + Dismiss - src/app/components/manage/management-list/management-list.component.html - 10 + src/app/components/admin/tasks/tasks.component.html + 81 - src/app/components/manage/settings/settings.component.html - 135 + src/app/components/admin/tasks/tasks.component.ts + 64 + + + Open Document - src/app/components/manage/settings/settings.component.html - 346 + src/app/components/admin/tasks/tasks.component.html + 87 + + + {VAR_PLURAL, plural, =1 {One task} other { total tasks}} - src/app/components/manage/settings/settings.component.html - 384 + src/app/components/admin/tasks/tasks.component.html + 103 - - Create new user group + + Failed - src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts - 26 + src/app/components/admin/tasks/tasks.component.html + 110 - - Edit user group + + Complete - src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts - 30 + src/app/components/admin/tasks/tasks.component.html + 116 - - IMAP Server + + Started - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 11 + src/app/components/admin/tasks/tasks.component.html + 122 - - IMAP Port + + Queued - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 12 + src/app/components/admin/tasks/tasks.component.html + 128 - - IMAP Security + + Dismiss selected - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 13 + src/app/components/admin/tasks/tasks.component.ts + 28 - - Username + + Dismiss all - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 16 + src/app/components/admin/tasks/tasks.component.ts + 29 - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 10 + src/app/components/admin/tasks/tasks.component.ts + 62 + + + Confirm Dismiss All - src/app/components/manage/settings/settings.component.html - 422 + src/app/components/admin/tasks/tasks.component.ts + 60 - - Password + + tasks? - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 17 + src/app/components/admin/tasks/tasks.component.ts + 62 + + + queued - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 12 + src/app/components/admin/tasks/tasks.component.ts + 130 - - Password is token + + started - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 18 + src/app/components/admin/tasks/tasks.component.ts + 132 - - Check if the password above is a token used for authentication + + completed - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 18 + src/app/components/admin/tasks/tasks.component.ts + 134 - - Character Set + + failed - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 19 + src/app/components/admin/tasks/tasks.component.ts + 136 - - Loading... + + Users & Groups - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 30 + src/app/components/admin/users-groups/users-groups.component.html + 1 - src/app/components/common/permissions-dialog/permissions-dialog.component.html - 18 + src/app/components/app-frame/app-frame.component.html + 186 - src/app/components/dashboard/dashboard.component.html - 10 + src/app/components/app-frame/app-frame.component.html + 189 + + + Users - src/app/components/dashboard/widgets/widget-frame/widget-frame.component.html - 7 + src/app/components/admin/users-groups/users-groups.component.html + 6 - src/app/components/document-list/document-list.component.html - 95 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 68 + + + Add User - src/app/components/manage/logs/logs.component.html + src/app/components/admin/users-groups/users-groups.component.html 11 + + + Username - src/app/components/manage/logs/logs.component.html - 20 + src/app/components/admin/users-groups/users-groups.component.html + 18 - src/app/components/manage/management-list/management-list.component.html - 46 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 16 - src/app/components/manage/management-list/management-list.component.html - 46 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 10 + + + Groups - src/app/components/manage/management-list/management-list.component.html - 46 + src/app/components/admin/users-groups/users-groups.component.html + 20 - src/app/components/manage/management-list/management-list.component.html - 46 + src/app/components/admin/users-groups/users-groups.component.html + 43 - src/app/components/manage/settings/settings.component.html - 306 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 27 + + + Edit - src/app/components/manage/settings/settings.component.html - 398 + src/app/components/admin/users-groups/users-groups.component.html + 32 - src/app/components/manage/settings/settings.component.html - 484 + src/app/components/admin/users-groups/users-groups.component.html + 69 - src/app/components/manage/tasks/tasks.component.html - 19 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 46 - src/app/components/manage/tasks/tasks.component.html - 27 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 17 - - - Test - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html - 32 + src/app/components/document-list/document-card-large/document-card-large.component.html + 49 - - - No encryption - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 14 + src/app/components/document-list/document-card-small/document-card-small.component.html + 83 - - - SSL - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 15 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 28 - - - STARTTLS - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 16 + src/app/components/manage/mail/mail.component.html + 30 - - - Create new mail account - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 41 + src/app/components/manage/mail/mail.component.html + 68 - - - Edit mail account - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 45 + src/app/components/manage/management-list/management-list.component.html + 73 - - - Successfully connected to the mail server - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 90 + src/app/components/manage/management-list/management-list.component.html + 73 - - - Unable to connect to the mail server - src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts - 91 + src/app/components/manage/management-list/management-list.component.html + 73 - - - Account - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 11 + src/app/components/manage/management-list/management-list.component.html + 73 - src/app/components/manage/settings/settings.component.html - 372 + src/app/components/manage/management-list/management-list.component.html + 87 - - - Folder - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 12 + src/app/components/manage/management-list/management-list.component.html + 87 - - - Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 12 + src/app/components/manage/management-list/management-list.component.html + 87 - - - Maximum age (days) - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 13 + src/app/components/manage/management-list/management-list.component.html + 87 - - Attachment type + + Add Group - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 14 + src/app/components/admin/users-groups/users-groups.component.html + 48 - - Consumption scope + + Password has been changed, you will be logged out momentarily. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 15 + src/app/components/admin/users-groups/users-groups.component.ts + 93 - - See docs for .eml processing requirements + + Saved user "". - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 15 + src/app/components/admin/users-groups/users-groups.component.ts + 100 - - Rule order + + Error saving user. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 16 + src/app/components/admin/users-groups/users-groups.component.ts + 110 - - Paperless will only process mails that match all of the filters specified below. + + Confirm delete user account - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 19 + src/app/components/admin/users-groups/users-groups.component.ts + 118 - - Filter from + + This operation will permanently delete this user account. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 20 + src/app/components/admin/users-groups/users-groups.component.ts + 119 - - Filter to + + This operation cannot be undone. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 21 + src/app/components/admin/users-groups/users-groups.component.ts + 120 - - - Filter subject - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 22 + src/app/components/admin/users-groups/users-groups.component.ts + 170 - - - Filter body - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 23 + src/app/components/document-detail/document-detail.component.ts + 656 - - - Filter attachment filename - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 24 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 461 - - - Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 24 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 500 - - - Action - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 27 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 91 - - - Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 27 + src/app/components/manage/mail/mail.component.ts + 114 - - - Action parameter - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 28 + src/app/components/manage/mail/mail.component.ts + 173 - - Assignments specified here will supersede any consumption templates. + + Proceed - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 29 + src/app/components/admin/users-groups/users-groups.component.ts + 122 + + + src/app/components/admin/users-groups/users-groups.component.ts + 172 + + + src/app/components/document-detail/document-detail.component.ts + 658 + + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 502 + + + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 93 + + + src/app/components/manage/mail/mail.component.ts + 116 + + + src/app/components/manage/mail/mail.component.ts + 175 - - Assign title from + + Deleted user - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 30 + src/app/components/admin/users-groups/users-groups.component.ts + 128 - - Assign correspondent from + + Error deleting user. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 33 + src/app/components/admin/users-groups/users-groups.component.ts + 134 - - Assign owner from rule + + Saved group "". - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html - 35 + src/app/components/admin/users-groups/users-groups.component.ts + 152 - - Only process attachments + + Error saving group. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 27 + src/app/components/admin/users-groups/users-groups.component.ts + 160 + + + Confirm delete user group - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 38 + src/app/components/admin/users-groups/users-groups.component.ts + 168 - - Process all files, including 'inline' attachments + + This operation will permanently delete this user group. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 31 + src/app/components/admin/users-groups/users-groups.component.ts + 169 - - Process message as .eml + + Deleted group - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 42 + src/app/components/admin/users-groups/users-groups.component.ts + 178 - - Process message as .eml and attachments separately + + Error deleting group. - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 46 + src/app/components/admin/users-groups/users-groups.component.ts + 184 - - Delete + + Paperless-ngx - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 53 + src/app/components/app-frame/app-frame.component.html + 11 + app title + + + Search documents - src/app/components/common/permissions-select/permissions-select.component.html - 9 + src/app/components/app-frame/app-frame.component.html + 18 + + + Logged in as - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 33 + src/app/components/app-frame/app-frame.component.html + 39 + + + Logout - src/app/components/document-detail/document-detail.component.html - 11 + src/app/components/app-frame/app-frame.component.html + 50 + + + Dashboard - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 138 + src/app/components/app-frame/app-frame.component.html + 69 - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 27 + src/app/components/app-frame/app-frame.component.html + 72 - src/app/components/manage/management-list/management-list.component.html - 74 + src/app/components/dashboard/dashboard.component.html + 1 + + + Documents - src/app/components/manage/management-list/management-list.component.html - 74 + src/app/components/app-frame/app-frame.component.html + 76 - src/app/components/manage/management-list/management-list.component.html - 74 + src/app/components/app-frame/app-frame.component.html + 79 - src/app/components/manage/management-list/management-list.component.html - 74 + src/app/components/document-list/document-list.component.ts + 97 src/app/components/manage/management-list/management-list.component.html - 92 + 82 src/app/components/manage/management-list/management-list.component.html - 92 + 82 src/app/components/manage/management-list/management-list.component.html - 92 + 82 src/app/components/manage/management-list/management-list.component.html - 92 + 82 + + + Open documents - src/app/components/manage/management-list/management-list.component.ts - 205 + src/app/components/app-frame/app-frame.component.html + 101 + + + Close all - src/app/components/manage/settings/settings.component.html - 298 + src/app/components/app-frame/app-frame.component.html + 117 - src/app/components/manage/settings/settings.component.html - 347 + src/app/components/app-frame/app-frame.component.html + 120 + + + Manage - src/app/components/manage/settings/settings.component.html - 385 + src/app/components/app-frame/app-frame.component.html + 127 + + + Correspondents - src/app/components/manage/settings/settings.component.html - 437 + src/app/components/app-frame/app-frame.component.html + 131 - src/app/components/manage/settings/settings.component.html - 472 + src/app/components/app-frame/app-frame.component.html + 134 - - Move to specified folder + + Tags - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 57 + src/app/components/app-frame/app-frame.component.html + 138 - - - Mark as read, don't process read mails - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 61 + src/app/components/app-frame/app-frame.component.html + 141 - - - Flag the mail, don't process flagged mails - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 65 + src/app/components/common/input/tags/tags.component.ts + 63 - - - Tag the mail with specified tag, don't process tagged mails - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 69 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 26 - - - Use subject as title - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 76 + src/app/components/document-list/filter-editor/filter-editor.component.html + 26 - - Use attachment filename as title + + Document types - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 80 + src/app/components/app-frame/app-frame.component.html + 145 - - - Do not assign title from this rule - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 84 + src/app/components/app-frame/app-frame.component.html + 148 - - Do not assign a correspondent + + Storage paths - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 91 + src/app/components/app-frame/app-frame.component.html + 152 - - - Use mail address - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 95 + src/app/components/app-frame/app-frame.component.html + 155 - - Use name (or mail address if not available) + + Consumption templates - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 99 + src/app/components/app-frame/app-frame.component.html + 159 - - Use correspondent selected below + + Templates - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 103 + src/app/components/app-frame/app-frame.component.html + 162 - - Create new mail rule + + Mail - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 145 + src/app/components/app-frame/app-frame.component.html + 166 - - - Edit mail rule - src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts - 149 + src/app/components/app-frame/app-frame.component.html + 169 - - Path - - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html - 10 - + + Administration - src/app/components/manage/storage-path-list/storage-path-list.component.ts - 42 + src/app/components/app-frame/app-frame.component.html + 175 - - e.g. + + File Tasks - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 28 + src/app/components/app-frame/app-frame.component.html + 197 - - or use slashes to add directories e.g. + + Documentation - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 30 + src/app/components/app-frame/app-frame.component.html + 214 - - - See <a target="_blank" href="https://docs.paperless-ngx.com/advanced_usage/#file-name-handling">documentation</a> for full list. - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 32 + src/app/components/app-frame/app-frame.component.html + 217 - - Create new storage path + + GitHub - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 37 + src/app/components/app-frame/app-frame.component.html + 222 - - - Edit storage path - src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts - 41 + src/app/components/app-frame/app-frame.component.html + 225 - - Color + + Suggest an idea - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 10 + src/app/components/app-frame/app-frame.component.html + 227 - src/app/components/manage/tag-list/tag-list.component.ts - 42 + src/app/components/app-frame/app-frame.component.html + 231 - - Inbox tag + + is available. - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 12 + src/app/components/app-frame/app-frame.component.html + 240 - - Inbox tags are automatically assigned to all consumed documents. + + Click to view. - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html - 12 + src/app/components/app-frame/app-frame.component.html + 240 - - Create new tag + + Paperless-ngx can automatically check for updates - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts - 28 + src/app/components/app-frame/app-frame.component.html + 244 - - Edit tag + + How does this work? - src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts - 32 + src/app/components/app-frame/app-frame.component.html + 251,253 - - Email + + Update available - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 11 + src/app/components/app-frame/app-frame.component.html + 262 - - First name + + An error occurred while saving update checking settings. - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 13 + src/app/components/app-frame/app-frame.component.ts + 237 - - Last name + + Clear - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 14 + src/app/components/common/clearable-badge/clearable-badge.component.html + 1 - - - Active - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 19 + src/app/components/common/date-dropdown/date-dropdown.component.html + 33 - - - Superuser - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 23 + src/app/components/common/date-dropdown/date-dropdown.component.html + 56 - - (Grants all permissions and can view objects) + + Cancel - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 23 + src/app/components/common/confirm-dialog/confirm-dialog.component.html + 12 - - Groups - - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html - 27 - - - src/app/components/manage/settings/settings.component.html - 424 - - - src/app/components/manage/settings/settings.component.html - 445 - - - - Create new user account + + Confirmation - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts - 44 + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 20 - - Edit user account + + Confirm - src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts - 48 + src/app/components/common/confirm-dialog/confirm-dialog.component.ts + 32 - - - All - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 16 + src/app/components/common/permissions-dialog/permissions-dialog.component.html + 21 - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 18 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 323 - src/app/components/common/permissions-select/permissions-select.component.html - 6 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 363 - src/app/components/common/permissions-select/permissions-select.component.html - 17 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 401 - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 20 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 439 - - Any + + now - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 18 + src/app/components/common/date-dropdown/date-dropdown.component.html + 20 - - Include + + After - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 24 + src/app/components/common/date-dropdown/date-dropdown.component.html + 28 - - Exclude + + Before - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 26 + src/app/components/common/date-dropdown/date-dropdown.component.html + 51 - - Apply + + Last 7 days - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + src/app/components/common/date-dropdown/date-dropdown.component.ts 42 - - Click again to exclude items. + + Last month - src/app/components/common/filterable-dropdown/filterable-dropdown.component.html - 48 + src/app/components/common/date-dropdown/date-dropdown.component.ts + 47 - - Not assigned + + Last 3 months - src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts - 337 + src/app/components/common/date-dropdown/date-dropdown.component.ts + 52 - Filter drop down element to filter for documents with no correspondent/type/tag assigned - - Invalid date. + + Last year - src/app/components/common/input/date/date.component.html - 18 + src/app/components/common/date-dropdown/date-dropdown.component.ts + 57 - - Suggestions: + + Sort order - src/app/components/common/input/date/date.component.html - 21 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 13 - src/app/components/common/input/select/select.component.html - 37 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 15 + + + Filters - src/app/components/common/input/tags/tags.component.html - 43 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 18 - - Filter documents with this + + Process documents that match all filters specified below. - src/app/components/common/input/date/date.component.ts - 103 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 19 + + + Filter sources - src/app/components/common/input/select/select.component.ts - 149 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 20 - - Edit Permissions + + Filter filename - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 7 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 21 - - Owner: + + Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 19 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 21 - - Objects without an owner can be viewed and edited by all users + + Filter path - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 25 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 22 + + + Apply to documents that match this path. Wildcards specified as * are allowed. Case insensitive.</a> - src/app/components/manage/settings/settings.component.html - 150 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 22 - - View + + Filter mail rule - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 27 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 23 + + + Apply to documents consumed via this mail rule. - src/app/components/common/permissions-select/permissions-select.component.html - 10 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 23 + + + Assignments - src/app/components/document-list/document-card-large/document-card-large.component.html - 56 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 28 - - Edit + + Assign title - src/app/components/common/input/permissions/permissions-form/permissions-form.component.html - 46 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 33 + + + Can include some placeholders, see <a target='_blank' href='https://docs.paperless-ngx.com/usage/#consumption-templates'>documentation</a>. - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 17 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 33 + + + Assign tags - src/app/components/document-list/document-card-large/document-card-large.component.html - 49 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 34 + + + Assign document type - src/app/components/document-list/document-card-small/document-card-small.component.html - 83 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 35 - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 26 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 32 + + + Assign correspondent - src/app/components/manage/management-list/management-list.component.html - 73 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 36 - src/app/components/manage/management-list/management-list.component.html - 73 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 34 + + + Assign storage path - src/app/components/manage/management-list/management-list.component.html - 73 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 37 + + + Assign owner - src/app/components/manage/management-list/management-list.component.html - 73 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 40 + + + Assign view permissions - src/app/components/manage/management-list/management-list.component.html - 87 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 42 + + + Assign edit permissions - src/app/components/manage/management-list/management-list.component.html - 87 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 61 + + + Error - src/app/components/manage/management-list/management-list.component.html - 87 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 88 - src/app/components/manage/management-list/management-list.component.html - 87 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 40 - src/app/components/manage/settings/settings.component.html - 345 + src/app/components/common/toasts/toasts.component.html + 14 - src/app/components/manage/settings/settings.component.html - 383 + src/app/services/toast.service.ts + 37 + + + Cancel - src/app/components/manage/settings/settings.component.html - 436 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.html + 89 - src/app/components/manage/settings/settings.component.html - 471 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 20 - - - Add item - src/app/components/common/input/select/select.component.html - 12 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html + 22 - Used for both types, correspondents, storage paths - - - Private - src/app/components/common/input/select/select.component.ts - 57 + src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.html + 16 - src/app/components/common/tag/tag.component.html - 7 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 34 - src/app/components/common/tag/tag.component.html - 8 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 41 - src/app/components/document-list/document-card-small/document-card-small.component.ts - 80 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 21 - - - - src/app/components/common/input/tags/tags.component.html - 2 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 23 - src/app/components/common/permissions-select/permissions-select.component.html - 22 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 35 - src/app/components/manage/tasks/tasks.component.html - 11 + src/app/components/common/permissions-dialog/permissions-dialog.component.html + 20 - - - Add tag - src/app/components/common/input/tags/tags.component.html + src/app/components/common/select-dialog/select-dialog.component.html 12 + + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 6 + + + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 18 + - - Filter documents with these Tags + + Consume Folder - src/app/components/common/input/tags/tags.component.html - 35 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts + 25 - - Set permissions + + API Upload - src/app/components/common/permissions-dialog/permissions-dialog.component.ts - 28 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts + 29 - - Edit permissions for + + Mail Fetch - src/app/components/common/permissions-dialog/permissions-dialog.component.ts + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts 33 - - Note that permissions set here will override any existing permissions + + Create new consumption template - src/app/components/common/permissions-dialog/permissions-dialog.component.ts - 61 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts + 83 - - My documents + + Edit consumption template - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 28 + src/app/components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component.ts + 87 - - Shared with me + + Matching algorithm - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 38 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 10 - - - Unowned - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 48 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html + 11 - - - Users - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 68 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 11 - src/app/components/manage/settings/settings.component.html - 410 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 13 - - Hide unowned + + Matching pattern - src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html - 77 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 11 - - - Type - src/app/components/common/permissions-select/permissions-select.component.html - 5 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html + 12 - - - Add - src/app/components/common/permissions-select/permissions-select.component.html - 7 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 12 - - - Change - src/app/components/common/permissions-select/permissions-select.component.html - 8 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 14 - - Inherited from group + + Case insensitive - src/app/components/common/permissions-select/permissions-select.component.ts - 61 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html + 12 - - - Select - src/app/components/common/select-dialog/select-dialog.component.html + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.html 13 - src/app/components/common/select-dialog/select-dialog.component.ts - 17 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 13 - src/app/components/document-list/document-list.component.html - 8 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 15 - - Please select an object + + Create new correspondent - src/app/components/common/select-dialog/select-dialog.component.ts - 20 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 27 - - Share Links + + Edit correspondent - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 6 + src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.ts + 31 + + + Create new document type - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 26 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts + 27 - - No existing links + + Edit document type - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 10,12 + src/app/components/common/edit-dialog/document-type-edit-dialog/document-type-edit-dialog.component.ts + 31 - - Copy + + Create new item - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 23 + src/app/components/common/edit-dialog/edit-dialog.component.ts + 109 - - Share + + Edit item - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 28 + src/app/components/common/edit-dialog/edit-dialog.component.ts + 113 - - Copied! + + Create new user group - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 36 + src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts + 26 - - Share archive version + + Edit user group - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 42 + src/app/components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component.ts + 30 - - Create + + IMAP Server - src/app/components/common/share-links-dropdown/share-links-dropdown.component.html - 55 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 11 + + + IMAP Port - src/app/components/manage/management-list/management-list.component.html + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 12 + + + IMAP Security - src/app/components/manage/management-list/management-list.component.html - 12 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 13 + + + Password - src/app/components/manage/management-list/management-list.component.html - 12 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 17 - src/app/components/manage/management-list/management-list.component.html + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html 12 - - 1 day + + Password is token - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 18 + + + + Check if the password above is a token used for authentication + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 18 + + + + Character Set + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html 19 + + + Test - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 90 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.html + 32 - - 7 days + + No encryption - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 20 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 14 - - 30 days + + SSL - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 21 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 15 - - Never + + STARTTLS - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 22 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 16 - - Error retrieving links + + Create new mail account - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 74 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 41 - - days + + Edit mail account - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 45 + + + + Successfully connected to the mail server + + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts 90 - - Error deleting link + + Unable to connect to the mail server - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 117 + src/app/components/common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component.ts + 91 - - Error creating link + + Account - src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts - 145 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 11 + + + src/app/components/manage/mail/mail.component.html + 57 - - Status + + Folder - src/app/components/common/toasts/toasts.component.html + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 12 - - Copy Raw Error + + Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server. - src/app/components/common/toasts/toasts.component.html - 23 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 12 - - Hello , welcome to Paperless-ngx + + Maximum age (days) - src/app/components/dashboard/dashboard.component.ts - 23 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 13 - - Welcome to Paperless-ngx + + Attachment type - src/app/components/dashboard/dashboard.component.ts - 25 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 14 - - Show all + + Consumption scope - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 3 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 15 + + + See docs for .eml processing requirements - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 27 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 15 - - Created + + Rule order - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 9 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 16 + + + Paperless will only process mails that match all of the filters specified below. - src/app/components/document-list/document-list.component.html - 184 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 19 + + + Filter from - src/app/components/document-list/filter-editor/filter-editor.component.html - 62 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 20 + + + Filter to - src/app/components/manage/tasks/tasks.component.html - 41 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 21 + + + Filter subject - src/app/services/rest/document.service.ts + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 22 - - Title + + Filter body - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 10 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 23 + + + Filter attachment filename - src/app/components/document-detail/document-detail.component.html - 85 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 24 + + + Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive. - src/app/components/document-list/document-list.component.html - 149 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 24 + + + Action - src/app/components/document-list/filter-editor/filter-editor.component.ts - 201 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 27 + + + Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched. - src/app/services/rest/document.service.ts - 20 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 27 - - View Preview + + Action parameter - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html - 19 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 28 - - Download + + Assignments specified here will supersede any consumption templates. - src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html 29 + + + Assign title from - src/app/components/document-detail/document-detail.component.html - 18 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 102 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 30 + + + Assign correspondent from - src/app/components/document-list/document-card-large/document-card-large.component.html - 64 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 33 + + + Assign owner from rule - src/app/components/document-list/document-card-small/document-card-small.component.html - 99 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.html + 35 - - Statistics + + Only process attachments - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 1 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 27 + + + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 38 - - Go to inbox + + Process all files, including 'inline' attachments - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 4 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 31 - - Documents in inbox + + Process message as .eml - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 5 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 42 - - Go to documents + + Process message as .eml and attachments separately - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 8 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 46 - - Total documents + + Move to specified folder - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 9 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 57 - - Total characters + + Mark as read, don't process read mails - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html - 13 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 61 - - Other + + Flag the mail, don't process flagged mails - src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.ts - 55 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 65 - - Upload new documents + + Tag the mail with specified tag, don't process tagged mails - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 1 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 69 - - Dismiss completed + + Use subject as title - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 4 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 76 - This button dismisses all status messages about processed documents on the dashboard (failed and successful) - - Drop documents here or + + Use attachment filename as title - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 13 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 80 - - Browse files + + Do not assign title from this rule - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 13 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 84 - - {VAR_PLURAL, plural, =1 {One more document} other { more documents}} + + Do not assign a correspondent - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html - 25 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 91 - This is shown as a summary line when there are more than 5 document in the processing pipeline. - - Processing: + + Use mail address - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts - 39 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 95 - - Failed: + + Use name (or mail address if not available) - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts - 42 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 99 - - Added: + + Use correspondent selected below - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts - 45 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 103 - - , + + Create new mail rule - src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts - 48 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 145 + + + Edit mail rule - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 268 + src/app/components/common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component.ts + 149 - this string is used to separate processing, failed and added on the file upload widget - - Paperless-ngx is running! + + Path - src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html - 2 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.html + 10 + + + src/app/components/manage/storage-path-list/storage-path-list.component.ts + 42 - - You're ready to start uploading documents! Explore the various features of this web app on your own, or start a quick tour using the button below. + + e.g. - src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html - 3 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts + 28 - - More detail on how to use and configure Paperless-ngx is always available in the documentation. + + or use slashes to add directories e.g. - src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html - 4 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts + 30 - - Thanks for being a part of the Paperless-ngx community! + + See <a target="_blank" href="https://docs.paperless-ngx.com/advanced_usage/#file-name-handling">documentation</a> for full list. - src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html - 7 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts + 32 - - Start the tour + + Create new storage path - src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html - 8 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts + 37 - - Searching document with asn + + Edit storage path - src/app/components/document-asn/document-asn.component.html - 1 + src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts + 41 - - Page + + Color - src/app/components/document-detail/document-detail.component.html - 3 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 10 - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 15 + src/app/components/manage/tag-list/tag-list.component.ts + 42 - - of + + Inbox tag - src/app/components/document-detail/document-detail.component.html - 5,6 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 12 - - Download original + + Inbox tags are automatically assigned to all consumed documents. - src/app/components/document-detail/document-detail.component.html - 24 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.html + 12 - - Actions + + Create new tag - src/app/components/document-detail/document-detail.component.html - 34 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts + 28 + + + Edit tag - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 86 + src/app/components/common/edit-dialog/tag-edit-dialog/tag-edit-dialog.component.ts + 32 + + + Email - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 16 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 11 + + + First name - src/app/components/manage/management-list/management-list.component.html - 39 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 13 + + + Last name - src/app/components/manage/management-list/management-list.component.html - 39 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 14 + + + Active - src/app/components/manage/management-list/management-list.component.html - 39 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 19 + + + Superuser - src/app/components/manage/management-list/management-list.component.html - 39 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 23 + + + (Grants all permissions and can view objects) - src/app/components/manage/settings/settings.component.html - 297 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.html + 23 + + + Create new user account - src/app/components/manage/settings/settings.component.html - 335 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts + 44 + + + Edit user account - src/app/components/manage/settings/settings.component.html - 373 + src/app/components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component.ts + 48 + + + All - src/app/components/manage/settings/settings.component.html - 425 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 16 - src/app/components/manage/settings/settings.component.html - 460 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 18 - src/app/components/manage/tasks/tasks.component.html - 44 + src/app/components/common/permissions-select/permissions-select.component.html + 6 - - - Redo OCR - src/app/components/document-detail/document-detail.component.html - 40 + src/app/components/common/permissions-select/permissions-select.component.html + 17 src/app/components/document-list/bulk-editor/bulk-editor.component.html - 89 + 20 - - More like this - - src/app/components/document-detail/document-detail.component.html - 46 - + + Any - src/app/components/document-list/document-card-large/document-card-large.component.html - 44 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 18 - - Close + + Include - src/app/components/document-detail/document-detail.component.html - 53 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 24 + + + Exclude - src/app/guards/dirty-saved-view.guard.ts - 37 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 26 - - Previous + + Apply - src/app/components/document-detail/document-detail.component.html - 60 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 42 - - Details + + Click again to exclude items. - src/app/components/document-detail/document-detail.component.html - 82 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.html + 48 - - Archive serial number + + Not assigned - src/app/components/document-detail/document-detail.component.html - 86 + src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts + 337 + Filter drop down element to filter for documents with no correspondent/type/tag assigned - - Date created + + Invalid date. - src/app/components/document-detail/document-detail.component.html - 87 + src/app/components/common/input/date/date.component.html + 18 - - Correspondent + + Suggestions: - src/app/components/document-detail/document-detail.component.html - 89 + src/app/components/common/input/date/date.component.html + 21 - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 38 + src/app/components/common/input/select/select.component.html + 37 - src/app/components/document-list/document-list.component.html - 142 + src/app/components/common/input/tags/tags.component.html + 43 + + + Filter documents with this - src/app/components/document-list/filter-editor/filter-editor.component.html - 35 + src/app/components/common/input/date/date.component.ts + 103 - src/app/services/rest/document.service.ts - 19 + src/app/components/common/input/select/select.component.ts + 149 - - Document type + + Edit Permissions - src/app/components/document-detail/document-detail.component.html - 91 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 7 + + + Owner: - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 49 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 19 + + + View - src/app/components/document-list/document-list.component.html - 170 + src/app/components/common/input/permissions/permissions-form/permissions-form.component.html + 27 - src/app/components/document-list/filter-editor/filter-editor.component.html - 43 + src/app/components/common/permissions-select/permissions-select.component.html + 10 - src/app/services/rest/document.service.ts - 21 + src/app/components/document-list/document-card-large/document-card-large.component.html + 56 - - Storage path + + Add item - src/app/components/document-detail/document-detail.component.html - 93 + src/app/components/common/input/select/select.component.html + 12 + Used for both types, correspondents, storage paths + + + Private - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 60 + src/app/components/common/input/select/select.component.ts + 57 - src/app/components/document-list/document-list.component.html - 177 + src/app/components/common/tag/tag.component.html + 7 - src/app/components/document-list/filter-editor/filter-editor.component.html - 51 + src/app/components/common/tag/tag.component.html + 8 - - - Default - src/app/components/document-detail/document-detail.component.html - 94 + src/app/components/document-list/document-card-small/document-card-small.component.ts + 80 - - Content + + Add tag - src/app/components/document-detail/document-detail.component.html - 101 + src/app/components/common/input/tags/tags.component.html + 12 - - Metadata + + Filter documents with these Tags - src/app/components/document-detail/document-detail.component.html - 110 + src/app/components/common/input/tags/tags.component.html + 35 + + + Set permissions - src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts - 17 + src/app/components/common/permissions-dialog/permissions-dialog.component.ts + 28 - - Date modified + + Edit permissions for - src/app/components/document-detail/document-detail.component.html - 116 + src/app/components/common/permissions-dialog/permissions-dialog.component.ts + 33 - - Date added + + Note that permissions set here will override any existing permissions - src/app/components/document-detail/document-detail.component.html - 120 + src/app/components/common/permissions-dialog/permissions-dialog.component.ts + 61 - - Media filename + + My documents - src/app/components/document-detail/document-detail.component.html - 124 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 28 - - Original filename + + Shared with me - src/app/components/document-detail/document-detail.component.html - 128 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 38 - - Original MD5 checksum + + Unowned - src/app/components/document-detail/document-detail.component.html - 132 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 48 - - Original file size + + Hide unowned - src/app/components/document-detail/document-detail.component.html - 136 + src/app/components/common/permissions-filter-dropdown/permissions-filter-dropdown.component.html + 77 - - Original mime type + + Type - src/app/components/document-detail/document-detail.component.html - 140 + src/app/components/common/permissions-select/permissions-select.component.html + 5 - - Archive MD5 checksum + + Add - src/app/components/document-detail/document-detail.component.html - 144 + src/app/components/common/permissions-select/permissions-select.component.html + 7 - - Archive file size + + Change - src/app/components/document-detail/document-detail.component.html - 148 + src/app/components/common/permissions-select/permissions-select.component.html + 8 - - Original document metadata + + Inherited from group - src/app/components/document-detail/document-detail.component.html - 154 + src/app/components/common/permissions-select/permissions-select.component.ts + 61 - - Archived document metadata + + Select - src/app/components/document-detail/document-detail.component.html - 155 + src/app/components/common/select-dialog/select-dialog.component.html + 13 - - - Preview - src/app/components/document-detail/document-detail.component.html - 161 + src/app/components/common/select-dialog/select-dialog.component.ts + 17 - - - Enter Password - src/app/components/document-detail/document-detail.component.html - 177 + src/app/components/document-list/document-list.component.html + 8 + + + Please select an object - src/app/components/document-detail/document-detail.component.html - 228 + src/app/components/common/select-dialog/select-dialog.component.ts + 20 - - Notes + + Share Links - src/app/components/document-detail/document-detail.component.html - 185,186 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 6 - - - Discard - src/app/components/document-detail/document-detail.component.html - 204 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 26 - - Save & next + + No existing links - src/app/components/document-detail/document-detail.component.html - 206 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 10,12 - - Save & close + + Copy - src/app/components/document-detail/document-detail.component.html - 207 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 23 - - An error occurred loading content: + + Share - src/app/components/document-detail/document-detail.component.ts - 253,255 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 28 - - Error retrieving metadata + + Copied! - src/app/components/document-detail/document-detail.component.ts - 398 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 36 - - Error retrieving suggestions. + + Share archive version - src/app/components/document-detail/document-detail.component.ts - 419 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 42 - - Document saved successfully. + + Create - src/app/components/document-detail/document-detail.component.ts - 532 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.html + 55 - src/app/components/document-detail/document-detail.component.ts - 540 + src/app/components/manage/management-list/management-list.component.html + 12 - - - Error saving document - src/app/components/document-detail/document-detail.component.ts - 544 + src/app/components/manage/management-list/management-list.component.html + 12 - src/app/components/document-detail/document-detail.component.ts - 585 + src/app/components/manage/management-list/management-list.component.html + 12 + + + src/app/components/manage/management-list/management-list.component.html + 12 - - Confirm delete + + 1 day - src/app/components/document-detail/document-detail.component.ts - 611 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 19 - src/app/components/manage/management-list/management-list.component.ts - 201 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 90 - - Do you really want to delete document ""? + + 7 days - src/app/components/document-detail/document-detail.component.ts - 612 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 20 - - The files for this document will be deleted permanently. This operation cannot be undone. + + 30 days - src/app/components/document-detail/document-detail.component.ts - 613 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 21 - - Delete document + + Never - src/app/components/document-detail/document-detail.component.ts - 615 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 22 - - Error deleting document + + Error retrieving links - src/app/components/document-detail/document-detail.component.ts - 634 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 74 - - Redo OCR confirm + + days - src/app/components/document-detail/document-detail.component.ts - 654 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 90 + + + Error deleting link - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 498 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 117 - - This operation will permanently redo OCR for this document. + + Error creating link - src/app/components/document-detail/document-detail.component.ts - 655 + src/app/components/common/share-links-dropdown/share-links-dropdown.component.ts + 145 - - This operation cannot be undone. + + Status - src/app/components/document-detail/document-detail.component.ts - 656 + src/app/components/common/toasts/toasts.component.html + 12 + + + Copy Raw Error - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 461 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 500 - - - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 91 - - - src/app/components/manage/settings/settings.component.ts - 801 - - - src/app/components/manage/settings/settings.component.ts - 853 - - - src/app/components/manage/settings/settings.component.ts - 914 - - - src/app/components/manage/settings/settings.component.ts - 976 - - - - Proceed - - src/app/components/document-detail/document-detail.component.ts - 658 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 502 - - - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 93 - - - src/app/components/manage/settings/settings.component.ts - 803 - - - src/app/components/manage/settings/settings.component.ts - 855 - - - src/app/components/manage/settings/settings.component.ts - 916 - - - src/app/components/manage/settings/settings.component.ts - 978 + src/app/components/common/toasts/toasts.component.html + 23 - - Redo OCR operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content. - - src/app/components/document-detail/document-detail.component.ts - 666 - - - - Error executing operation - - src/app/components/document-detail/document-detail.component.ts - 677 - - - - Select: + + Hello , welcome to Paperless-ngx - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 10 + src/app/components/dashboard/dashboard.component.ts + 23 - - Edit: + + Welcome to Paperless-ngx - src/app/components/document-list/bulk-editor/bulk-editor.component.html + src/app/components/dashboard/dashboard.component.ts 25 - - Filter tags + + Show all - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 27 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 3 - src/app/components/document-list/filter-editor/filter-editor.component.html + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html 27 - - Filter correspondents - - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 39 - + + Title - src/app/components/document-list/filter-editor/filter-editor.component.html - 36 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 10 - - - Filter document types - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 50 + src/app/components/document-detail/document-detail.component.html + 85 - src/app/components/document-list/filter-editor/filter-editor.component.html - 44 + src/app/components/document-list/document-list.component.html + 149 - - - Filter storage paths - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 61 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 201 - src/app/components/document-list/filter-editor/filter-editor.component.html - 52 + src/app/services/rest/document.service.ts + 20 - - Include: + + View Preview - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 108 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 19 - - Archived files + + Download - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 112,114 + src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html + 29 - - - Original files - src/app/components/document-list/bulk-editor/bulk-editor.component.html - 118,120 + src/app/components/document-detail/document-detail.component.html + 18 - - - Use formatted filename src/app/components/document-list/bulk-editor/bulk-editor.component.html - 125,127 - - - - Error executing bulk operation - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 185 - - - - "" - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 260 - - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 266 - - - - "" and "" - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 262 - - This is for messages like 'modify "tag1" and "tag2"' - - - and "" - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 270,272 - - this is for messages like 'modify "tag1", "tag2" and "tag3"' - - - Confirm tags assignment - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 287 - - - - This operation will add the tag "" to selected document(s). - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 293 - - - - This operation will add the tags to selected document(s). - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 298,300 - - - - This operation will remove the tag "" from selected document(s). - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 306 - - - - This operation will remove the tags from selected document(s). - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 311,313 - - - - This operation will add the tags and remove the tags on selected document(s). - - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 315,319 + 102 - - - Confirm correspondent assignment - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 356 + src/app/components/document-list/document-card-large/document-card-large.component.html + 64 - - - This operation will assign the correspondent "" to selected document(s). - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 358 + src/app/components/document-list/document-card-small/document-card-small.component.html + 99 - - This operation will remove the correspondent from selected document(s). + + Statistics - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 360 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 1 - - Confirm document type assignment + + Go to inbox - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 394 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 4 - - This operation will assign the document type "" to selected document(s). + + Documents in inbox - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 396 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 5 - - This operation will remove the document type from selected document(s). + + Go to documents - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 398 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 8 - - Confirm storage path assignment + + Total documents - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 432 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 9 - - This operation will assign the storage path "" to selected document(s). + + Total characters - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 434 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.html + 13 - - This operation will remove the storage path from selected document(s). + + Other - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 436 + src/app/components/dashboard/widgets/statistics-widget/statistics-widget.component.ts + 55 - - Delete confirm + + Upload new documents - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 459 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 1 - - This operation will permanently delete selected document(s). + + Dismiss completed - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 460 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 4 + This button dismisses all status messages about processed documents on the dashboard (failed and successful) - - Delete document(s) + + Drop documents here or - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 463 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 - - This operation will permanently redo OCR for selected document(s). + + Browse files - src/app/components/document-list/bulk-editor/bulk-editor.component.ts - 499 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 13 - - Filter by correspondent - - src/app/components/document-list/document-card-large/document-card-large.component.html - 20 - + + {VAR_PLURAL, plural, =1 {One more document} other { more documents}} - src/app/components/document-list/document-list.component.html - 206 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html + 25 + This is shown as a summary line when there are more than 5 document in the processing pipeline. - - Filter by tag - - src/app/components/document-list/document-card-large/document-card-large.component.html - 24 - + + Processing: - src/app/components/document-list/document-list.component.html - 211 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 39 - - View notes + + Failed: - src/app/components/document-list/document-card-large/document-card-large.component.html - 70 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 42 - - Notes + + Added: - src/app/components/document-list/document-card-large/document-card-large.component.html - 74 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 45 - - Filter by document type + + , - src/app/components/document-list/document-card-large/document-card-large.component.html - 76 + src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.ts + 48 - src/app/components/document-list/document-list.component.html - 227 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 268 + this string is used to separate processing, failed and added on the file upload widget - - Filter by storage path + + Paperless-ngx is running! - src/app/components/document-list/document-card-large/document-card-large.component.html - 83 + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 2 + + + You're ready to start uploading documents! Explore the various features of this web app on your own, or start a quick tour using the button below. - src/app/components/document-list/document-list.component.html - 232 + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 3 - - Created: + + More detail on how to use and configure Paperless-ngx is always available in the documentation. - src/app/components/document-list/document-card-large/document-card-large.component.html - 98,99 + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 4 + + + Thanks for being a part of the Paperless-ngx community! - src/app/components/document-list/document-card-small/document-card-small.component.html - 56,57 + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 7 - - Added: + + Start the tour - src/app/components/document-list/document-card-large/document-card-large.component.html - 99,100 + src/app/components/dashboard/widgets/welcome-widget/welcome-widget.component.html + 8 + + + Searching document with asn - src/app/components/document-list/document-card-small/document-card-small.component.html - 57,58 + src/app/components/document-asn/document-asn.component.html + 1 - - Modified: + + Page - src/app/components/document-list/document-card-large/document-card-large.component.html - 100,101 + src/app/components/document-detail/document-detail.component.html + 3 - src/app/components/document-list/document-card-small/document-card-small.component.html - 58,59 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 15 - - Score: + + of - src/app/components/document-list/document-card-large/document-card-large.component.html - 116 + src/app/components/document-detail/document-detail.component.html + 5,6 - - Toggle tag filter + + Download original - src/app/components/document-list/document-card-small/document-card-small.component.html - 14 + src/app/components/document-detail/document-detail.component.html + 24 - - Toggle correspondent filter + + Redo OCR - src/app/components/document-list/document-card-small/document-card-small.component.html - 32 + src/app/components/document-detail/document-detail.component.html + 40 - - - Toggle document type filter - src/app/components/document-list/document-card-small/document-card-small.component.html - 39 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 89 - - Toggle storage path filter + + More like this - src/app/components/document-list/document-card-small/document-card-small.component.html + src/app/components/document-detail/document-detail.component.html 46 - - - Select none - src/app/components/document-list/document-list.component.html - 11 + src/app/components/document-list/document-card-large/document-card-large.component.html + 44 - - Select page + + Close - src/app/components/document-list/document-list.component.html - 12 + src/app/components/document-detail/document-detail.component.html + 53 - - - Select all - src/app/components/document-list/document-list.component.html - 13 + src/app/guards/dirty-saved-view.guard.ts + 37 - - Sort + + Previous - src/app/components/document-list/document-list.component.html - 38 + src/app/components/document-detail/document-detail.component.html + 60 - - Views - - src/app/components/document-list/document-list.component.html - 64 - + + Details - src/app/components/manage/settings/settings.component.html - 275 + src/app/components/document-detail/document-detail.component.html + 82 - - Save "" + + Archive serial number - src/app/components/document-list/document-list.component.html - 76 + src/app/components/document-detail/document-detail.component.html + 86 - - Save as... + + Date created - src/app/components/document-list/document-list.component.html - 78 + src/app/components/document-detail/document-detail.component.html + 87 - - {VAR_PLURAL, plural, =1 {Selected of one document} other {Selected of documents}} + + Correspondent - src/app/components/document-list/document-list.component.html - 97 + src/app/components/document-detail/document-detail.component.html + 89 - - - {VAR_PLURAL, plural, =1 {One document} other { documents}} - src/app/components/document-list/document-list.component.html - 99 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 38 - - - (filtered) src/app/components/document-list/document-list.component.html - 99 + 142 - - - Reset filters - src/app/components/document-list/document-list.component.html - 104 + src/app/components/document-list/filter-editor/filter-editor.component.html + 35 - src/app/components/document-list/filter-editor/filter-editor.component.html - 84 + src/app/services/rest/document.service.ts + 19 - - Error while loading documents + + Document type - src/app/components/document-list/document-list.component.html - 117 + src/app/components/document-detail/document-detail.component.html + 91 - - - Sort by ASN - src/app/components/document-list/document-list.component.html - 131 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 49 - - - ASN src/app/components/document-list/document-list.component.html - 135 + 170 - src/app/components/document-list/filter-editor/filter-editor.component.ts - 206 + src/app/components/document-list/filter-editor/filter-editor.component.html + 43 src/app/services/rest/document.service.ts - 18 - - - - Sort by correspondent - - src/app/components/document-list/document-list.component.html - 138 + 21 - - Sort by title + + Storage path - src/app/components/document-list/document-list.component.html - 145 - - - - Sort by owner + src/app/components/document-detail/document-detail.component.html + 93 + - src/app/components/document-list/document-list.component.html - 152 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 60 - - - Owner src/app/components/document-list/document-list.component.html - 156 + 177 - src/app/services/rest/document.service.ts - 26 + src/app/components/document-list/filter-editor/filter-editor.component.html + 51 - - Sort by notes + + Default - src/app/components/document-list/document-list.component.html - 159 + src/app/components/document-detail/document-detail.component.html + 94 - - Notes + + Content - src/app/components/document-list/document-list.component.html - 163 + src/app/components/document-detail/document-detail.component.html + 101 + + + Metadata - src/app/components/manage/settings/settings.component.html - 235 + src/app/components/document-detail/document-detail.component.html + 110 - src/app/services/rest/document.service.ts - 25 + src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts + 17 - - Sort by document type + + Date modified - src/app/components/document-list/document-list.component.html - 166 + src/app/components/document-detail/document-detail.component.html + 116 - - Sort by storage path + + Date added - src/app/components/document-list/document-list.component.html - 173 + src/app/components/document-detail/document-detail.component.html + 120 - - Sort by created date + + Media filename - src/app/components/document-list/document-list.component.html - 180 + src/app/components/document-detail/document-detail.component.html + 124 - - Sort by added date + + Original filename - src/app/components/document-list/document-list.component.html - 187 + src/app/components/document-detail/document-detail.component.html + 128 - - Added + + Original MD5 checksum - src/app/components/document-list/document-list.component.html - 191 + src/app/components/document-detail/document-detail.component.html + 132 + + + Original file size - src/app/components/document-list/filter-editor/filter-editor.component.html - 68 + src/app/components/document-detail/document-detail.component.html + 136 + + + Original mime type - src/app/services/rest/document.service.ts - 23 + src/app/components/document-detail/document-detail.component.html + 140 - - Edit document + + Archive MD5 checksum - src/app/components/document-list/document-list.component.html - 210 + src/app/components/document-detail/document-detail.component.html + 144 - - View "" saved successfully. + + Archive file size - src/app/components/document-list/document-list.component.ts - 207 + src/app/components/document-detail/document-detail.component.html + 148 - - View "" created successfully. + + Original document metadata - src/app/components/document-list/document-list.component.ts - 248 + src/app/components/document-detail/document-detail.component.html + 154 - - Correspondent: + + Archived document metadata - src/app/components/document-list/filter-editor/filter-editor.component.ts - 118,120 + src/app/components/document-detail/document-detail.component.html + 155 - - Without correspondent + + Preview - src/app/components/document-list/filter-editor/filter-editor.component.ts - 122 + src/app/components/document-detail/document-detail.component.html + 161 - - Document type: + + Enter Password - src/app/components/document-list/filter-editor/filter-editor.component.ts - 128,130 + src/app/components/document-detail/document-detail.component.html + 177 - - - Without document type - src/app/components/document-list/filter-editor/filter-editor.component.ts - 132 + src/app/components/document-detail/document-detail.component.html + 228 - - Storage path: + + Notes - src/app/components/document-list/filter-editor/filter-editor.component.ts - 138,140 + src/app/components/document-detail/document-detail.component.html + 185,186 - - Without storage path + + Discard - src/app/components/document-list/filter-editor/filter-editor.component.ts - 142 + src/app/components/document-detail/document-detail.component.html + 204 - - Tag: + + Save & next - src/app/components/document-list/filter-editor/filter-editor.component.ts - 146,147 + src/app/components/document-detail/document-detail.component.html + 206 - - Without any tag + + Save & close - src/app/components/document-list/filter-editor/filter-editor.component.ts - 151 + src/app/components/document-detail/document-detail.component.html + 207 - - Title: + + An error occurred loading content: - src/app/components/document-list/filter-editor/filter-editor.component.ts - 155 + src/app/components/document-detail/document-detail.component.ts + 253,255 - - ASN: + + Error retrieving metadata - src/app/components/document-list/filter-editor/filter-editor.component.ts - 158 + src/app/components/document-detail/document-detail.component.ts + 398 - - Owner: + + Error retrieving suggestions. - src/app/components/document-list/filter-editor/filter-editor.component.ts - 161 + src/app/components/document-detail/document-detail.component.ts + 419 - - Owner not in: + + Document saved successfully. - src/app/components/document-list/filter-editor/filter-editor.component.ts - 164 + src/app/components/document-detail/document-detail.component.ts + 532 - - - Without an owner - src/app/components/document-list/filter-editor/filter-editor.component.ts - 167 + src/app/components/document-detail/document-detail.component.ts + 540 - - Title & content + + Error saving document - src/app/components/document-list/filter-editor/filter-editor.component.ts - 204 + src/app/components/document-detail/document-detail.component.ts + 544 + + + src/app/components/document-detail/document-detail.component.ts + 585 - - Advanced search + + Confirm delete - src/app/components/document-list/filter-editor/filter-editor.component.ts - 209 + src/app/components/document-detail/document-detail.component.ts + 611 + + + src/app/components/manage/management-list/management-list.component.ts + 201 - - More like + + Do you really want to delete document ""? - src/app/components/document-list/filter-editor/filter-editor.component.ts - 215 + src/app/components/document-detail/document-detail.component.ts + 612 - - equals + + The files for this document will be deleted permanently. This operation cannot be undone. - src/app/components/document-list/filter-editor/filter-editor.component.ts - 234 + src/app/components/document-detail/document-detail.component.ts + 613 - - is empty + + Delete document - src/app/components/document-list/filter-editor/filter-editor.component.ts - 238 + src/app/components/document-detail/document-detail.component.ts + 615 - - is not empty + + Error deleting document - src/app/components/document-list/filter-editor/filter-editor.component.ts - 242 + src/app/components/document-detail/document-detail.component.ts + 634 - - greater than + + Redo OCR confirm - src/app/components/document-list/filter-editor/filter-editor.component.ts - 246 + src/app/components/document-detail/document-detail.component.ts + 654 - - - less than - src/app/components/document-list/filter-editor/filter-editor.component.ts - 250 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 498 - - Save current view + + This operation will permanently redo OCR for this document. - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 3 + src/app/components/document-detail/document-detail.component.ts + 655 - - Show in sidebar + + Redo OCR operation will begin in the background. Close and re-open or reload this document after the operation has completed to see new content. - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 9 + src/app/components/document-detail/document-detail.component.ts + 666 + + + Error executing operation - src/app/components/manage/settings/settings.component.html - 292 + src/app/components/document-detail/document-detail.component.ts + 677 - - Show on dashboard + + Select: - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + src/app/components/document-list/bulk-editor/bulk-editor.component.html 10 - - src/app/components/manage/settings/settings.component.html - 288 - - - Filter rules error occurred while saving this view + + Edit: - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 12 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 25 - - The error returned was + + Filter tags - src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html - 13 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 27 - - - Enter note - src/app/components/document-notes/document-notes.component.html - 4 + src/app/components/document-list/filter-editor/filter-editor.component.html + 27 - - Please enter a note. + + Filter correspondents - src/app/components/document-notes/document-notes.component.html - 5,7 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 39 - - - Add note - src/app/components/document-notes/document-notes.component.html - 11 + src/app/components/document-list/filter-editor/filter-editor.component.html + 36 - - Delete note + + Filter document types - src/app/components/document-notes/document-notes.component.html - 21 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 50 - src/app/components/document-notes/document-notes.component.html - 25 + src/app/components/document-list/filter-editor/filter-editor.component.html + 44 - - Error saving note + + Filter storage paths - src/app/components/document-notes/document-notes.component.ts - 66 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 61 - - - Error deleting note - src/app/components/document-notes/document-notes.component.ts - 80 + src/app/components/document-list/filter-editor/filter-editor.component.html + 52 - - Add Template + + Include: - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 6 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 108 - - Document Sources + + Archived files - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 15 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 112,114 - - No templates defined. + + Original files - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.html - 33 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 118,120 - - Saved template "". + + Use formatted filename - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 73 + src/app/components/document-list/bulk-editor/bulk-editor.component.html + 125,127 - - Error saving template. + + Error executing bulk operation - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 81 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 185 - - Confirm delete template + + "" - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 89 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 260 - - - This operation will permanently delete this template. - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 90 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 266 - - Deleted template + + "" and "" - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 99 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 262 + This is for messages like 'modify "tag1" and "tag2"' - - Error deleting template. + + and "" - src/app/components/manage/consumption-templates-list/consumption-templates-list.component.ts - 104 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 270,272 + this is for messages like 'modify "tag1", "tag2" and "tag3"' - - correspondent + + Confirm tags assignment - src/app/components/manage/correspondent-list/correspondent-list.component.ts - 39 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 287 - - correspondents + + This operation will add the tag "" to selected document(s). - src/app/components/manage/correspondent-list/correspondent-list.component.ts - 40 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 293 - - Last used + + This operation will add the tags to selected document(s). - src/app/components/manage/correspondent-list/correspondent-list.component.ts - 45 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 298,300 - - Do you really want to delete the correspondent ""? + + This operation will remove the tag "" from selected document(s). - src/app/components/manage/correspondent-list/correspondent-list.component.ts - 67 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 306 - - document type + + This operation will remove the tags from selected document(s). - src/app/components/manage/document-type-list/document-type-list.component.ts - 36 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 311,313 - - document types + + This operation will add the tags and remove the tags on selected document(s). + + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 315,319 + + + + Confirm correspondent assignment - src/app/components/manage/document-type-list/document-type-list.component.ts - 37 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 356 - - Do you really want to delete the document type ""? + + This operation will assign the correspondent "" to selected document(s). - src/app/components/manage/document-type-list/document-type-list.component.ts - 44 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 358 - - Clear selection + + This operation will remove the correspondent from selected document(s). - src/app/components/manage/management-list/management-list.component.html - 5 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 360 + + + Confirm document type assignment - src/app/components/manage/management-list/management-list.component.html - 5 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 394 + + + This operation will assign the document type "" to selected document(s). - src/app/components/manage/management-list/management-list.component.html - 5 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 396 + + + This operation will remove the document type from selected document(s). - src/app/components/manage/management-list/management-list.component.html - 5 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 398 + + + Confirm storage path assignment - src/app/components/manage/tasks/tasks.component.html - 6 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 432 - - Filter by: + + This operation will assign the storage path "" to selected document(s). - src/app/components/manage/management-list/management-list.component.html - 18 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 434 + + + This operation will remove the storage path from selected document(s). - src/app/components/manage/management-list/management-list.component.html - 18 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 436 + + + Delete confirm - src/app/components/manage/management-list/management-list.component.html - 18 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 459 + + + This operation will permanently delete selected document(s). - src/app/components/manage/management-list/management-list.component.html - 18 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 460 - - Matching + + Delete document(s) - src/app/components/manage/management-list/management-list.component.html - 36 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 463 + + + This operation will permanently redo OCR for selected document(s). - src/app/components/manage/management-list/management-list.component.html - 36 + src/app/components/document-list/bulk-editor/bulk-editor.component.ts + 499 + + + Filter by correspondent - src/app/components/manage/management-list/management-list.component.html - 36 + src/app/components/document-list/document-card-large/document-card-large.component.html + 20 - src/app/components/manage/management-list/management-list.component.html - 36 + src/app/components/document-list/document-list.component.html + 206 - - Document count + + Filter by tag - src/app/components/manage/management-list/management-list.component.html - 37 + src/app/components/document-list/document-card-large/document-card-large.component.html + 24 - src/app/components/manage/management-list/management-list.component.html - 37 + src/app/components/document-list/document-list.component.html + 211 + + + View notes - src/app/components/manage/management-list/management-list.component.html - 37 + src/app/components/document-list/document-card-large/document-card-large.component.html + 70 + + + Notes - src/app/components/manage/management-list/management-list.component.html - 37 + src/app/components/document-list/document-card-large/document-card-large.component.html + 74 - - Filter Documents + + Filter by document type - src/app/components/manage/management-list/management-list.component.html - 72 + src/app/components/document-list/document-card-large/document-card-large.component.html + 76 - src/app/components/manage/management-list/management-list.component.html - 72 + src/app/components/document-list/document-list.component.html + 227 + + + Filter by storage path - src/app/components/manage/management-list/management-list.component.html - 72 + src/app/components/document-list/document-card-large/document-card-large.component.html + 83 - src/app/components/manage/management-list/management-list.component.html - 72 + src/app/components/document-list/document-list.component.html + 232 - - {VAR_PLURAL, plural, =1 {One } other { total }} + + Created: - src/app/components/manage/management-list/management-list.component.html - 102 + src/app/components/document-list/document-card-large/document-card-large.component.html + 98,99 - src/app/components/manage/management-list/management-list.component.html - 102 + src/app/components/document-list/document-card-small/document-card-small.component.html + 56,57 + + + Added: - src/app/components/manage/management-list/management-list.component.html - 102 + src/app/components/document-list/document-card-large/document-card-large.component.html + 99,100 - src/app/components/manage/management-list/management-list.component.html - 102 + src/app/components/document-list/document-card-small/document-card-small.component.html + 57,58 - - Automatic + + Modified: - src/app/components/manage/management-list/management-list.component.ts - 113 + src/app/components/document-list/document-card-large/document-card-large.component.html + 100,101 - src/app/data/matching-model.ts - 15 + src/app/components/document-list/document-card-small/document-card-small.component.html + 58,59 - - None - - src/app/components/manage/management-list/management-list.component.ts - 115 - + + Score: - src/app/data/matching-model.ts - 45 + src/app/components/document-list/document-card-large/document-card-large.component.html + 116 - - Successfully created . + + Toggle tag filter - src/app/components/manage/management-list/management-list.component.ts - 158 + src/app/components/document-list/document-card-small/document-card-small.component.html + 14 - - Error occurred while creating . + + Toggle correspondent filter - src/app/components/manage/management-list/management-list.component.ts - 163 + src/app/components/document-list/document-card-small/document-card-small.component.html + 32 - - Successfully updated . + + Toggle document type filter - src/app/components/manage/management-list/management-list.component.ts - 178 + src/app/components/document-list/document-card-small/document-card-small.component.html + 39 - - Error occurred while saving . + + Toggle storage path filter - src/app/components/manage/management-list/management-list.component.ts - 183 + src/app/components/document-list/document-card-small/document-card-small.component.html + 46 - - Associated documents will not be deleted. + + Select none - src/app/components/manage/management-list/management-list.component.ts - 203 + src/app/components/document-list/document-list.component.html + 11 - - Error while deleting element + + Select page - src/app/components/manage/management-list/management-list.component.ts - 219 + src/app/components/document-list/document-list.component.html + 12 - - Permissions updated successfully + + Select all - src/app/components/manage/management-list/management-list.component.ts - 293 + src/app/components/document-list/document-list.component.html + 13 - - Error updating permissions + + Sort - src/app/components/manage/management-list/management-list.component.ts - 300 + src/app/components/document-list/document-list.component.html + 38 + + + Save "" - src/app/components/manage/settings/settings.component.ts - 1020 + src/app/components/document-list/document-list.component.html + 76 - - Start tour + + Save as... - src/app/components/manage/settings/settings.component.html - 2 + src/app/components/document-list/document-list.component.html + 78 - - Open Django Admin + + {VAR_PLURAL, plural, =1 {Selected of one document} other {Selected of documents}} - src/app/components/manage/settings/settings.component.html - 4 + src/app/components/document-list/document-list.component.html + 97 - - General + + {VAR_PLURAL, plural, =1 {One document} other { documents}} - src/app/components/manage/settings/settings.component.html - 15 + src/app/components/document-list/document-list.component.html + 99 - - Appearance + + (filtered) - src/app/components/manage/settings/settings.component.html - 18 + src/app/components/document-list/document-list.component.html + 99 - - Display language + + Reset filters - src/app/components/manage/settings/settings.component.html - 22 + src/app/components/document-list/document-list.component.html + 104 - - - You need to reload the page after applying a new language. - src/app/components/manage/settings/settings.component.html - 30 + src/app/components/document-list/filter-editor/filter-editor.component.html + 84 - - Date display + + Error while loading documents - src/app/components/manage/settings/settings.component.html - 37 + src/app/components/document-list/document-list.component.html + 117 - - Date format + + Sort by ASN - src/app/components/manage/settings/settings.component.html - 50 + src/app/components/document-list/document-list.component.html + 131 - - Short: + + ASN - src/app/components/manage/settings/settings.component.html - 56,57 + src/app/components/document-list/document-list.component.html + 135 - - - Medium: - src/app/components/manage/settings/settings.component.html - 60,61 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 206 - - - Long: - src/app/components/manage/settings/settings.component.html - 64,65 + src/app/services/rest/document.service.ts + 18 - - Items per page + + Sort by correspondent - src/app/components/manage/settings/settings.component.html - 72 + src/app/components/document-list/document-list.component.html + 138 - - Document editor + + Sort by title - src/app/components/manage/settings/settings.component.html - 88 + src/app/components/document-list/document-list.component.html + 145 - - Use PDF viewer provided by the browser + + Sort by owner - src/app/components/manage/settings/settings.component.html - 92 + src/app/components/document-list/document-list.component.html + 152 - - This is usually faster for displaying large PDF documents, but it might not work on some browsers. + + Owner - src/app/components/manage/settings/settings.component.html - 92 + src/app/components/document-list/document-list.component.html + 156 - - - Sidebar - src/app/components/manage/settings/settings.component.html - 99 + src/app/services/rest/document.service.ts + 26 - - Use 'slim' sidebar (icons only) + + Sort by notes - src/app/components/manage/settings/settings.component.html - 103 + src/app/components/document-list/document-list.component.html + 159 - - Dark mode + + Sort by document type - src/app/components/manage/settings/settings.component.html - 110 + src/app/components/document-list/document-list.component.html + 166 - - Use system settings + + Sort by storage path - src/app/components/manage/settings/settings.component.html - 113 + src/app/components/document-list/document-list.component.html + 173 - - Enable dark mode + + Sort by created date - src/app/components/manage/settings/settings.component.html - 114 + src/app/components/document-list/document-list.component.html + 180 - - Invert thumbnails in dark mode + + Sort by added date - src/app/components/manage/settings/settings.component.html - 115 + src/app/components/document-list/document-list.component.html + 187 - - Theme Color + + Added - src/app/components/manage/settings/settings.component.html - 121 + src/app/components/document-list/document-list.component.html + 191 - - - Reset - src/app/components/manage/settings/settings.component.html - 130 + src/app/components/document-list/filter-editor/filter-editor.component.html + 68 + + + src/app/services/rest/document.service.ts + 23 - - Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI + + Edit document - src/app/components/manage/settings/settings.component.html - 139,141 + src/app/components/document-list/document-list.component.html + 210 - - Default Owner + + View "" saved successfully. - src/app/components/manage/settings/settings.component.html - 146 + src/app/components/document-list/document-list.component.ts + 207 - - Default View Permissions + + View "" created successfully. - src/app/components/manage/settings/settings.component.html - 155 + src/app/components/document-list/document-list.component.ts + 248 - - Default Edit Permissions + + Correspondent: - src/app/components/manage/settings/settings.component.html - 182 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 118,120 - - Update checking + + Without correspondent - src/app/components/manage/settings/settings.component.html - 211 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 122 - - Update checking works by pinging the public GitHub API for the latest release to determine whether a new version is available. Actual updating of the app must still be performed manually. + + Document type: - src/app/components/manage/settings/settings.component.html - 215,218 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 128,130 - - No tracking data is collected by the app in any way. + + Without document type - src/app/components/manage/settings/settings.component.html - 220,222 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 132 - - Enable update checking + + Storage path: - src/app/components/manage/settings/settings.component.html - 222 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 138,140 - - Note that for users of third-party containers e.g. linuxserver.io this notification may be 'ahead' of the current third-party release. + + Without storage path - src/app/components/manage/settings/settings.component.html - 222 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 142 - - Bulk editing + + Tag: - src/app/components/manage/settings/settings.component.html - 226 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 146,147 - - Show confirmation dialogs + + Without any tag - src/app/components/manage/settings/settings.component.html - 230 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 151 - - Deleting documents will always ask for confirmation. + + Title: - src/app/components/manage/settings/settings.component.html - 230 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 155 - - Apply on close + + ASN: - src/app/components/manage/settings/settings.component.html - 231 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 158 - - Enable notes + + Owner: - src/app/components/manage/settings/settings.component.html - 239 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 161 - - Notifications + + Owner not in: - src/app/components/manage/settings/settings.component.html - 247 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 164 - - Document processing + + Without an owner - src/app/components/manage/settings/settings.component.html - 250 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 167 - - Show notifications when new documents are detected + + Title & content - src/app/components/manage/settings/settings.component.html - 254 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 204 - - Show notifications when document processing completes successfully + + Advanced search - src/app/components/manage/settings/settings.component.html - 255 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 209 - - Show notifications when document processing fails + + More like - src/app/components/manage/settings/settings.component.html - 256 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 215 - - Suppress notifications on dashboard + + equals - src/app/components/manage/settings/settings.component.html - 257 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 234 - - This will suppress all messages about document processing status on the dashboard. + + is empty - src/app/components/manage/settings/settings.component.html - 257 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 238 - - Show warning when closing saved views with unsaved changes + + is not empty - src/app/components/manage/settings/settings.component.html - 271 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 242 - -  Appears on + + greater than - src/app/components/manage/settings/settings.component.html - 285,286 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 246 - - No saved views defined. + + less than - src/app/components/manage/settings/settings.component.html - 302 + src/app/components/document-list/filter-editor/filter-editor.component.ts + 250 - - Mail + + Save current view - src/app/components/manage/settings/settings.component.html - 315 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 3 - - Mail accounts + + Filter rules error occurred while saving this view - src/app/components/manage/settings/settings.component.html - 321 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 12 - - Add Account + + The error returned was - src/app/components/manage/settings/settings.component.html - 326 + src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html + 13 - - Server + + Enter note - src/app/components/manage/settings/settings.component.html - 334 + src/app/components/document-notes/document-notes.component.html + 4 - - No mail accounts defined. + + Please enter a note. - src/app/components/manage/settings/settings.component.html - 353 + src/app/components/document-notes/document-notes.component.html + 5,7 - - Mail rules + + Add note - src/app/components/manage/settings/settings.component.html - 359 + src/app/components/document-notes/document-notes.component.html + 11 - - Add Rule + + Delete note - src/app/components/manage/settings/settings.component.html - 364 + src/app/components/document-notes/document-notes.component.html + 21 - - - No mail rules defined. - src/app/components/manage/settings/settings.component.html - 391 + src/app/components/document-notes/document-notes.component.html + 25 - - Users & Groups + + Error saving note - src/app/components/manage/settings/settings.component.html - 405 + src/app/components/document-notes/document-notes.component.ts + 66 - - Add User + + Error deleting note - src/app/components/manage/settings/settings.component.html - 415 + src/app/components/document-notes/document-notes.component.ts + 80 - - Add Group + + Add Template - src/app/components/manage/settings/settings.component.html - 450 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 6 - - Error retrieving groups + + Document Sources - src/app/components/manage/settings/settings.component.ts - 304 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 16 - - Error retrieving mail rules + + No templates defined. - src/app/components/manage/settings/settings.component.ts - 328 + src/app/components/manage/consumption-templates/consumption-templates.component.html + 36 - - Error retrieving mail accounts + + Saved template "". - src/app/components/manage/settings/settings.component.ts - 336 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 73 - - Error retrieving users + + Error saving template. - src/app/components/manage/settings/settings.component.ts - 354 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 81 - - Saved view "" deleted. + + Confirm delete template - src/app/components/manage/settings/settings.component.ts - 558 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 89 - - Settings saved + + This operation will permanently delete this template. - src/app/components/manage/settings/settings.component.ts - 680 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 90 - - Settings were saved successfully. + + Deleted template - src/app/components/manage/settings/settings.component.ts - 681 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 99 - - Settings were saved successfully. Reload is required to apply some changes. + + Error deleting template. - src/app/components/manage/settings/settings.component.ts - 685 + src/app/components/manage/consumption-templates/consumption-templates.component.ts + 104 - - Reload now + + correspondent - src/app/components/manage/settings/settings.component.ts - 686 + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 39 - - Use system language + + correspondents - src/app/components/manage/settings/settings.component.ts - 704 + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 40 - - Use date format of display language + + Last used - src/app/components/manage/settings/settings.component.ts - 711 + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 45 - - Error while storing settings on server. + + Do you really want to delete the correspondent ""? - src/app/components/manage/settings/settings.component.ts - 731 + src/app/components/manage/correspondent-list/correspondent-list.component.ts + 67 - - Password has been changed, you will be logged out momentarily. + + document type - src/app/components/manage/settings/settings.component.ts - 773 + src/app/components/manage/document-type-list/document-type-list.component.ts + 36 - - Saved user "". + + document types - src/app/components/manage/settings/settings.component.ts - 780 + src/app/components/manage/document-type-list/document-type-list.component.ts + 37 - - Error saving user. + + Do you really want to delete the document type ""? - src/app/components/manage/settings/settings.component.ts - 791 + src/app/components/manage/document-type-list/document-type-list.component.ts + 44 - - Confirm delete user account + + Mail Settings - src/app/components/manage/settings/settings.component.ts - 799 + src/app/components/manage/mail/mail.component.html + 1 - - This operation will permanently delete this user account. + + Mail accounts - src/app/components/manage/settings/settings.component.ts - 800 + src/app/components/manage/mail/mail.component.html + 6 - - Deleted user + + Add Account - src/app/components/manage/settings/settings.component.ts - 809 + src/app/components/manage/mail/mail.component.html + 11 - - Error deleting user. + + Server - src/app/components/manage/settings/settings.component.ts - 816 + src/app/components/manage/mail/mail.component.html + 19 - - Saved group "". + + No mail accounts defined. - src/app/components/manage/settings/settings.component.ts - 834 + src/app/components/manage/mail/mail.component.html + 38 - - Error saving group. + + Mail rules - src/app/components/manage/settings/settings.component.ts - 843 + src/app/components/manage/mail/mail.component.html + 44 - - - Confirm delete user group + + + Add Rule - src/app/components/manage/settings/settings.component.ts - 851 + src/app/components/manage/mail/mail.component.html + 49 - - This operation will permanently delete this user group. + + No mail rules defined. - src/app/components/manage/settings/settings.component.ts - 852 + src/app/components/manage/mail/mail.component.html + 76 - - Deleted group + + Error retrieving mail accounts - src/app/components/manage/settings/settings.component.ts - 861 + src/app/components/manage/mail/mail.component.ts + 56 - - Error deleting group. + + Error retrieving mail rules - src/app/components/manage/settings/settings.component.ts - 868 + src/app/components/manage/mail/mail.component.ts + 70 Saved account "". - src/app/components/manage/settings/settings.component.ts - 891 + src/app/components/manage/mail/mail.component.ts + 92 Error saving account. - src/app/components/manage/settings/settings.component.ts - 904 + src/app/components/manage/mail/mail.component.ts + 104 Confirm delete mail account - src/app/components/manage/settings/settings.component.ts - 912 + src/app/components/manage/mail/mail.component.ts + 112 This operation will permanently delete this mail account. - src/app/components/manage/settings/settings.component.ts - 913 + src/app/components/manage/mail/mail.component.ts + 113 Deleted mail account - src/app/components/manage/settings/settings.component.ts - 922 + src/app/components/manage/mail/mail.component.ts + 122 Error deleting mail account. - src/app/components/manage/settings/settings.component.ts - 933 + src/app/components/manage/mail/mail.component.ts + 132 Saved rule "". - src/app/components/manage/settings/settings.component.ts - 953 + src/app/components/manage/mail/mail.component.ts + 152 Error saving rule. - src/app/components/manage/settings/settings.component.ts - 966 + src/app/components/manage/mail/mail.component.ts + 163 Confirm delete mail rule - src/app/components/manage/settings/settings.component.ts - 974 + src/app/components/manage/mail/mail.component.ts + 171 This operation will permanently delete this mail rule. - src/app/components/manage/settings/settings.component.ts - 975 + src/app/components/manage/mail/mail.component.ts + 172 Deleted mail rule - src/app/components/manage/settings/settings.component.ts - 984 + src/app/components/manage/mail/mail.component.ts + 181 Error deleting mail rule. - src/app/components/manage/settings/settings.component.ts - 994 + src/app/components/manage/mail/mail.component.ts + 190 Permissions updated - src/app/components/manage/settings/settings.component.ts - 1016 + src/app/components/manage/mail/mail.component.ts + 212 - - storage path + + Error updating permissions - src/app/components/manage/storage-path-list/storage-path-list.component.ts - 36 + src/app/components/manage/mail/mail.component.ts + 216 - - - storage paths - src/app/components/manage/storage-path-list/storage-path-list.component.ts - 37 + src/app/components/manage/management-list/management-list.component.ts + 300 - - Do you really want to delete the storage path ""? + + Filter by: - src/app/components/manage/storage-path-list/storage-path-list.component.ts - 52 + src/app/components/manage/management-list/management-list.component.html + 18 + + + src/app/components/manage/management-list/management-list.component.html + 18 + + + src/app/components/manage/management-list/management-list.component.html + 18 + + + src/app/components/manage/management-list/management-list.component.html + 18 - - tag + + Matching - src/app/components/manage/tag-list/tag-list.component.ts + src/app/components/manage/management-list/management-list.component.html + 36 + + + src/app/components/manage/management-list/management-list.component.html + 36 + + + src/app/components/manage/management-list/management-list.component.html + 36 + + + src/app/components/manage/management-list/management-list.component.html 36 - - tags + + Document count - src/app/components/manage/tag-list/tag-list.component.ts + src/app/components/manage/management-list/management-list.component.html 37 - - - Do you really want to delete the tag ""? - src/app/components/manage/tag-list/tag-list.component.ts - 53 + src/app/components/manage/management-list/management-list.component.html + 37 - - - Refresh - src/app/components/manage/tasks/tasks.component.html - 20 + src/app/components/manage/management-list/management-list.component.html + 37 - - - Results - src/app/components/manage/tasks/tasks.component.html - 42 + src/app/components/manage/management-list/management-list.component.html + 37 - - click for full output + + Filter Documents - src/app/components/manage/tasks/tasks.component.html - 66 + src/app/components/manage/management-list/management-list.component.html + 72 + + + src/app/components/manage/management-list/management-list.component.html + 72 + + + src/app/components/manage/management-list/management-list.component.html + 72 + + + src/app/components/manage/management-list/management-list.component.html + 72 - - Dismiss + + {VAR_PLURAL, plural, =1 {One } other { total }} - src/app/components/manage/tasks/tasks.component.html - 81 + src/app/components/manage/management-list/management-list.component.html + 102 - src/app/components/manage/tasks/tasks.component.ts - 64 + src/app/components/manage/management-list/management-list.component.html + 102 + + + src/app/components/manage/management-list/management-list.component.html + 102 + + + src/app/components/manage/management-list/management-list.component.html + 102 - - Open Document + + Automatic - src/app/components/manage/tasks/tasks.component.html - 87 + src/app/components/manage/management-list/management-list.component.ts + 113 + + + src/app/data/matching-model.ts + 15 - - {VAR_PLURAL, plural, =1 {One task} other { total tasks}} + + None - src/app/components/manage/tasks/tasks.component.html - 103 + src/app/components/manage/management-list/management-list.component.ts + 115 + + + src/app/data/matching-model.ts + 45 - - Failed + + Successfully created . - src/app/components/manage/tasks/tasks.component.html - 110 + src/app/components/manage/management-list/management-list.component.ts + 158 - - Complete + + Error occurred while creating . - src/app/components/manage/tasks/tasks.component.html - 116 + src/app/components/manage/management-list/management-list.component.ts + 163 - - Started + + Successfully updated . - src/app/components/manage/tasks/tasks.component.html - 122 + src/app/components/manage/management-list/management-list.component.ts + 178 - - Queued + + Error occurred while saving . - src/app/components/manage/tasks/tasks.component.html - 128 + src/app/components/manage/management-list/management-list.component.ts + 183 - - Dismiss selected + + Associated documents will not be deleted. - src/app/components/manage/tasks/tasks.component.ts - 28 + src/app/components/manage/management-list/management-list.component.ts + 203 - - Dismiss all + + Error while deleting element - src/app/components/manage/tasks/tasks.component.ts - 29 + src/app/components/manage/management-list/management-list.component.ts + 219 + + + Permissions updated successfully - src/app/components/manage/tasks/tasks.component.ts - 62 + src/app/components/manage/management-list/management-list.component.ts + 293 - - Confirm Dismiss All + + storage path - src/app/components/manage/tasks/tasks.component.ts - 60 + src/app/components/manage/storage-path-list/storage-path-list.component.ts + 36 - - tasks? + + storage paths - src/app/components/manage/tasks/tasks.component.ts - 62 + src/app/components/manage/storage-path-list/storage-path-list.component.ts + 37 - - queued + + Do you really want to delete the storage path ""? - src/app/components/manage/tasks/tasks.component.ts - 130 + src/app/components/manage/storage-path-list/storage-path-list.component.ts + 52 - - started + + tag - src/app/components/manage/tasks/tasks.component.ts - 132 + src/app/components/manage/tag-list/tag-list.component.ts + 36 - - completed + + tags - src/app/components/manage/tasks/tasks.component.ts - 134 + src/app/components/manage/tag-list/tag-list.component.ts + 37 - - failed + + Do you really want to delete the tag ""? - src/app/components/manage/tasks/tasks.component.ts - 136 + src/app/components/manage/tag-list/tag-list.component.ts + 53 diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts index 34bf77609f..f2888b5960 100644 --- a/src-ui/src/app/app-routing.module.ts +++ b/src-ui/src/app/app-routing.module.ts @@ -6,14 +6,14 @@ import { DocumentDetailComponent } from './components/document-detail/document-d import { DocumentListComponent } from './components/document-list/document-list.component' import { CorrespondentListComponent } from './components/manage/correspondent-list/correspondent-list.component' import { DocumentTypeListComponent } from './components/manage/document-type-list/document-type-list.component' -import { LogsComponent } from './components/manage/logs/logs.component' -import { SettingsComponent } from './components/manage/settings/settings.component' +import { LogsComponent } from './components/admin/logs/logs.component' +import { SettingsComponent } from './components/admin/settings/settings.component' import { TagListComponent } from './components/manage/tag-list/tag-list.component' import { NotFoundComponent } from './components/not-found/not-found.component' import { DocumentAsnComponent } from './components/document-asn/document-asn.component' import { DirtyFormGuard } from './guards/dirty-form.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' -import { TasksComponent } from './components/manage/tasks/tasks.component' +import { TasksComponent } from './components/admin/tasks/tasks.component' import { PermissionsGuard } from './guards/permissions.guard' import { DirtyDocGuard } from './guards/dirty-doc.guard' import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' @@ -21,7 +21,9 @@ import { PermissionAction, PermissionType, } from './services/permissions.service' -import { ConsumptionTemplatesListComponent } from './components/manage/consumption-templates-list/consumption-templates-list.component' +import { ConsumptionTemplatesComponent } from './components/manage/consumption-templates/consumption-templates.component' +import { MailComponent } from './components/manage/mail/mail.component' +import { UsersAndGroupsComponent } from './components/admin/users-groups/users-groups.component' export const routes: Routes = [ { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, @@ -143,6 +145,15 @@ export const routes: Routes = [ }, }, }, + // redirect old paths + { + path: 'settings/mail', + redirectTo: '/mail', + }, + { + path: 'settings/usersgroups', + redirectTo: '/usersgroups', + }, { path: 'settings', component: SettingsComponent, @@ -167,11 +178,6 @@ export const routes: Routes = [ }, }, }, - { - path: 'settings/:section', - component: SettingsComponent, - canDeactivate: [DirtyFormGuard], - }, { path: 'tasks', component: TasksComponent, @@ -185,7 +191,7 @@ export const routes: Routes = [ }, { path: 'templates', - component: ConsumptionTemplatesListComponent, + component: ConsumptionTemplatesComponent, canActivate: [PermissionsGuard], data: { requiredPermission: { @@ -194,6 +200,28 @@ export const routes: Routes = [ }, }, }, + { + path: 'mail', + component: MailComponent, + canActivate: [PermissionsGuard], + data: { + requiredPermission: { + action: PermissionAction.View, + type: PermissionType.MailAccount, + }, + }, + }, + { + path: 'usersgroups', + component: UsersAndGroupsComponent, + canActivate: [PermissionsGuard], + data: { + requiredPermission: { + action: PermissionAction.View, + type: PermissionType.User, + }, + }, + }, ], }, diff --git a/src-ui/src/app/app.component.ts b/src-ui/src/app/app.component.ts index ca8e5ab238..9ca963337b 100644 --- a/src-ui/src/app/app.component.ts +++ b/src-ui/src/app/app.component.ts @@ -179,6 +179,22 @@ export class AppComponent implements OnInit, OnDestroy { offset: 0, }, }, + { + anchorId: 'tour.mail', + content: $localize`Manage e-mail accounts and rules for automatically importing documents.`, + route: '/mail', + backdropConfig: { + offset: 0, + }, + }, + { + anchorId: 'tour.consumption-templates', + content: $localize`Consumption templates give you finer control over the document ingestion process.`, + route: '/templates', + backdropConfig: { + offset: 0, + }, + }, { anchorId: 'tour.file-tasks', content: $localize`File Tasks shows you documents that have been consumed, are waiting to be, or may have failed during the process.`, @@ -189,7 +205,7 @@ export class AppComponent implements OnInit, OnDestroy { }, { anchorId: 'tour.settings', - content: $localize`Check out the settings for various tweaks to the web app, toggle settings for saved views or setup e-mail checking.`, + content: $localize`Check out the settings for various tweaks to the web app and toggle settings for saved views.`, route: '/settings', backdropConfig: { offset: 0, diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index bb6c8777a4..9d93074920 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -14,8 +14,8 @@ import { DashboardComponent } from './components/dashboard/dashboard.component' import { TagListComponent } from './components/manage/tag-list/tag-list.component' import { DocumentTypeListComponent } from './components/manage/document-type-list/document-type-list.component' import { CorrespondentListComponent } from './components/manage/correspondent-list/correspondent-list.component' -import { LogsComponent } from './components/manage/logs/logs.component' -import { SettingsComponent } from './components/manage/settings/settings.component' +import { LogsComponent } from './components/admin/logs/logs.component' +import { SettingsComponent } from './components/admin/settings/settings.component' import { FormsModule, ReactiveFormsModule } from '@angular/forms' import { DatePipe, registerLocaleData } from '@angular/common' import { NotFoundComponent } from './components/not-found/not-found.component' @@ -77,7 +77,7 @@ import { DirtySavedViewGuard } from './guards/dirty-saved-view.guard' import { StoragePathListComponent } from './components/manage/storage-path-list/storage-path-list.component' import { StoragePathEditDialogComponent } from './components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component' import { SettingsService } from './services/settings.service' -import { TasksComponent } from './components/manage/tasks/tasks.component' +import { TasksComponent } from './components/admin/tasks/tasks.component' import { TourNgBootstrapModule } from 'ngx-ui-tour-ng-bootstrap' import { UserEditDialogComponent } from './components/common/edit-dialog/user-edit-dialog/user-edit-dialog.component' import { GroupEditDialogComponent } from './components/common/edit-dialog/group-edit-dialog/group-edit-dialog.component' @@ -95,8 +95,10 @@ import { UsernamePipe } from './pipes/username.pipe' import { LogoComponent } from './components/common/logo/logo.component' import { IsNumberPipe } from './pipes/is-number.pipe' import { ShareLinksDropdownComponent } from './components/common/share-links-dropdown/share-links-dropdown.component' -import { ConsumptionTemplatesListComponent } from './components/manage/consumption-templates-list/consumption-templates-list.component' +import { ConsumptionTemplatesComponent } from './components/manage/consumption-templates/consumption-templates.component' import { ConsumptionTemplateEditDialogComponent } from './components/common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component' +import { MailComponent } from './components/manage/mail/mail.component' +import { UsersAndGroupsComponent } from './components/admin/users-groups/users-groups.component' import localeAf from '@angular/common/locales/af' import localeAr from '@angular/common/locales/ar' @@ -235,8 +237,10 @@ function initializeApp(settings: SettingsService) { LogoComponent, IsNumberPipe, ShareLinksDropdownComponent, - ConsumptionTemplatesListComponent, + ConsumptionTemplatesComponent, ConsumptionTemplateEditDialogComponent, + MailComponent, + UsersAndGroupsComponent, ], imports: [ BrowserModule, diff --git a/src-ui/src/app/components/manage/logs/logs.component.html b/src-ui/src/app/components/admin/logs/logs.component.html similarity index 100% rename from src-ui/src/app/components/manage/logs/logs.component.html rename to src-ui/src/app/components/admin/logs/logs.component.html diff --git a/src-ui/src/app/components/manage/logs/logs.component.scss b/src-ui/src/app/components/admin/logs/logs.component.scss similarity index 100% rename from src-ui/src/app/components/manage/logs/logs.component.scss rename to src-ui/src/app/components/admin/logs/logs.component.scss diff --git a/src-ui/src/app/components/manage/logs/logs.component.spec.ts b/src-ui/src/app/components/admin/logs/logs.component.spec.ts similarity index 100% rename from src-ui/src/app/components/manage/logs/logs.component.spec.ts rename to src-ui/src/app/components/admin/logs/logs.component.spec.ts diff --git a/src-ui/src/app/components/manage/logs/logs.component.ts b/src-ui/src/app/components/admin/logs/logs.component.ts similarity index 100% rename from src-ui/src/app/components/manage/logs/logs.component.ts rename to src-ui/src/app/components/admin/logs/logs.component.ts diff --git a/src-ui/src/app/components/manage/settings/settings.component.html b/src-ui/src/app/components/admin/settings/settings.component.html similarity index 57% rename from src-ui/src/app/components/manage/settings/settings.component.html rename to src-ui/src/app/components/admin/settings/settings.component.html index e2e4ed5c53..447f9cfb74 100644 --- a/src-ui/src/app/components/manage/settings/settings.component.html +++ b/src-ui/src/app/components/admin/settings/settings.component.html @@ -11,7 +11,7 @@
diff --git a/src-ui/src/app/components/manage/settings/settings.component.scss b/src-ui/src/app/components/admin/settings/settings.component.scss similarity index 100% rename from src-ui/src/app/components/manage/settings/settings.component.scss rename to src-ui/src/app/components/admin/settings/settings.component.scss diff --git a/src-ui/src/app/components/admin/settings/settings.component.spec.ts b/src-ui/src/app/components/admin/settings/settings.component.spec.ts new file mode 100644 index 0000000000..7ea025fe53 --- /dev/null +++ b/src-ui/src/app/components/admin/settings/settings.component.spec.ts @@ -0,0 +1,356 @@ +import { ViewportScroller, DatePipe } from '@angular/common' +import { HttpClientTestingModule } from '@angular/common/http/testing' +import { ComponentFixture, TestBed } from '@angular/core/testing' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { By } from '@angular/platform-browser' +import { Router, ActivatedRoute, convertToParamMap } from '@angular/router' +import { RouterTestingModule } from '@angular/router/testing' +import { + NgbModule, + NgbAlertModule, + NgbNavLink, +} from '@ng-bootstrap/ng-bootstrap' +import { NgSelectModule } from '@ng-select/ng-select' +import { of, throwError } from 'rxjs' +import { routes } from 'src/app/app-routing.module' +import { PaperlessSavedView } from 'src/app/data/paperless-saved-view' +import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' +import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive' +import { PermissionsGuard } from 'src/app/guards/permissions.guard' +import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe' +import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe' +import { PermissionsService } from 'src/app/services/permissions.service' +import { GroupService } from 'src/app/services/rest/group.service' +import { SavedViewService } from 'src/app/services/rest/saved-view.service' +import { UserService } from 'src/app/services/rest/user.service' +import { SettingsService } from 'src/app/services/settings.service' +import { ToastService, Toast } from 'src/app/services/toast.service' +import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' +import { CheckComponent } from '../../common/input/check/check.component' +import { ColorComponent } from '../../common/input/color/color.component' +import { NumberComponent } from '../../common/input/number/number.component' +import { PermissionsGroupComponent } from '../../common/input/permissions/permissions-group/permissions-group.component' +import { PermissionsUserComponent } from '../../common/input/permissions/permissions-user/permissions-user.component' +import { SelectComponent } from '../../common/input/select/select.component' +import { TagsComponent } from '../../common/input/tags/tags.component' +import { TextComponent } from '../../common/input/text/text.component' +import { PageHeaderComponent } from '../../common/page-header/page-header.component' +import { SettingsComponent } from './settings.component' +import { IfOwnerDirective } from 'src/app/directives/if-owner.directive' + +const savedViews = [ + { id: 1, name: 'view1', show_in_sidebar: true, show_on_dashboard: true }, + { id: 2, name: 'view2', show_in_sidebar: false, show_on_dashboard: false }, +] +const users = [ + { id: 1, username: 'user1', is_superuser: false }, + { id: 2, username: 'user2', is_superuser: false }, +] +const groups = [ + { id: 1, name: 'group1' }, + { id: 2, name: 'group2' }, +] + +describe('SettingsComponent', () => { + let component: SettingsComponent + let fixture: ComponentFixture + let router: Router + let settingsService: SettingsService + let savedViewService: SavedViewService + let activatedRoute: ActivatedRoute + let viewportScroller: ViewportScroller + let toastService: ToastService + let userService: UserService + let permissionsService: PermissionsService + let groupService: GroupService + + beforeEach(async () => { + TestBed.configureTestingModule({ + declarations: [ + SettingsComponent, + PageHeaderComponent, + IfPermissionsDirective, + CustomDatePipe, + ConfirmDialogComponent, + CheckComponent, + ColorComponent, + SafeHtmlPipe, + SelectComponent, + TextComponent, + NumberComponent, + TagsComponent, + PermissionsUserComponent, + PermissionsGroupComponent, + IfOwnerDirective, + ], + providers: [CustomDatePipe, DatePipe, PermissionsGuard], + imports: [ + NgbModule, + HttpClientTestingModule, + RouterTestingModule.withRoutes(routes), + FormsModule, + ReactiveFormsModule, + NgbAlertModule, + NgSelectModule, + ], + }).compileComponents() + + router = TestBed.inject(Router) + activatedRoute = TestBed.inject(ActivatedRoute) + viewportScroller = TestBed.inject(ViewportScroller) + toastService = TestBed.inject(ToastService) + settingsService = TestBed.inject(SettingsService) + settingsService.currentUser = users[0] + userService = TestBed.inject(UserService) + permissionsService = TestBed.inject(PermissionsService) + jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true) + jest + .spyOn(permissionsService, 'currentUserHasObjectPermissions') + .mockReturnValue(true) + jest + .spyOn(permissionsService, 'currentUserOwnsObject') + .mockReturnValue(true) + groupService = TestBed.inject(GroupService) + savedViewService = TestBed.inject(SavedViewService) + }) + + function completeSetup(excludeService = null) { + if (excludeService !== userService) { + jest.spyOn(userService, 'listAll').mockReturnValue( + of({ + all: users.map((u) => u.id), + count: users.length, + results: users.concat([]), + }) + ) + } + if (excludeService !== groupService) { + jest.spyOn(groupService, 'listAll').mockReturnValue( + of({ + all: groups.map((g) => g.id), + count: groups.length, + results: groups.concat([]), + }) + ) + } + if (excludeService !== savedViewService) { + jest.spyOn(savedViewService, 'listAll').mockReturnValue( + of({ + all: savedViews.map((v) => v.id), + count: savedViews.length, + results: (savedViews as PaperlessSavedView[]).concat([]), + }) + ) + } + + fixture = TestBed.createComponent(SettingsComponent) + component = fixture.componentInstance + fixture.detectChanges() + } + + it('should support tabbed settings & change URL, prevent navigation if dirty confirmation rejected', () => { + completeSetup() + const navigateSpy = jest.spyOn(router, 'navigate') + const tabButtons = fixture.debugElement.queryAll(By.directive(NgbNavLink)) + tabButtons[1].nativeElement.dispatchEvent(new MouseEvent('click')) + expect(navigateSpy).toHaveBeenCalledWith(['settings', 'permissions']) + tabButtons[2].nativeElement.dispatchEvent(new MouseEvent('click')) + expect(navigateSpy).toHaveBeenCalledWith(['settings', 'notifications']) + tabButtons[3].nativeElement.dispatchEvent(new MouseEvent('click')) + expect(navigateSpy).toHaveBeenCalledWith(['settings', 'savedviews']) + + const initSpy = jest.spyOn(component, 'initialize') + component.isDirty = true // mock dirty + navigateSpy.mockResolvedValueOnce(false) // nav rejected cause dirty + tabButtons[0].nativeElement.dispatchEvent(new MouseEvent('click')) + expect(navigateSpy).toHaveBeenCalledWith(['settings', 'general']) + expect(initSpy).not.toHaveBeenCalled() + + navigateSpy.mockResolvedValueOnce(true) // nav accepted even though dirty + tabButtons[1].nativeElement.dispatchEvent(new MouseEvent('click')) + expect(navigateSpy).toHaveBeenCalledWith(['settings', 'notifications']) + expect(initSpy).toHaveBeenCalled() + }) + + it('should support direct link to tab by URL, scroll if needed', () => { + completeSetup() + jest + .spyOn(activatedRoute, 'paramMap', 'get') + .mockReturnValue(of(convertToParamMap({ section: 'notifications' }))) + activatedRoute.snapshot.fragment = '#notifications' + const scrollSpy = jest.spyOn(viewportScroller, 'scrollToAnchor') + component.ngOnInit() + expect(component.activeNavID).toEqual(3) // Users & Groups + component.ngAfterViewInit() + expect(scrollSpy).toHaveBeenCalledWith('#notifications') + }) + + it('should support save saved views, show error', () => { + completeSetup() + + const tabButtons = fixture.debugElement.queryAll(By.directive(NgbNavLink)) + tabButtons[3].nativeElement.dispatchEvent(new MouseEvent('click')) + fixture.detectChanges() + + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastSpy = jest.spyOn(toastService, 'show') + const savedViewPatchSpy = jest.spyOn(savedViewService, 'patchMany') + + const toggle = fixture.debugElement.query( + By.css('.form-check.form-switch input') + ) + toggle.nativeElement.checked = true + toggle.nativeElement.dispatchEvent(new Event('change')) + + // saved views error first + savedViewPatchSpy.mockReturnValueOnce( + throwError(() => new Error('unable to save saved views')) + ) + component.saveSettings() + expect(toastErrorSpy).toHaveBeenCalled() + expect(savedViewPatchSpy).toHaveBeenCalled() + toastSpy.mockClear() + toastErrorSpy.mockClear() + savedViewPatchSpy.mockClear() + + // succeed saved views + savedViewPatchSpy.mockReturnValueOnce( + of(savedViews as PaperlessSavedView[]) + ) + component.saveSettings() + expect(toastErrorSpy).not.toHaveBeenCalled() + expect(savedViewPatchSpy).toHaveBeenCalled() + }) + + it('should update only patch saved views that have changed', () => { + completeSetup() + + const tabButtons = fixture.debugElement.queryAll(By.directive(NgbNavLink)) + tabButtons[3].nativeElement.dispatchEvent(new MouseEvent('click')) + fixture.detectChanges() + + const patchSpy = jest.spyOn(savedViewService, 'patchMany') + component.saveSettings() + expect(patchSpy).not.toHaveBeenCalled() + + const view = savedViews[0] + const toggle = fixture.debugElement.query( + By.css('.form-check.form-switch input') + ) + toggle.nativeElement.checked = true + toggle.nativeElement.dispatchEvent(new Event('change')) + // register change + component.savedViewGroup.get(view.id.toString()).value[ + 'show_on_dashboard' + ] = !view.show_on_dashboard + fixture.detectChanges() + + component.saveSettings() + expect(patchSpy).toHaveBeenCalledWith([ + { + id: view.id, + name: view.name, + show_in_sidebar: view.show_in_sidebar, + show_on_dashboard: !view.show_on_dashboard, + }, + ]) + }) + + it('should support save local settings updating appearance settings and calling API, show error', () => { + completeSetup() + jest.spyOn(savedViewService, 'patchMany').mockReturnValue(of([])) + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastSpy = jest.spyOn(toastService, 'show') + const storeSpy = jest.spyOn(settingsService, 'storeSettings') + const appearanceSettingsSpy = jest.spyOn( + settingsService, + 'updateAppearanceSettings' + ) + const setSpy = jest.spyOn(settingsService, 'set') + + // error first + storeSpy.mockReturnValueOnce( + throwError(() => new Error('unable to save settings')) + ) + component.saveSettings() + + expect(toastErrorSpy).toHaveBeenCalled() + expect(storeSpy).toHaveBeenCalled() + expect(appearanceSettingsSpy).not.toHaveBeenCalled() + expect(setSpy).toHaveBeenCalledTimes(24) + + // succeed + storeSpy.mockReturnValueOnce(of(true)) + component.saveSettings() + expect(toastSpy).toHaveBeenCalled() + expect(appearanceSettingsSpy).toHaveBeenCalled() + }) + + it('should offer reload if settings changes require', () => { + completeSetup() + jest.spyOn(savedViewService, 'patchMany').mockReturnValue(of([])) + let toast: Toast + toastService.getToasts().subscribe((t) => (toast = t[0])) + component.initialize(true) // reset + component.store.getValue()['displayLanguage'] = 'en-US' + component.store.getValue()['updateCheckingEnabled'] = false + component.settingsForm.value.displayLanguage = 'en-GB' + component.settingsForm.value.updateCheckingEnabled = true + jest.spyOn(settingsService, 'storeSettings').mockReturnValueOnce(of(true)) + component.saveSettings() + expect(toast.actionName).toEqual('Reload now') + }) + + it('should allow setting theme color, visually apply change immediately but not save', () => { + completeSetup() + const appearanceSpy = jest.spyOn( + settingsService, + 'updateAppearanceSettings' + ) + const colorInput = fixture.debugElement.query(By.directive(ColorComponent)) + colorInput.query(By.css('input')).nativeElement.value = '#ff0000' + colorInput + .query(By.css('input')) + .nativeElement.dispatchEvent(new Event('change')) + fixture.detectChanges() + expect(appearanceSpy).toHaveBeenCalled() + expect(settingsService.get(SETTINGS_KEYS.THEME_COLOR)).toEqual('') + component.clearThemeColor() + }) + + it('should support delete saved view', () => { + completeSetup() + const toastSpy = jest.spyOn(toastService, 'showInfo') + const deleteSpy = jest.spyOn(savedViewService, 'delete') + deleteSpy.mockReturnValue(of(true)) + component.deleteSavedView(savedViews[0] as PaperlessSavedView) + expect(deleteSpy).toHaveBeenCalled() + expect(toastSpy).toHaveBeenCalledWith( + `Saved view "${savedViews[0].name}" deleted.` + ) + }) + + it('should show errors on load if load users failure', () => { + const toastErrorSpy = jest.spyOn(toastService, 'showError') + jest + .spyOn(userService, 'listAll') + .mockImplementation(() => + throwError(() => new Error('failed to load users')) + ) + completeSetup(userService) + fixture.detectChanges() + expect(toastErrorSpy).toBeCalled() + }) + + it('should show errors on load if load groups failure', () => { + const toastErrorSpy = jest.spyOn(toastService, 'showError') + jest + .spyOn(groupService, 'listAll') + .mockImplementation(() => + throwError(() => new Error('failed to load groups')) + ) + completeSetup(groupService) + fixture.detectChanges() + expect(toastErrorSpy).toBeCalled() + }) +}) diff --git a/src-ui/src/app/components/admin/settings/settings.component.ts b/src-ui/src/app/components/admin/settings/settings.component.ts new file mode 100644 index 0000000000..14528d76d5 --- /dev/null +++ b/src-ui/src/app/components/admin/settings/settings.component.ts @@ -0,0 +1,551 @@ +import { ViewportScroller } from '@angular/common' +import { + Component, + OnInit, + AfterViewInit, + OnDestroy, + Inject, + LOCALE_ID, +} from '@angular/core' +import { FormGroup, FormControl } from '@angular/forms' +import { ActivatedRoute, Router } from '@angular/router' +import { NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap' +import { DirtyComponent, dirtyCheck } from '@ngneat/dirty-check-forms' +import { TourService } from 'ngx-ui-tour-ng-bootstrap' +import { + BehaviorSubject, + Subscription, + Observable, + Subject, + first, + takeUntil, + tap, +} from 'rxjs' +import { PaperlessGroup } from 'src/app/data/paperless-group' +import { PaperlessSavedView } from 'src/app/data/paperless-saved-view' +import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings' +import { PaperlessUser } from 'src/app/data/paperless-user' +import { DocumentListViewService } from 'src/app/services/document-list-view.service' +import { + PermissionsService, + PermissionAction, + PermissionType, +} from 'src/app/services/permissions.service' +import { GroupService } from 'src/app/services/rest/group.service' +import { SavedViewService } from 'src/app/services/rest/saved-view.service' +import { UserService } from 'src/app/services/rest/user.service' +import { + SettingsService, + LanguageOption, +} from 'src/app/services/settings.service' +import { ToastService, Toast } from 'src/app/services/toast.service' +import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component' + +enum SettingsNavIDs { + General = 1, + Permissions = 2, + Notifications = 3, + SavedViews = 4, +} + +@Component({ + selector: 'pngx-settings', + templateUrl: './settings.component.html', + styleUrls: ['./settings.component.scss'], +}) +export class SettingsComponent + extends ComponentWithPermissions + implements OnInit, AfterViewInit, OnDestroy, DirtyComponent +{ + SettingsNavIDs = SettingsNavIDs + activeNavID: number + + savedViewGroup = new FormGroup({}) + + settingsForm = new FormGroup({ + bulkEditConfirmationDialogs: new FormControl(null), + bulkEditApplyOnClose: new FormControl(null), + documentListItemPerPage: new FormControl(null), + slimSidebarEnabled: new FormControl(null), + darkModeUseSystem: new FormControl(null), + darkModeEnabled: new FormControl(null), + darkModeInvertThumbs: new FormControl(null), + themeColor: new FormControl(null), + useNativePdfViewer: new FormControl(null), + displayLanguage: new FormControl(null), + dateLocale: new FormControl(null), + dateFormat: new FormControl(null), + notesEnabled: new FormControl(null), + updateCheckingEnabled: new FormControl(null), + defaultPermsOwner: new FormControl(null), + defaultPermsViewUsers: new FormControl(null), + defaultPermsViewGroups: new FormControl(null), + defaultPermsEditUsers: new FormControl(null), + defaultPermsEditGroups: new FormControl(null), + + notificationsConsumerNewDocument: new FormControl(null), + notificationsConsumerSuccess: new FormControl(null), + notificationsConsumerFailed: new FormControl(null), + notificationsConsumerSuppressOnDashboard: new FormControl(null), + + savedViewsWarnOnUnsavedChange: new FormControl(null), + savedViews: this.savedViewGroup, + }) + + savedViews: PaperlessSavedView[] + + store: BehaviorSubject + storeSub: Subscription + isDirty$: Observable + isDirty: boolean = false + unsubscribeNotifier: Subject = new Subject() + savePending: boolean = false + + users: PaperlessUser[] + groups: PaperlessGroup[] + + get computedDateLocale(): string { + return ( + this.settingsForm.value.dateLocale || + this.settingsForm.value.displayLanguage || + this.currentLocale + ) + } + + constructor( + public savedViewService: SavedViewService, + private documentListViewService: DocumentListViewService, + private toastService: ToastService, + private settings: SettingsService, + @Inject(LOCALE_ID) public currentLocale: string, + private viewportScroller: ViewportScroller, + private activatedRoute: ActivatedRoute, + public readonly tourService: TourService, + private usersService: UserService, + private groupsService: GroupService, + private router: Router, + public permissionsService: PermissionsService + ) { + super() + this.settings.settingsSaved.subscribe(() => { + if (!this.savePending) this.initialize() + }) + } + + ngOnInit() { + this.initialize() + + if ( + this.permissionsService.currentUserCan( + PermissionAction.View, + PermissionType.User + ) + ) { + this.usersService + .listAll() + .pipe(first()) + .subscribe({ + next: (r) => { + this.users = r.results + }, + error: (e) => { + this.toastService.showError($localize`Error retrieving users`, e) + }, + }) + } + + if ( + this.permissionsService.currentUserCan( + PermissionAction.View, + PermissionType.Group + ) + ) { + this.groupsService + .listAll() + .pipe(first()) + .subscribe({ + next: (r) => { + this.groups = r.results + }, + error: (e) => { + this.toastService.showError($localize`Error retrieving groups`, e) + }, + }) + } + + if ( + this.permissionsService.currentUserCan( + PermissionAction.View, + PermissionType.SavedView + ) + ) { + this.savedViewService.listAll().subscribe((r) => { + this.savedViews = r.results + this.initialize(false) + }) + } + + this.activatedRoute.paramMap.subscribe((paramMap) => { + const section = paramMap.get('section') + if (section) { + const navIDKey: string = Object.keys(SettingsNavIDs).find( + (navID) => navID.toLowerCase() == section + ) + if (navIDKey) { + this.activeNavID = SettingsNavIDs[navIDKey] + } + } + }) + } + + ngAfterViewInit(): void { + if (this.activatedRoute.snapshot.fragment) { + this.viewportScroller.scrollToAnchor( + this.activatedRoute.snapshot.fragment + ) + } + } + + private getCurrentSettings() { + return { + bulkEditConfirmationDialogs: this.settings.get( + SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS + ), + bulkEditApplyOnClose: this.settings.get( + SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE + ), + documentListItemPerPage: this.settings.get( + SETTINGS_KEYS.DOCUMENT_LIST_SIZE + ), + slimSidebarEnabled: this.settings.get(SETTINGS_KEYS.SLIM_SIDEBAR), + darkModeUseSystem: this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM), + darkModeEnabled: this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED), + darkModeInvertThumbs: this.settings.get( + SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED + ), + themeColor: this.settings.get(SETTINGS_KEYS.THEME_COLOR), + useNativePdfViewer: this.settings.get( + SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER + ), + displayLanguage: this.settings.getLanguage(), + dateLocale: this.settings.get(SETTINGS_KEYS.DATE_LOCALE), + dateFormat: this.settings.get(SETTINGS_KEYS.DATE_FORMAT), + notesEnabled: this.settings.get(SETTINGS_KEYS.NOTES_ENABLED), + updateCheckingEnabled: this.settings.get( + SETTINGS_KEYS.UPDATE_CHECKING_ENABLED + ), + notificationsConsumerNewDocument: this.settings.get( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT + ), + notificationsConsumerSuccess: this.settings.get( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS + ), + notificationsConsumerFailed: this.settings.get( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED + ), + notificationsConsumerSuppressOnDashboard: this.settings.get( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD + ), + savedViewsWarnOnUnsavedChange: this.settings.get( + SETTINGS_KEYS.SAVED_VIEWS_WARN_ON_UNSAVED_CHANGE + ), + defaultPermsOwner: this.settings.get(SETTINGS_KEYS.DEFAULT_PERMS_OWNER), + defaultPermsViewUsers: this.settings.get( + SETTINGS_KEYS.DEFAULT_PERMS_VIEW_USERS + ), + defaultPermsViewGroups: this.settings.get( + SETTINGS_KEYS.DEFAULT_PERMS_VIEW_GROUPS + ), + defaultPermsEditUsers: this.settings.get( + SETTINGS_KEYS.DEFAULT_PERMS_EDIT_USERS + ), + defaultPermsEditGroups: this.settings.get( + SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS + ), + savedViews: {}, + } + } + + onNavChange(navChangeEvent: NgbNavChangeEvent) { + const [foundNavIDkey] = Object.entries(SettingsNavIDs).find( + ([, navIDValue]) => navIDValue == navChangeEvent.nextId + ) + if (foundNavIDkey) + // if its dirty we need to wait for confirmation + this.router + .navigate(['settings', foundNavIDkey.toLowerCase()]) + .then((navigated) => { + if (!navigated && this.isDirty) { + this.activeNavID = navChangeEvent.activeId + } else if (navigated && this.isDirty) { + this.initialize() + } + }) + } + + initialize(resetSettings: boolean = true) { + this.unsubscribeNotifier.next(true) + + const currentFormValue = this.settingsForm.value + + let storeData = this.getCurrentSettings() + + if (this.savedViews) { + this.emptyGroup(this.savedViewGroup) + + for (let view of this.savedViews) { + storeData.savedViews[view.id.toString()] = { + id: view.id, + name: view.name, + show_on_dashboard: view.show_on_dashboard, + show_in_sidebar: view.show_in_sidebar, + } + this.savedViewGroup.addControl( + view.id.toString(), + new FormGroup({ + id: new FormControl(null), + name: new FormControl(null), + show_on_dashboard: new FormControl(null), + show_in_sidebar: new FormControl(null), + }) + ) + } + } + + this.store = new BehaviorSubject(storeData) + + this.storeSub = this.store.asObservable().subscribe((state) => { + this.settingsForm.patchValue(state, { emitEvent: false }) + }) + + // Initialize dirtyCheck + this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable()) + + // Record dirty in case we need to 'undo' appearance settings if not saved on close + this.isDirty$ + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe((dirty) => { + this.isDirty = dirty + }) + + // "Live" visual changes prior to save + this.settingsForm.valueChanges + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe(() => { + this.settings.updateAppearanceSettings( + this.settingsForm.get('darkModeUseSystem').value, + this.settingsForm.get('darkModeEnabled').value, + this.settingsForm.get('themeColor').value + ) + }) + + if (!resetSettings && currentFormValue) { + // prevents loss of unsaved changes + this.settingsForm.patchValue(currentFormValue) + } + } + + private emptyGroup(group: FormGroup) { + Object.keys(group.controls).forEach((key) => group.removeControl(key)) + } + + ngOnDestroy() { + if (this.isDirty) this.settings.updateAppearanceSettings() // in case user changed appearance but didnt save + this.storeSub && this.storeSub.unsubscribe() + } + + deleteSavedView(savedView: PaperlessSavedView) { + this.savedViewService.delete(savedView).subscribe(() => { + this.savedViewGroup.removeControl(savedView.id.toString()) + this.savedViews.splice(this.savedViews.indexOf(savedView), 1) + this.toastService.showInfo( + $localize`Saved view "${savedView.name}" deleted.` + ) + this.savedViewService.clearCache() + this.savedViewService.listAll().subscribe((r) => { + this.savedViews = r.results + this.initialize(true) + }) + }) + } + + private saveLocalSettings() { + this.savePending = true + const reloadRequired = + this.settingsForm.value.displayLanguage != + this.store?.getValue()['displayLanguage'] || // displayLanguage is dirty + (this.settingsForm.value.updateCheckingEnabled != + this.store?.getValue()['updateCheckingEnabled'] && + this.settingsForm.value.updateCheckingEnabled) // update checking was turned on + + this.settings.set( + SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE, + this.settingsForm.value.bulkEditApplyOnClose + ) + this.settings.set( + SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS, + this.settingsForm.value.bulkEditConfirmationDialogs + ) + this.settings.set( + SETTINGS_KEYS.DOCUMENT_LIST_SIZE, + this.settingsForm.value.documentListItemPerPage + ) + this.settings.set( + SETTINGS_KEYS.SLIM_SIDEBAR, + this.settingsForm.value.slimSidebarEnabled + ) + this.settings.set( + SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, + this.settingsForm.value.darkModeUseSystem + ) + this.settings.set( + SETTINGS_KEYS.DARK_MODE_ENABLED, + (this.settingsForm.value.darkModeEnabled == true).toString() + ) + this.settings.set( + SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED, + (this.settingsForm.value.darkModeInvertThumbs == true).toString() + ) + this.settings.set( + SETTINGS_KEYS.THEME_COLOR, + this.settingsForm.value.themeColor.toString() + ) + this.settings.set( + SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, + this.settingsForm.value.useNativePdfViewer + ) + this.settings.set( + SETTINGS_KEYS.DATE_LOCALE, + this.settingsForm.value.dateLocale + ) + this.settings.set( + SETTINGS_KEYS.DATE_FORMAT, + this.settingsForm.value.dateFormat + ) + this.settings.set( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT, + this.settingsForm.value.notificationsConsumerNewDocument + ) + this.settings.set( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS, + this.settingsForm.value.notificationsConsumerSuccess + ) + this.settings.set( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED, + this.settingsForm.value.notificationsConsumerFailed + ) + this.settings.set( + SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD, + this.settingsForm.value.notificationsConsumerSuppressOnDashboard + ) + this.settings.set( + SETTINGS_KEYS.NOTES_ENABLED, + this.settingsForm.value.notesEnabled + ) + this.settings.set( + SETTINGS_KEYS.UPDATE_CHECKING_ENABLED, + this.settingsForm.value.updateCheckingEnabled + ) + this.settings.set( + SETTINGS_KEYS.SAVED_VIEWS_WARN_ON_UNSAVED_CHANGE, + this.settingsForm.value.savedViewsWarnOnUnsavedChange + ) + this.settings.set( + SETTINGS_KEYS.DEFAULT_PERMS_OWNER, + this.settingsForm.value.defaultPermsOwner + ) + this.settings.set( + SETTINGS_KEYS.DEFAULT_PERMS_VIEW_USERS, + this.settingsForm.value.defaultPermsViewUsers + ) + this.settings.set( + SETTINGS_KEYS.DEFAULT_PERMS_VIEW_GROUPS, + this.settingsForm.value.defaultPermsViewGroups + ) + this.settings.set( + SETTINGS_KEYS.DEFAULT_PERMS_EDIT_USERS, + this.settingsForm.value.defaultPermsEditUsers + ) + this.settings.set( + SETTINGS_KEYS.DEFAULT_PERMS_EDIT_GROUPS, + this.settingsForm.value.defaultPermsEditGroups + ) + this.settings.setLanguage(this.settingsForm.value.displayLanguage) + this.settings + .storeSettings() + .pipe(first()) + .pipe(tap(() => (this.savePending = false))) + .subscribe({ + next: () => { + this.store.next(this.settingsForm.value) + this.documentListViewService.updatePageSize() + this.settings.updateAppearanceSettings() + let savedToast: Toast = { + title: $localize`Settings saved`, + content: $localize`Settings were saved successfully.`, + delay: 5000, + } + if (reloadRequired) { + savedToast.content = $localize`Settings were saved successfully. Reload is required to apply some changes.` + savedToast.actionName = $localize`Reload now` + savedToast.action = () => { + location.reload() + } + } + + this.toastService.show(savedToast) + }, + error: (error) => { + this.toastService.showError( + $localize`An error occurred while saving settings.`, + error + ) + }, + }) + } + + get displayLanguageOptions(): LanguageOption[] { + return [{ code: '', name: $localize`Use system language` }].concat( + this.settings.getLanguageOptions() + ) + } + + get dateLocaleOptions(): LanguageOption[] { + return [ + { code: '', name: $localize`Use date format of display language` }, + ].concat(this.settings.getDateLocaleOptions()) + } + + get today() { + return new Date() + } + + saveSettings() { + // only patch views that have actually changed + const changed: PaperlessSavedView[] = [] + Object.values(this.savedViewGroup.controls) + .filter((g: FormGroup) => !g.pristine) + .forEach((group: FormGroup) => { + changed.push(group.value) + }) + if (changed.length > 0) { + this.savedViewService.patchMany(changed).subscribe({ + next: () => { + this.saveLocalSettings() + }, + error: (error) => { + this.toastService.showError( + $localize`Error while storing settings on server.`, + error + ) + }, + }) + } else { + this.saveLocalSettings() + } + } + + clearThemeColor() { + this.settingsForm.get('themeColor').patchValue('') + } +} diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.html b/src-ui/src/app/components/admin/tasks/tasks.component.html similarity index 100% rename from src-ui/src/app/components/manage/tasks/tasks.component.html rename to src-ui/src/app/components/admin/tasks/tasks.component.html diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.scss b/src-ui/src/app/components/admin/tasks/tasks.component.scss similarity index 100% rename from src-ui/src/app/components/manage/tasks/tasks.component.scss rename to src-ui/src/app/components/admin/tasks/tasks.component.scss diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.spec.ts b/src-ui/src/app/components/admin/tasks/tasks.component.spec.ts similarity index 100% rename from src-ui/src/app/components/manage/tasks/tasks.component.spec.ts rename to src-ui/src/app/components/admin/tasks/tasks.component.spec.ts diff --git a/src-ui/src/app/components/manage/tasks/tasks.component.ts b/src-ui/src/app/components/admin/tasks/tasks.component.ts similarity index 100% rename from src-ui/src/app/components/manage/tasks/tasks.component.ts rename to src-ui/src/app/components/admin/tasks/tasks.component.ts diff --git a/src-ui/src/app/components/admin/users-groups/users-groups.component.html b/src-ui/src/app/components/admin/users-groups/users-groups.component.html new file mode 100644 index 0000000000..daea4cb2f1 --- /dev/null +++ b/src-ui/src/app/components/admin/users-groups/users-groups.component.html @@ -0,0 +1,99 @@ + + + + +

+ Users + +

+
    + +
  • +
    +
    Username
    +
    Name
    +
    Groups
    +
    Actions
    +
    +
  • + +
  • +
    +
    +
    {{user.first_name}} {{user.last_name}}
    +
    {{user.groups?.map(getGroupName, this).join(', ')}}
    +
    +
    + + +
    +
    +
    +
  • +
+
+ + +

+ Groups + +

+
    + +
  • +
    +
    Name
    +
    +
    +
    Actions
    +
    +
  • + +
  • +
    +
    +
    +
    +
    +
    + + +
    +
    +
    +
  • +
+ +
No groups defined
+
+ +
+
+
Loading...
+
diff --git a/src-ui/src/app/components/manage/consumption-templates-list/consumption-templates-list.component.scss b/src-ui/src/app/components/admin/users-groups/users-groups.component.scss similarity index 100% rename from src-ui/src/app/components/manage/consumption-templates-list/consumption-templates-list.component.scss rename to src-ui/src/app/components/admin/users-groups/users-groups.component.scss diff --git a/src-ui/src/app/components/admin/users-groups/users-groups.component.spec.ts b/src-ui/src/app/components/admin/users-groups/users-groups.component.spec.ts new file mode 100644 index 0000000000..fd8961d518 --- /dev/null +++ b/src-ui/src/app/components/admin/users-groups/users-groups.component.spec.ts @@ -0,0 +1,267 @@ +import { DatePipe } from '@angular/common' +import { HttpClientTestingModule } from '@angular/common/http/testing' +import { + ComponentFixture, + TestBed, + fakeAsync, + tick, +} from '@angular/core/testing' +import { FormsModule, ReactiveFormsModule } from '@angular/forms' +import { RouterTestingModule } from '@angular/router/testing' +import { + NgbModule, + NgbAlertModule, + NgbModal, + NgbModalRef, +} from '@ng-bootstrap/ng-bootstrap' +import { NgSelectModule } from '@ng-select/ng-select' +import { throwError, of } from 'rxjs' +import { routes } from 'src/app/app-routing.module' +import { IfOwnerDirective } from 'src/app/directives/if-owner.directive' +import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive' +import { PermissionsGuard } from 'src/app/guards/permissions.guard' +import { CustomDatePipe } from 'src/app/pipes/custom-date.pipe' +import { SafeHtmlPipe } from 'src/app/pipes/safehtml.pipe' +import { PermissionsService } from 'src/app/services/permissions.service' +import { GroupService } from 'src/app/services/rest/group.service' +import { UserService } from 'src/app/services/rest/user.service' +import { SettingsService } from 'src/app/services/settings.service' +import { ToastService } from 'src/app/services/toast.service' +import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' +import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component' +import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component' +import { CheckComponent } from '../../common/input/check/check.component' +import { NumberComponent } from '../../common/input/number/number.component' +import { PasswordComponent } from '../../common/input/password/password.component' +import { PermissionsGroupComponent } from '../../common/input/permissions/permissions-group/permissions-group.component' +import { PermissionsUserComponent } from '../../common/input/permissions/permissions-user/permissions-user.component' +import { SelectComponent } from '../../common/input/select/select.component' +import { TagsComponent } from '../../common/input/tags/tags.component' +import { TextComponent } from '../../common/input/text/text.component' +import { PageHeaderComponent } from '../../common/page-header/page-header.component' +import { SettingsComponent } from '../settings/settings.component' +import { UsersAndGroupsComponent } from './users-groups.component' +import { PaperlessUser } from 'src/app/data/paperless-user' +import { PaperlessGroup } from 'src/app/data/paperless-group' + +const users = [ + { id: 1, username: 'user1', is_superuser: false }, + { id: 2, username: 'user2', is_superuser: false }, +] +const groups = [ + { id: 1, name: 'group1' }, + { id: 2, name: 'group2' }, +] + +describe('UsersAndGroupsComponent', () => { + let component: UsersAndGroupsComponent + let fixture: ComponentFixture + let settingsService: SettingsService + let modalService: NgbModal + let toastService: ToastService + let userService: UserService + let permissionsService: PermissionsService + let groupService: GroupService + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + UsersAndGroupsComponent, + SettingsComponent, + PageHeaderComponent, + IfPermissionsDirective, + CustomDatePipe, + ConfirmDialogComponent, + CheckComponent, + SafeHtmlPipe, + SelectComponent, + TextComponent, + PasswordComponent, + NumberComponent, + TagsComponent, + PermissionsUserComponent, + PermissionsGroupComponent, + IfOwnerDirective, + ], + providers: [CustomDatePipe, DatePipe, PermissionsGuard], + imports: [ + NgbModule, + HttpClientTestingModule, + RouterTestingModule.withRoutes(routes), + FormsModule, + ReactiveFormsModule, + NgbAlertModule, + NgSelectModule, + ], + }).compileComponents() + fixture = TestBed.createComponent(UsersAndGroupsComponent) + settingsService = TestBed.inject(SettingsService) + settingsService.currentUser = users[0] + userService = TestBed.inject(UserService) + modalService = TestBed.inject(NgbModal) + toastService = TestBed.inject(ToastService) + permissionsService = TestBed.inject(PermissionsService) + jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true) + jest + .spyOn(permissionsService, 'currentUserHasObjectPermissions') + .mockReturnValue(true) + jest + .spyOn(permissionsService, 'currentUserOwnsObject') + .mockReturnValue(true) + groupService = TestBed.inject(GroupService) + component = fixture.componentInstance + fixture.detectChanges() + }) + + function completeSetup(excludeService = null) { + if (excludeService !== userService) { + jest.spyOn(userService, 'listAll').mockReturnValue( + of({ + all: users.map((a) => a.id), + count: users.length, + results: (users as PaperlessUser[]).concat([]), + }) + ) + } + if (excludeService !== groupService) { + jest.spyOn(groupService, 'listAll').mockReturnValue( + of({ + all: groups.map((r) => r.id), + count: groups.length, + results: (groups as PaperlessGroup[]).concat([]), + }) + ) + } + + fixture = TestBed.createComponent(UsersAndGroupsComponent) + component = fixture.componentInstance + fixture.detectChanges() + } + + it('should support edit / create user, show error if needed', () => { + completeSetup() + let modal: NgbModalRef + modalService.activeInstances.subscribe((refs) => (modal = refs[0])) + component.editUser(users[0]) + const editDialog = modal.componentInstance as UserEditDialogComponent + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastInfoSpy = jest.spyOn(toastService, 'showInfo') + editDialog.failed.emit() + expect(toastErrorSpy).toBeCalled() + settingsService.currentUser = users[1] // simulate logged in as different user + editDialog.succeeded.emit(users[0]) + expect(toastInfoSpy).toHaveBeenCalledWith( + `Saved user "${users[0].username}".` + ) + component.editUser() + }) + + it('should support delete user, show error if needed', () => { + completeSetup() + let modal: NgbModalRef + modalService.activeInstances.subscribe((refs) => (modal = refs[0])) + component.deleteUser(users[0]) + const deleteDialog = modal.componentInstance as ConfirmDialogComponent + const deleteSpy = jest.spyOn(userService, 'delete') + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastInfoSpy = jest.spyOn(toastService, 'showInfo') + const listAllSpy = jest.spyOn(userService, 'listAll') + deleteSpy.mockReturnValueOnce( + throwError(() => new Error('error deleting user')) + ) + deleteDialog.confirm() + expect(toastErrorSpy).toBeCalled() + deleteSpy.mockReturnValueOnce(of(true)) + deleteDialog.confirm() + expect(listAllSpy).toHaveBeenCalled() + expect(toastInfoSpy).toHaveBeenCalledWith('Deleted user') + }) + + it('should logout current user if password changed, after delay', fakeAsync(() => { + completeSetup() + let modal: NgbModalRef + modalService.activeInstances.subscribe((refs) => (modal = refs[0])) + component.editUser(users[0]) + const editDialog = modal.componentInstance as UserEditDialogComponent + editDialog.passwordIsSet = true + settingsService.currentUser = users[0] // simulate logged in as same user + editDialog.succeeded.emit(users[0]) + fixture.detectChanges() + Object.defineProperty(window, 'location', { + value: { + href: 'http://localhost/', + }, + writable: true, // possibility to override + }) + tick(2600) + expect(window.location.href).toContain('logout') + })) + + it('should support edit / create group, show error if needed', () => { + completeSetup() + let modal: NgbModalRef + modalService.activeInstances.subscribe((refs) => (modal = refs[0])) + component.editGroup(groups[0]) + const editDialog = modal.componentInstance as GroupEditDialogComponent + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastInfoSpy = jest.spyOn(toastService, 'showInfo') + editDialog.failed.emit() + expect(toastErrorSpy).toBeCalled() + editDialog.succeeded.emit(groups[0]) + expect(toastInfoSpy).toHaveBeenCalledWith( + `Saved group "${groups[0].name}".` + ) + component.editGroup() + }) + + it('should support delete group, show error if needed', () => { + completeSetup() + let modal: NgbModalRef + modalService.activeInstances.subscribe((refs) => (modal = refs[0])) + component.deleteGroup(users[0]) + const deleteDialog = modal.componentInstance as ConfirmDialogComponent + const deleteSpy = jest.spyOn(groupService, 'delete') + const toastErrorSpy = jest.spyOn(toastService, 'showError') + const toastInfoSpy = jest.spyOn(toastService, 'showInfo') + const listAllSpy = jest.spyOn(groupService, 'listAll') + deleteSpy.mockReturnValueOnce( + throwError(() => new Error('error deleting group')) + ) + deleteDialog.confirm() + expect(toastErrorSpy).toBeCalled() + deleteSpy.mockReturnValueOnce(of(true)) + deleteDialog.confirm() + expect(listAllSpy).toHaveBeenCalled() + expect(toastInfoSpy).toHaveBeenCalledWith('Deleted group') + }) + + it('should get group name', () => { + completeSetup() + expect(component.getGroupName(1)).toEqual(groups[0].name) + expect(component.getGroupName(11)).toEqual('') + }) + + it('should show errors on load if load users failure', () => { + const toastErrorSpy = jest.spyOn(toastService, 'showError') + jest + .spyOn(userService, 'listAll') + .mockImplementation(() => + throwError(() => new Error('failed to load users')) + ) + completeSetup(userService) + fixture.detectChanges() + expect(toastErrorSpy).toBeCalled() + }) + + it('should show errors on load if load groups failure', () => { + const toastErrorSpy = jest.spyOn(toastService, 'showError') + jest + .spyOn(groupService, 'listAll') + .mockImplementation(() => + throwError(() => new Error('failed to load groups')) + ) + completeSetup(groupService) + fixture.detectChanges() + expect(toastErrorSpy).toBeCalled() + }) +}) diff --git a/src-ui/src/app/components/admin/users-groups/users-groups.component.ts b/src-ui/src/app/components/admin/users-groups/users-groups.component.ts new file mode 100644 index 0000000000..a9ce1d6001 --- /dev/null +++ b/src-ui/src/app/components/admin/users-groups/users-groups.component.ts @@ -0,0 +1,189 @@ +import { Component, OnDestroy, OnInit } from '@angular/core' +import { NgbModal } from '@ng-bootstrap/ng-bootstrap' +import { Subject, first, takeUntil } from 'rxjs' +import { PaperlessGroup } from 'src/app/data/paperless-group' +import { PaperlessUser } from 'src/app/data/paperless-user' +import { PermissionsService } from 'src/app/services/permissions.service' +import { GroupService } from 'src/app/services/rest/group.service' +import { UserService } from 'src/app/services/rest/user.service' +import { ToastService } from 'src/app/services/toast.service' +import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component' +import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component' +import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component' +import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component' +import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component' +import { SettingsService } from 'src/app/services/settings.service' + +@Component({ + selector: 'pngx-users-groups', + templateUrl: './users-groups.component.html', + styleUrls: ['./users-groups.component.scss'], +}) +export class UsersAndGroupsComponent + extends ComponentWithPermissions + implements OnInit, OnDestroy +{ + users: PaperlessUser[] + groups: PaperlessGroup[] + + unsubscribeNotifier: Subject = new Subject() + + constructor( + private usersService: UserService, + private groupsService: GroupService, + private toastService: ToastService, + private modalService: NgbModal, + public permissionsService: PermissionsService, + private settings: SettingsService + ) { + super() + } + + ngOnInit(): void { + this.usersService + .listAll(null, null, { full_perms: true }) + .pipe(first(), takeUntil(this.unsubscribeNotifier)) + .subscribe({ + next: (r) => { + this.users = r.results + }, + error: (e) => { + this.toastService.showError($localize`Error retrieving users`, e) + }, + }) + + this.groupsService + .listAll(null, null, { full_perms: true }) + .pipe(first(), takeUntil(this.unsubscribeNotifier)) + .subscribe({ + next: (r) => { + this.groups = r.results + }, + error: (e) => { + this.toastService.showError($localize`Error retrieving groups`, e) + }, + }) + } + + ngOnDestroy() { + this.unsubscribeNotifier.next(true) + } + + editUser(user: PaperlessUser = null) { + var modal = this.modalService.open(UserEditDialogComponent, { + backdrop: 'static', + size: 'xl', + }) + modal.componentInstance.dialogMode = user + ? EditDialogMode.EDIT + : EditDialogMode.CREATE + modal.componentInstance.object = user + modal.componentInstance.succeeded + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe((newUser: PaperlessUser) => { + if ( + newUser.id === this.settings.currentUser.id && + (modal.componentInstance as UserEditDialogComponent).passwordIsSet + ) { + this.toastService.showInfo( + $localize`Password has been changed, you will be logged out momentarily.` + ) + setTimeout(() => { + window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/` + }, 2500) + } else { + this.toastService.showInfo( + $localize`Saved user "${newUser.username}".` + ) + this.usersService.listAll().subscribe((r) => { + this.users = r.results + }) + } + }) + modal.componentInstance.failed + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe((e) => { + this.toastService.showError($localize`Error saving user.`, e) + }) + } + + deleteUser(user: PaperlessUser) { + let modal = this.modalService.open(ConfirmDialogComponent, { + backdrop: 'static', + }) + modal.componentInstance.title = $localize`Confirm delete user account` + modal.componentInstance.messageBold = $localize`This operation will permanently delete this user account.` + modal.componentInstance.message = $localize`This operation cannot be undone.` + modal.componentInstance.btnClass = 'btn-danger' + modal.componentInstance.btnCaption = $localize`Proceed` + modal.componentInstance.confirmClicked.subscribe(() => { + modal.componentInstance.buttonsEnabled = false + this.usersService.delete(user).subscribe({ + next: () => { + modal.close() + this.toastService.showInfo($localize`Deleted user`) + this.usersService.listAll().subscribe((r) => { + this.users = r.results + }) + }, + error: (e) => { + this.toastService.showError($localize`Error deleting user.`, e) + }, + }) + }) + } + + editGroup(group: PaperlessGroup = null) { + var modal = this.modalService.open(GroupEditDialogComponent, { + backdrop: 'static', + size: 'lg', + }) + modal.componentInstance.dialogMode = group + ? EditDialogMode.EDIT + : EditDialogMode.CREATE + modal.componentInstance.object = group + modal.componentInstance.succeeded + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe((newGroup) => { + this.toastService.showInfo($localize`Saved group "${newGroup.name}".`) + this.groupsService.listAll().subscribe((r) => { + this.groups = r.results + }) + }) + modal.componentInstance.failed + .pipe(takeUntil(this.unsubscribeNotifier)) + .subscribe((e) => { + this.toastService.showError($localize`Error saving group.`, e) + }) + } + + deleteGroup(group: PaperlessGroup) { + let modal = this.modalService.open(ConfirmDialogComponent, { + backdrop: 'static', + }) + modal.componentInstance.title = $localize`Confirm delete user group` + modal.componentInstance.messageBold = $localize`This operation will permanently delete this user group.` + modal.componentInstance.message = $localize`This operation cannot be undone.` + modal.componentInstance.btnClass = 'btn-danger' + modal.componentInstance.btnCaption = $localize`Proceed` + modal.componentInstance.confirmClicked.subscribe(() => { + modal.componentInstance.buttonsEnabled = false + this.groupsService.delete(group).subscribe({ + next: () => { + modal.close() + this.toastService.showInfo($localize`Deleted group`) + this.groupsService.listAll().subscribe((r) => { + this.groups = r.results + }) + }, + error: (e) => { + this.toastService.showError($localize`Error deleting group.`, e) + }, + }) + }) + } + + getGroupName(id: number): string { + return this.groups?.find((g) => g.id === id)?.name ?? '' + } +} diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index 61e7167149..cb4223e331 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -48,6 +48,12 @@ Logout + + + + + + Documentation @@ -80,8 +86,8 @@ -
-
+ -
-
+ - + + + - - -