diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/dependencies.d/init-llmindex-migrate b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-complete/dependencies.d/init-llmindex-migrate new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/dependencies.d/init-migrations b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/dependencies.d/init-migrations new file mode 100644 index 000000000..e69de29bb diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/run new file mode 100755 index 000000000..50fa691c2 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/run @@ -0,0 +1,12 @@ +#!/command/with-contenv /usr/bin/bash +# shellcheck shell=bash + +declare -r log_prefix="[init-llmindex-migrate]" + +echo "${log_prefix} Checking for pending LLM index migrations..." +cd "${PAPERLESS_SRC_DIR}" +if [[ -n "${USER_IS_NON_ROOT}" ]]; then + python3 manage.py document_llmindex migrate +else + s6-setuidgid paperless python3 manage.py document_llmindex migrate +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/type b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/type new file mode 100644 index 000000000..bdd22a185 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/type @@ -0,0 +1 @@ +oneshot diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/up b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/up new file mode 100644 index 000000000..c2016d47a --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/up @@ -0,0 +1 @@ +/etc/s6-overlay/s6-rc.d/init-llmindex-migrate/run diff --git a/docs/administration.md b/docs/administration.md index 8e27df982..fbc636935 100644 --- a/docs/administration.md +++ b/docs/administration.md @@ -212,6 +212,16 @@ following: This is a no-op if the index is already up to date, so it is safe to run on every upgrade. +5. Migrate the LLM index if needed. + + ```shell-session + cd src + python3 manage.py document_llmindex migrate + ``` + + This is a no-op if the index schema is already current, so it is safe + to run on every upgrade. + ### Database Upgrades Paperless-ngx is compatible with Django-supported versions of PostgreSQL and MariaDB and it is generally @@ -532,7 +542,7 @@ index is updated automatically on the schedule set by can manage it manually: ``` -document_llmindex {rebuild,update,compact} +document_llmindex {rebuild,update,compact,migrate} ``` Specify `rebuild` to build the index from scratch from all documents in the database. Use diff --git a/docs/usage.md b/docs/usage.md index e4009cdff..bd03c9a51 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -620,6 +620,34 @@ no other workflow will be executed on the document. If a "Move to Trash" action is executed in a consume pipeline, the consumption will be aborted and the file will be deleted. +##### Password Removal {#workflow-action-password-removal} + +"Password Removal" actions attempt to remove password protection from encrypted PDF documents. You can specify: + +- One or more passwords to try, separated by commas or new lines +- Each password is tried in order until one successfully unlocks the document + +Password removal never modifies a file in place. Instead, once a working password is found, the +decrypted content is consumed as a new [document version](#document-file-versions), leaving the +original (still encrypted) version in the document's version history. + +**Consumption Started**: because this trigger fires before the document exists yet, the password +removal itself is deferred until after the initial consumption of the encrypted file has completed. +OCR engines cannot process an encrypted PDF, so this first version is typically stored with no +extracted text (unless the file already contained extractable text outside of OCR). Immediately +afterwards, the password is removed and the decrypted file is automatically re-consumed as a second, +new version of the same document, this time with normal OCR/text extraction applied. In other words, +a password-protected file added with this trigger will briefly exist as an un-OCR'd version before +the properly processed version is created. + +**Document Added**, **Document Updated**, **Scheduled**: these triggers run against a document that +already exists, so password removal happens immediately: the decrypted content is queued for +consumption as a new version right away. Note that if the document's initial consumption also +happened while it was still encrypted, that original version will likewise be missing OCR text. + +**Current limitation**: Passwords are stored as a simple list without descriptions. To handle +multiple PDF types with different passwords, create separate workflows for each use case. + #### Workflow placeholders Titles and webhook payloads can be generated by workflows using [Jinja templates](https://jinja.palletsprojects.com/en/3.1.x/templates/). diff --git a/src-ui/messages.xlf b/src-ui/messages.xlf index 9e98563f0..4a0607abb 100644 --- a/src-ui/messages.xlf +++ b/src-ui/messages.xlf @@ -659,7 +659,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -831,7 +831,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1355,7 +1355,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1596,7 +1596,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 @@ -1607,7 +1607,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1638,7 +1638,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1669,7 +1669,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1849,7 +1849,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -3972,11 +3972,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 @@ -3987,11 +3987,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 @@ -4002,14 +4002,14 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4020,21 +4020,21 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 @@ -4330,14 +4330,14 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 @@ -4914,7 +4914,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 @@ -7760,14 +7760,14 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -7790,14 +7790,14 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -7808,14 +7808,14 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -7826,147 +7826,147 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 History src/app/components/document-detail/document-detail.component.html - 379 + 383 Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 diff --git a/src-ui/src/app/components/admin/tasks/tasks.component.html b/src-ui/src/app/components/admin/tasks/tasks.component.html index 7fae03a7f..f1220e4b5 100644 --- a/src-ui/src/app/components/admin/tasks/tasks.component.html +++ b/src-ui/src/app/components/admin/tasks/tasks.component.html @@ -21,7 +21,7 @@ -@if (!tasksService.completedFileTasks && tasksService.loading) { +@if (loading() && pagedTasks().length === 0) {
Loading...
} 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 052ea386d..9f8f6fd8d 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 @@ -182,7 +182,7 @@ container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim"> Attributes - @if (!slimSidebarEnabled) { + @if (!slimSidebarEnabled && canSaveSettings) { `, imports: [FormsModule, ReactiveFormsModule], @@ -276,4 +278,22 @@ describe('EditDialogComponent', () => { expect(failedSpy).toHaveBeenCalled() expect(component.error).toEqual('error') }) + + it('should update the view after a failed save', async () => { + const button: HTMLButtonElement = + fixture.nativeElement.querySelector('button') + button.click() + await fixture.whenStable() + expect(button.disabled).toBe(true) + + httpTestingController + .expectOne(`${environment.apiBaseUrl}tags/`) + .flush({ name: ['Name is required.'] }, { status: 400, statusText: '' }) + await fixture.whenStable() + + expect(button.disabled).toBe(false) + expect(fixture.nativeElement.querySelector('.error').textContent).toContain( + 'Name is required.' + ) + }) }) diff --git a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts index 456ba69f9..d9fc611d6 100644 --- a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts +++ b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts @@ -1,4 +1,5 @@ import { + ChangeDetectorRef, Directive, EventEmitter, Input, @@ -45,6 +46,7 @@ export abstract class EditDialogComponent< protected userService = inject(UserService) protected settingsService = inject(SettingsService) protected permissionsService = inject(PermissionsService) + protected changeDetector = inject(ChangeDetectorRef) dialogMode = model(EditDialogMode.CREATE) @@ -108,10 +110,12 @@ export abstract class EditDialogComponent< // wait to enable close button so it doesn't steal focus from input since its the first clickable element in the DOM setTimeout(() => { this.closeEnabled = true + this.changeDetector.markForCheck() }) this.userService.listAll().subscribe((r) => { this.users = r.results + this.changeDetector.markForCheck() }) } @@ -191,6 +195,7 @@ export abstract class EditDialogComponent< this.error = error.error this.networkActive = false this.failed.next(error) + this.changeDetector.markForCheck() }, }) } diff --git a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts index 0e16ac2b2..ffb1fe8b5 100644 --- a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts +++ b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.spec.ts @@ -129,13 +129,25 @@ describe('PngxPdfViewerComponent', () => { ;(component as any).applyScale() expect(viewer.currentScaleValue).toBe(PdfZoomScale.PageFit) expect(viewer.currentScale).toBe(2) + }) + it('does not reapply scale for page-only changes', async () => { + await initComponent() + + const pdf = (component as any).pdf as { numPages: number } + pdf.numPages = 3 + const viewer = (component as any).pdfViewer as PDFViewer + viewer.setDocument(pdf) const applyScaleSpy = jest.spyOn(component as any, 'applyScale') component.page = 2 - ;(component as any).lastViewerPage = 2 - ;(component as any).applyViewerState() + + component.ngOnChanges({ + page: new SimpleChange(1, 2, false), + }) + + expect(viewer.currentPageNumber).toBe(2) expect((component as any).lastViewerPage).toBeUndefined() - expect(applyScaleSpy).toHaveBeenCalled() + expect(applyScaleSpy).not.toHaveBeenCalled() }) it('does not reset the viewer when it is already on the requested page', async () => { diff --git a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts index 4a0478316..153c67d91 100644 --- a/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts +++ b/src-ui/src/app/components/common/pdf-viewer/pdf-viewer.component.ts @@ -116,7 +116,10 @@ export class PngxPdfViewerComponent changes['zoomScale'] || changes['rotation'] ) { - this.applyViewerState() + // Prevent loop with page / scale application see https://github.com/paperless-ngx/paperless-ngx/issues/13404 + this.applyViewerState( + !!(changes['zoom'] || changes['zoomScale'] || changes['rotation']) + ) } if (changes['searchQuery']) { @@ -240,7 +243,7 @@ export class PngxPdfViewerComponent } } - private applyViewerState(): void { + private applyViewerState(applyScale = true): void { if (!this.pdfViewer) { return } @@ -264,7 +267,7 @@ export class PngxPdfViewerComponent if (this.page === this.lastViewerPage) { this.lastViewerPage = undefined } - if (hasPages) { + if (hasPages && applyScale) { this.applyScale() } this.dispatchFindIfReady() diff --git a/src-ui/src/app/components/document-detail/document-detail.component.html b/src-ui/src/app/components/document-detail/document-detail.component.html index 6ee6b442a..664fa950c 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.html +++ b/src-ui/src/app/components/document-detail/document-detail.component.html @@ -113,8 +113,8 @@
-
-
+
+
@@ -127,32 +127,36 @@
-
- - +
+
+ + +
+ +
+ + +
-
- - +
+
- -
-
+
@@ -440,7 +444,7 @@
-
+
@if (hasNext()) { diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts index 7cc8f3638..1cf05b781 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.spec.ts @@ -2269,4 +2269,34 @@ describe('FilterEditorComponent', () => { component.itemSelected({ item: 'world', preventDefault: () => true }) expect(component.textFilter).toEqual('hello world ') }) + + it('should choose the active autocomplete item with Enter', () => { + component.textFilterTarget = 'fulltext-query' + jest + .spyOn(searchService, 'autocomplete') + .mockReturnValue(of(['hello', 'help'])) + + const input = component.textFilterInput.nativeElement as HTMLInputElement + input.value = 'he' + input.dispatchEvent(new Event('input')) + tick(250) + + input.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'ArrowDown', + bubbles: true, + cancelable: true, + }) + ) + input.dispatchEvent( + new KeyboardEvent('keydown', { + key: 'Enter', + bubbles: true, + cancelable: true, + }) + ) + fixture.detectChanges() + + expect(component.textFilter).toEqual('help ') + }) }) diff --git a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts index 5566f9ecd..d747002b2 100644 --- a/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts +++ b/src-ui/src/app/components/document-list/filter-editor/filter-editor.component.ts @@ -1314,6 +1314,10 @@ export class FilterEditorComponent textFilterKeydown(event: KeyboardEvent) { if (event.key == 'Enter') { + if (event.defaultPrevented) { + // NgbTypeahead calls preventDefault, so use that to detect if the Enter key was for the dropdown + return + } const filterString = ( this.textFilterInput.nativeElement as HTMLInputElement ).value diff --git a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.html b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.html index da6077039..38f449956 100644 --- a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.html +++ b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.html @@ -51,8 +51,8 @@ *pngxIfPermissions="{ action: PermissionAction.Add, type: activeManagementList.permissionType }"> Create - } @else if (activeCustomFields) { - diff --git a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.spec.ts b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.spec.ts index 97a8bfd1f..b40c35692 100644 --- a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.spec.ts +++ b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.spec.ts @@ -18,6 +18,7 @@ import { DocumentAttributesComponent, DocumentAttributesSectionKind, } from './document-attributes.component' +import { CustomFieldsComponent } from './custom-fields/custom-fields.component' import { ManagementListComponent } from './management-list/management-list.component' @Component({ @@ -207,6 +208,29 @@ describe('DocumentAttributesComponent', () => { expect(component.activeSection.kind).toBe( DocumentAttributesSectionKind.CustomFields ) - expect(component.activeCustomFields).toBeDefined() + const customFields = Object.create(CustomFieldsComponent.prototype) + customFields.editField = jest.fn() + component.activeOutlet = { + componentInstance: customFields, + } as any + expect(component.activeCustomFields).toBe(customFields) + + component.addCustomField() + expect(customFields.editField).toHaveBeenCalled() + }) + + it('should show the add field button before the custom fields instance is available', async () => { + jest.spyOn(permissionsService, 'currentUserCan').mockReturnValue(true) + + fixture.detectChanges() + component.activeNavID.set(2) + await fixture.whenStable() + + expect(component.activeCustomFields).toBeNull() + expect( + fixture.nativeElement.querySelector( + 'pngx-page-header .btn-outline-primary' + )?.textContent + ).toContain('Add Field') }) }) diff --git a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts index 482149ff0..0ff747407 100644 --- a/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts +++ b/src-ui/src/app/components/manage/document-attributes/document-attributes.component.ts @@ -163,12 +163,17 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy { } get activeCustomFields(): CustomFieldsComponent | null { - if (this.activeSection?.kind !== DocumentAttributesSectionKind.CustomFields) - return null + if (!this.customFieldsActive) return null const instance = this.activeOutlet?.componentInstance return instance instanceof CustomFieldsComponent ? instance : null } + get customFieldsActive(): boolean { + return ( + this.activeSection?.kind === DocumentAttributesSectionKind.CustomFields + ) + } + get activeTabLabel(): string { return this.activeSection?.label ?? '' } @@ -224,6 +229,10 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy { this.router.navigate(['attributes', nextSection]) } + addCustomField(): void { + this.activeCustomFields?.editField(null) + } + private getDefaultNavID(): DocumentAttributesNavIDs | null { return this.visibleSections[0]?.id ?? null } diff --git a/src-ui/src/app/services/tasks.service.spec.ts b/src-ui/src/app/services/tasks.service.spec.ts index 3412ae2ce..c8dca41fb 100644 --- a/src-ui/src/app/services/tasks.service.spec.ts +++ b/src-ui/src/app/services/tasks.service.spec.ts @@ -50,13 +50,66 @@ describe('TasksService', () => { req.flush({ count: 0, results: [] }) }) - it('does not call tasks api endpoint on reload if already loading', () => { - tasksService.loading = true + it('cancels an in-progress reload when reloading again', () => { tasksService.reload() - httpTestingController.expectNone( + const staleReload = httpTestingController.expectOne( (req: HttpRequest) => req.url === `${environment.apiBaseUrl}tasks/` ) + tasksService.reload() + + expect(staleReload.cancelled).toBe(true) + httpTestingController + .expectOne( + (req: HttpRequest) => + req.url === `${environment.apiBaseUrl}tasks/` + ) + .flush({ count: 0, results: [] }) + }) + + it('continues reloading after a reload request fails', () => { + tasksService.reload() + httpTestingController + .expectOne( + (req: HttpRequest) => + req.url === `${environment.apiBaseUrl}tasks/` + ) + .flush('error', { status: 500, statusText: 'error' }) + + expect(tasksService.loading).toBe(false) + + tasksService.reload() + httpTestingController + .expectOne( + (req: HttpRequest) => + req.url === `${environment.apiBaseUrl}tasks/` + ) + .flush({ count: 0, results: [] }) + }) + + it('reloads after dismissing a task while a reload is already in progress', () => { + tasksService.reload() + const staleReload = httpTestingController.expectOne( + (req: HttpRequest) => + req.url === `${environment.apiBaseUrl}tasks/` && + req.params.get('acknowledged') === 'false' + ) + + tasksService.dismissTasks(new Set([1])).subscribe() + httpTestingController + .expectOne(`${environment.apiBaseUrl}tasks/acknowledge/`) + .flush([]) + + expect(staleReload.cancelled).toBe(true) + httpTestingController + .expectOne( + (req: HttpRequest) => + req.url === `${environment.apiBaseUrl}tasks/` && + req.params.get('acknowledged') === 'false' + ) + .flush({ count: 0, results: [] }) + + expect(tasksService.needsAttentionTasks).toHaveLength(0) }) it('calls acknowledge_tasks api endpoint on dismiss and reloads', () => { @@ -101,79 +154,6 @@ describe('TasksService', () => { .flush({ count: 0, results: [] }) }) - it('groups mixed task types by status when reloading', () => { - expect(tasksService.total).toEqual(0) - const mockTasks = [ - { - task_type: PaperlessTaskType.ConsumeFile, - trigger_source: PaperlessTaskTriggerSource.FolderConsume, - status: PaperlessTaskStatus.Success, - acknowledged: false, - task_id: '1234', - input_data: { filename: 'file1.pdf' }, - date_created: new Date(), - related_document_ids: [], - }, - { - task_type: PaperlessTaskType.SanityCheck, - trigger_source: PaperlessTaskTriggerSource.System, - status: PaperlessTaskStatus.Failure, - acknowledged: false, - task_id: '1235', - input_data: {}, - date_created: new Date(), - related_document_ids: [], - }, - { - task_type: PaperlessTaskType.MailFetch, - trigger_source: PaperlessTaskTriggerSource.Scheduled, - status: PaperlessTaskStatus.Pending, - acknowledged: false, - task_id: '1236', - input_data: {}, - date_created: new Date(), - related_document_ids: [], - }, - { - task_type: PaperlessTaskType.LlmIndex, - trigger_source: PaperlessTaskTriggerSource.WebUI, - status: PaperlessTaskStatus.Started, - acknowledged: false, - task_id: '1237', - input_data: {}, - date_created: new Date(), - related_document_ids: [], - }, - { - task_type: PaperlessTaskType.EmptyTrash, - trigger_source: PaperlessTaskTriggerSource.Manual, - status: PaperlessTaskStatus.Success, - acknowledged: false, - task_id: '1238', - input_data: {}, - date_created: new Date(), - related_document_ids: [], - }, - ] - - tasksService.reload() - - const req = httpTestingController.expectOne( - (req: HttpRequest) => - req.url === `${environment.apiBaseUrl}tasks/` && - req.params.get('acknowledged') === 'false' && - req.params.get('page_size') === '1000' - ) - - req.flush({ count: mockTasks.length, results: mockTasks }) - - expect(tasksService.allFileTasks).toHaveLength(5) - expect(tasksService.completedFileTasks).toHaveLength(2) - expect(tasksService.failedFileTasks).toHaveLength(1) - expect(tasksService.queuedFileTasks).toHaveLength(1) - expect(tasksService.startedFileTasks).toHaveLength(1) - }) - it('includes revoked tasks in needs attention', () => { const mockTasks = [ { diff --git a/src-ui/src/app/services/tasks.service.ts b/src-ui/src/app/services/tasks.service.ts index 8b71c6923..189d3ac62 100644 --- a/src-ui/src/app/services/tasks.service.ts +++ b/src-ui/src/app/services/tasks.service.ts @@ -1,7 +1,15 @@ import { HttpClient } from '@angular/common/http' import { Injectable, inject, signal } from '@angular/core' -import { Observable, Subject } from 'rxjs' -import { first, map, takeUntil, tap } from 'rxjs/operators' +import { EMPTY, Observable, Subject } from 'rxjs' +import { + catchError, + finalize, + first, + map, + switchMap, + takeUntil, + tap, +} from 'rxjs/operators' import { PaperlessTask, PaperlessTaskStatus, @@ -23,44 +31,40 @@ export class TasksService { public loading: boolean = false - private readonly fileTasks = signal([]) + private readonly tasks = signal([]) + private readonly reloadNotifier = new Subject() private unsubscribeNotifer: Subject = new Subject() - public get total(): number { - return this.fileTasks().length - } - - public get allFileTasks(): PaperlessTask[] { - return this.fileTasks().slice(0) - } - - public get queuedFileTasks(): PaperlessTask[] { - return this.fileTasks().filter( - (t) => t.status === PaperlessTaskStatus.Pending - ) - } - - public get startedFileTasks(): PaperlessTask[] { - return this.fileTasks().filter( - (t) => t.status === PaperlessTaskStatus.Started - ) - } - - public get completedFileTasks(): PaperlessTask[] { - return this.fileTasks().filter( - (t) => t.status === PaperlessTaskStatus.Success - ) - } - - public get failedFileTasks(): PaperlessTask[] { - return this.fileTasks().filter( - (t) => t.status === PaperlessTaskStatus.Failure - ) + constructor() { + this.reloadNotifier + .pipe( + switchMap(() => { + this.loading = true + return this.http + .get>(`${this.baseUrl}${this.endpoint}/`, { + params: { + acknowledged: 'false', + page_size: this.defaultReloadPageSize, + }, + }) + .pipe( + map((response) => response.results), + takeUntil(this.unsubscribeNotifer), + catchError(() => EMPTY), + finalize(() => { + this.loading = false + }) + ) + }) + ) + .subscribe((tasks) => { + this.tasks.set(tasks) + }) } public get needsAttentionTasks(): PaperlessTask[] { - return this.fileTasks().filter((t) => + return this.tasks().filter((t) => [PaperlessTaskStatus.Failure, PaperlessTaskStatus.Revoked].includes( t.status ) @@ -68,22 +72,7 @@ export class TasksService { } public reload() { - if (this.loading) return - this.loading = true - - this.http - .get>(`${this.baseUrl}${this.endpoint}/`, { - params: { - acknowledged: 'false', - page_size: this.defaultReloadPageSize, - }, - }) - .pipe(map((r) => r.results)) - .pipe(takeUntil(this.unsubscribeNotifer), first()) - .subscribe((r) => { - this.fileTasks.set(r) - this.loading = false - }) + this.reloadNotifier.next() } public list( diff --git a/src-ui/src/locale/messages.af_ZA.xlf b/src-ui/src/locale/messages.af_ZA.xlf index 76313c092..22e6b34c6 100644 --- a/src-ui/src/locale/messages.af_ZA.xlf +++ b/src-ui/src/locale/messages.af_ZA.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Argiefreeksnommer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Skep nuwe item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Wysig item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Voorskou @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Datum geskep @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Inhoud @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum gewysig @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum toegevoeg @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Medialêernaam @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Oorspronklike lêernaam @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Oorspronklike lêergrootte @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Oorspronklike MIME-tipe @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Lêergrootteargief @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Oorspronklike dokumentmetadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Geargiveerdedokumentmetadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Bewaar & volgende @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Verwerp @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Voer wagwoord in diff --git a/src-ui/src/locale/messages.am_ET.xlf b/src-ui/src/locale/messages.am_ET.xlf index ec754323e..9246da961 100644 --- a/src-ui/src/locale/messages.am_ET.xlf +++ b/src-ui/src/locale/messages.am_ET.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date created @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Content @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date modified @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date added @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archive file size @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.ar_AR.xlf b/src-ui/src/locale/messages.ar_AR.xlf index 874492637..082f4a525 100644 --- a/src-ui/src/locale/messages.ar_AR.xlf +++ b/src-ui/src/locale/messages.ar_AR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 الرقم التسلسلي للأرشيف @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 إنشاء عنصر جديد @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 تعديل عنصر @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 معاينة @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 تفاصيل @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 تاريخ الإنشاء @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 محتوى @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 تاريخ التعديل @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 تاريخ الإضافة @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 اسم ملف الوسائط @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 اسم الملف الأصلي @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 حجم الملف الأصلي @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 نوع mime الأصلي @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 حجم ملف الأرشيف @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 بيانات التعريف للمستند الأصلي @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 بيانات التعريف للمستند الأصلي @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 السجل التاريخي @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 حفظ & التالي @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 حفظ وإغلاق @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 تجاهل @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 أدخل كلمة المرور diff --git a/src-ui/src/locale/messages.be_BY.xlf b/src-ui/src/locale/messages.be_BY.xlf index d67d55b63..7e8750058 100644 --- a/src-ui/src/locale/messages.be_BY.xlf +++ b/src-ui/src/locale/messages.be_BY.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Парадкавы нумар архіва @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Стварыць новы элемент @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Рэдагаваць элемент @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Падрабязнасці @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Дата стварэння @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Змест @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Дата змянення @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Дата дадання @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Імя медыяфайла @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Арыгінальная назва файла @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Арыгінальны памер файла @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Арыгінальны MIME тып @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Памер файла архіва @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Арыгінальныя метададзеныя дакумента @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Метададзеныя архіўнага дакумента @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Захаваць & наступны @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Адхіліць @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Увядзіце пароль diff --git a/src-ui/src/locale/messages.bg_BG.xlf b/src-ui/src/locale/messages.bg_BG.xlf index 5261212f7..d5c65d715 100644 --- a/src-ui/src/locale/messages.bg_BG.xlf +++ b/src-ui/src/locale/messages.bg_BG.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Сериен номер на архива @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Правилно @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Грешно @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Търсене в документи... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Не @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Добавете заявка @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Добавете израз @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Създаване на нов елемент @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Редактиране на елемент @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Преглед @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Подробности @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Дата на създаване @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Съдържание @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Дата на промяна @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Дата на добавяне @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Име на медиен файл @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Оригинално име на файла @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Оригинален размер на файла @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Оригинален mime тип @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Размер на архива @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Оригинални метаданни на документ @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Архивирани метаданни на документа @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 История @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Запази & следващото @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Запази & затвори @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Откажи @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Зареждане на документи... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Въведете парола diff --git a/src-ui/src/locale/messages.ca_ES.xlf b/src-ui/src/locale/messages.ca_ES.xlf index 99ac128b4..6d6beb0e7 100644 --- a/src-ui/src/locale/messages.ca_ES.xlf +++ b/src-ui/src/locale/messages.ca_ES.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Número de sèrie de l'arxiu @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Vertader @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Fals @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Cerca docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 No @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Afegir consulta @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Afegir expressió @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Crea element nou @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edita element @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Vista prèvia @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalls @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data de creació @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Contingut @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data modificació @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data afegit @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nom Arxiu @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nom arxiu original @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Mida arxiu original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tipus mímic original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Mida arxiu arxivat @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadades del document original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadades del document arxivat @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historial @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Detectats documents duplicats: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 A la brossa @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Desa i següent @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Desa i tanca @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Descarta @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document carregant... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Introdueix Contrasenya diff --git a/src-ui/src/locale/messages.cs_CZ.xlf b/src-ui/src/locale/messages.cs_CZ.xlf index 9f2b8dbce..7c0809298 100644 --- a/src-ui/src/locale/messages.cs_CZ.xlf +++ b/src-ui/src/locale/messages.cs_CZ.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Sériové číslo archivu @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Pravda @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Nepravda @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Hledat dokumenty... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Není @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Přidat dotaz @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Přidat výraz @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Vytvořit novou položku @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Upravit položku @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Náhled @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Podrobnosti @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Vytvořeno @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Obsah @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum úpravy @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum přidání @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Název souboru @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Původní název souboru @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Původní kontrolní součet SHA256 @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Původní velikost souboru @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Původní typ mime @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archivní kontrolní součet SHA256 @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Velikost souboru archivu @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadata původního dokumentu @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadata archivovaného dokumentu @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Poznámky @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historie @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Zjištěny duplicitní dokumenty: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 V koši @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Uložit a další @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Uložit a zavřít @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Zrušit @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Načítání dokumentu... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Zadejte heslo diff --git a/src-ui/src/locale/messages.da_DK.xlf b/src-ui/src/locale/messages.da_DK.xlf index bcc0b4201..90db31ba6 100644 --- a/src-ui/src/locale/messages.da_DK.xlf +++ b/src-ui/src/locale/messages.da_DK.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arkiv serienummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Opret nyt element @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Redigér element @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detaljer @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Oprettelsesdato @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Indhold @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Ændringsdato @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Tilføjelsesdato @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Filnavn for medie @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original filstørrelse @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mimetype @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arkiv filstørrelse @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original dokumentmetadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arkiveret dokumentmetadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Gem & næste @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Forkast @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Indtast adgangskode diff --git a/src-ui/src/locale/messages.de_CH.xlf b/src-ui/src/locale/messages.de_CH.xlf index 1d57c79cc..4c0d65652 100644 --- a/src-ui/src/locale/messages.de_CH.xlf +++ b/src-ui/src/locale/messages.de_CH.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archiv-Seriennummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Wahr @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falsch @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Suche Dokumente... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nicht @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Abfrage hinzufügen @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Ausdruck hinzufügen @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Neues Element erstellen @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Element bearbeiten @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Vorschau @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Ausstellungsdatum @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Inhalt @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Geändert am @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Hinzugefügt am @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media-Dateiname @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Ursprünglicher Dateiname @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Dateigrösse Original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 MIME-Typ Original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Dateigrösse Archiv @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadaten Original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadaten Archiv @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Verlauf @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Doppelte Dokumente erkannt: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 Im Papierkorb @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Speichern & weiter @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Speichern & schliessen @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Verwerfen @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokument wird geladen... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Kennwort eingeben diff --git a/src-ui/src/locale/messages.de_DE.xlf b/src-ui/src/locale/messages.de_DE.xlf index d9cee2ef8..caa2441f7 100644 --- a/src-ui/src/locale/messages.de_DE.xlf +++ b/src-ui/src/locale/messages.de_DE.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archiv-Seriennummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -2514,13 +2514,13 @@ E-Mail-Abruf - + LLM Index src/app/components/admin/tasks/tasks.component.ts 77 - LLM-Indizierung + LLM-Indizierung Empty Trash @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Wahr @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falsch @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Suche Dokumente... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nicht @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Abfrage hinzufügen @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Ausdruck hinzufügen @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Neues Element erstellen @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Element bearbeiten @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Vorschau @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Ausstellungsdatum @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Inhalt @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Geändert am @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Hinzugefügt am @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media-Dateiname @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Ursprünglicher Dateiname @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256-Prüfsumme @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Dateigröße Original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 MIME-Typ Original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archiv SHA256-Prüfsumme @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Dateigröße Archiv @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadaten Original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadaten Archiv @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notizen @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Verlauf @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplikate @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Doppelte Dokumente erkannt: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 Im Papierkorb @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Speichern & weiter @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Speichern & schließen @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Verwerfen @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokument wird geladen... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Kennwort eingeben diff --git a/src-ui/src/locale/messages.el_GR.xlf b/src-ui/src/locale/messages.el_GR.xlf index 8bbb7df98..944390346 100644 --- a/src-ui/src/locale/messages.el_GR.xlf +++ b/src-ui/src/locale/messages.el_GR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Αρχειοθέτηση σειριακού αριθμού @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Δημιουργία νέου αντικειμένου @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Επεξεργασία αντικειμένου @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Προεπισκόπηση @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Λεπτομέρειες @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Ημερομηνία δημιουργίας @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Περιεχόμενο @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Ημερομηνία τροποποίησης @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Ημερομηνία προσθήκης @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Όνομα αρχείου πολυμέσων @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Πρωτότυπο όνομα αρχείου @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Αρχικό μέγεθος αρχείου @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Αρχικός τύπος mime @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Μέγεθος αρχείου αρχειοθέτησης @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Πρωτότυπα μεταδεδομένα εγγράφου @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Αρχειοθετημένα μεταδεδομένα εγγράφου @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Αποθήκευση & επόμενο @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Αποθήκευση & κλείσιμο @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Απόρριψη @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Εισαγωγή Κωδικού Πρόσβασης diff --git a/src-ui/src/locale/messages.es_ES.xlf b/src-ui/src/locale/messages.es_ES.xlf index 0fb69954d..f93394311 100644 --- a/src-ui/src/locale/messages.es_ES.xlf +++ b/src-ui/src/locale/messages.es_ES.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Número de serie del archivo @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Verdadero @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falso @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Buscar documentos... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 No @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Añadir consulta @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Añadir expresión @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Crear nuevo elemento @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Editar elemento @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Vista previa @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalles @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Fecha de creación @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Contenido @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Fecha de modificación @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Fecha de subida @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nombre del fichero @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nombre del archivo original @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Tamaño del fichero original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tipo MIME original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Tamaño del archivo @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadatos originales @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadatos archivados @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historial @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Guardar y continuar @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Guardar & cerrar @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Descartar @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Cargando documento... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Introducir contraseña diff --git a/src-ui/src/locale/messages.et_EE.xlf b/src-ui/src/locale/messages.et_EE.xlf index ac8f53027..63d06dc37 100644 --- a/src-ui/src/locale/messages.et_EE.xlf +++ b/src-ui/src/locale/messages.et_EE.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date created @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Content @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date modified @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date added @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archive file size @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.fa_IR.xlf b/src-ui/src/locale/messages.fa_IR.xlf index a19cb6368..36f4db36f 100644 --- a/src-ui/src/locale/messages.fa_IR.xlf +++ b/src-ui/src/locale/messages.fa_IR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 شماره سریال بایگانی @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 درست @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 دروغ @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 اسناد جستجو ... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 نه @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 اضافه کردن پرس و جو @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 بیان را اضافه کنید @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 مورد جدید ایجاد کنید @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 مورد ویرایش @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 پیش نمایش @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 جزئیات @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 تاریخ ایجاد شده @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 محتوا @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 تاریخ اصلاح شده @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 تاریخ اضافه شده @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 نام رسانه @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 نام اصلی @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 اندازه پرونده اصلی @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 نوع اصلی تقلید @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 اندازه پرونده بایگانی @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 ابرداده سند اصلی @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 ابرداده سند بایگانی شده @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 تاریخ @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 دور کردن @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 بارگیری سند ... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 رمز ورود را وارد کنید diff --git a/src-ui/src/locale/messages.fi_FI.xlf b/src-ui/src/locale/messages.fi_FI.xlf index 3211cc0f3..12a47d983 100644 --- a/src-ui/src/locale/messages.fi_FI.xlf +++ b/src-ui/src/locale/messages.fi_FI.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arkistointisarjanumero @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Tosi @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Epätosi @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Luo uusi @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Muokkaa @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Esikatsele @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Tarkemmat tiedot @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Luontipäivä @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Sisältö @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Muokkauspäivämäärä @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Lisäyspäivämäärä @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Median tiedostonimi @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Alkuperäinen tiedoston nimi @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Alkuperäinen tiedostokoko @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Alkuperäinen mime-tyyppi @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arkistoidun tiedostokoko @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Alkuperäisen asiakirjan metatiedot @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arkistoidun asiakirjan metatiedot @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historia @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Tallenna & Lopeta @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Tallenna ja sulje @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Hylkää @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Asiakirja latautuu... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Syötä salasana diff --git a/src-ui/src/locale/messages.fr_FR.xlf b/src-ui/src/locale/messages.fr_FR.xlf index cbea53f8c..57928d303 100644 --- a/src-ui/src/locale/messages.fr_FR.xlf +++ b/src-ui/src/locale/messages.fr_FR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Numéro de série d'archivage (NSA) @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Vrai @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Faux @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Rechercher un document... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Non @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Ajouter une requête @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Ajouter une expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Créer un nouvel élément @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Modifier l'élément @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Prévisualisation @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Détails @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date de création @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Contenu @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date de modification @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date d'ajout @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nom de fichier du média @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nom du fichier d'origine @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Somme de contrôle SHA256 de l'original @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Taille du fichier original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Type MIME de l'original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Somme de contrôle SHA256 de l'archive @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Taille du fichier archivé @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Métadonnées du document original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Métadonnées du document archivé @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historique @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Documents en double détectés : @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 Dans la corbeille @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Enregistrer & suivant @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Enregister & fermer @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Abandonner @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Chargement du document… @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Saisir le mot de passe diff --git a/src-ui/src/locale/messages.he_IL.xlf b/src-ui/src/locale/messages.he_IL.xlf index abe5c7794..cc9a36572 100644 --- a/src-ui/src/locale/messages.he_IL.xlf +++ b/src-ui/src/locale/messages.he_IL.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 מספר סידורי בארכיון @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 אמת @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 שקר @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 חפש מסמכים... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 לא @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 הוסף שאילתה @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 הוסף ביטוי @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 יצירת פריט חדש @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 עריכת פריט @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 תצוגה מקדימה @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 פרטים @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 תאריך יצירה @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 תוכן @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 תאריך שינוי @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 תאריך הוספה @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 שם קובץ המסמך @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 שם קובץ מקורי @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 גודל הקובץ המקורי @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 סוג ה-mime המקורי @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 גודל הקובץ בארכיון @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 מטא-נתונים של המסמך המקורי @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 מטא-נתונים של המסמך בארכיון @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 היסטוריה @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 שמור & הבא @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 שמור & סגור @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 בטל @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 מסמך נטען... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 הזן סיסמה diff --git a/src-ui/src/locale/messages.hi_IN.xlf b/src-ui/src/locale/messages.hi_IN.xlf index 2061b6cf9..1fc1addfd 100644 --- a/src-ui/src/locale/messages.hi_IN.xlf +++ b/src-ui/src/locale/messages.hi_IN.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date created @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Content @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date modified @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date added @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archive file size @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.hr_HR.xlf b/src-ui/src/locale/messages.hr_HR.xlf index 141982415..767abf30a 100644 --- a/src-ui/src/locale/messages.hr_HR.xlf +++ b/src-ui/src/locale/messages.hr_HR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Serijski broj pohrane @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Točno @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Netočno @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Traži dokumente... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Dodaj upit @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Dodaj izraz @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Stvori novu stavku @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Uredi stavku @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Predpregled @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalji @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Datum izrade @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Sadržaj @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum izmjene @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum dodavanja @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Naziv datoteke @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Izvorni naziv datoteke @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Izvorna veličina datoteke @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Izvorna MIME vrsta @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Veličina arhivirane datoteke @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Izvorni meta podaci dokumenta @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Meta podaci arhiviranog dokumenta @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Povijest @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Otkriveni duplikati dokumenata: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 U smeću @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Spremi & sljedeći @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Spremi & zatvori @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Odbaci @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokument se učitava... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Unesi lozinku diff --git a/src-ui/src/locale/messages.hu_HU.xlf b/src-ui/src/locale/messages.hu_HU.xlf index af215dc2f..f36015c8a 100644 --- a/src-ui/src/locale/messages.hu_HU.xlf +++ b/src-ui/src/locale/messages.hu_HU.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archívum sorszáma @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Igaz @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Hamis @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Keresés a dokumentumokban... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nem @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Lekérdezés hozzáadása @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Kifejezés hozzáadása @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Új elem létrehozása @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Elem szerkesztése @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Előnézet @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Részletek @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Létrehozás dátuma @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Tartalom @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Módosított dátum @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Hozzáadás dátuma @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Média fájlnév @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Eredeti fájlnév @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Eredeti fájlméret @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Eredeti mime típus @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archivált fájl mérete @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Eredeti dokumentum metaadatai @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archivált dokumentum metaadatok @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Előzmények @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Mentés & következő @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Mentés & bezárás @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Eldob @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokumentum betöltése... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Jelszó megadása diff --git a/src-ui/src/locale/messages.id_ID.xlf b/src-ui/src/locale/messages.id_ID.xlf index e1ba0c30d..e8ebadbc9 100644 --- a/src-ui/src/locale/messages.id_ID.xlf +++ b/src-ui/src/locale/messages.id_ID.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Nomor serial arsip @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Benar @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Salah @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Cari dokumen... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Tidak @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Tambah permintaan @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Tambah ekspresi @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Buat barang baru @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Sunting barang @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Pratinjau @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Rincian @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Tanggal dibuat @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Konten @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Tanggal dimodifikasi @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Tanggal ditambahkan @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nama Berkas Media @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nama file asli @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Ukuran file asli @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Jenis mime asli @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Ukuran file arsip @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadata dokumen asli @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadata dokumen arsip @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Riwayat @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Simpan & lanjut @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Simpan & tutup @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Batalkan @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Memuat dokumen... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Masukan Kata Sandi diff --git a/src-ui/src/locale/messages.it_IT.xlf b/src-ui/src/locale/messages.it_IT.xlf index 5a1f2769d..86c8e2d75 100644 --- a/src-ui/src/locale/messages.it_IT.xlf +++ b/src-ui/src/locale/messages.it_IT.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Numero seriale di archivio @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Vero @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falso @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Cerca documenti... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Non @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Aggiungi query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Aggiungi espressione @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Crea nuovo elemento @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Modifica elemento @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Anteprima @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Dettagli @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data creazione @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Contenuto @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data modifica @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data aggiunta @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nome file @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nome file originale @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Checksum SHA256 originale @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Dimensione file originale @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tipo mime originale @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Checksum SHA256 dell'archivio @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Dimensione file archivio @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadati del documento originale @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadati del documento archiviato @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Note @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Cronologia @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicati @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Documenti duplicati rilevati: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 Nel cestino @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Salva e vai al prossimo @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Salva e chiudi @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Scarta @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Caricamento documento in corso... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Inserisci password diff --git a/src-ui/src/locale/messages.ja_JP.xlf b/src-ui/src/locale/messages.ja_JP.xlf index 5ba9f2188..f1e2c7c64 100644 --- a/src-ui/src/locale/messages.ja_JP.xlf +++ b/src-ui/src/locale/messages.ja_JP.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 アーカイブ番号 @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 ドキュメントを検索... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 クエリの追加 @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 式の追加 @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 新規アイテムの作成 @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 アイテムの編集 @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 プレビュー @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 詳細 @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 作成日 @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 内容 @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 更新日 @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 追加日 @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 メディアファイル名 @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 元のファイル名 @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 元のファイルサイズ @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 元の MIME タイプ @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 アーカイブのファイルサイズ @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 元のドキュメントのメタデータ @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 アーカイブされたドキュメントのメタデータ @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 履歴 @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 保存して次へ @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 保存して閉じる @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 破棄 @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 ドキュメントを読み込んでいます... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 パスワードを入力 diff --git a/src-ui/src/locale/messages.ko_KR.xlf b/src-ui/src/locale/messages.ko_KR.xlf index dab8a691b..23b6f74cb 100644 --- a/src-ui/src/locale/messages.ko_KR.xlf +++ b/src-ui/src/locale/messages.ko_KR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 보관 일련 번호 @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 거짓 @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 문서 검색... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 아님 @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 쿼리 추가 @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 표현식 추가 @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 새로운 아이템 생성 @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 아이템 수정 @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 미리보기 @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 세부 사항 @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 작성 날짜 @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 내용 @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 수정 날짜 @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 추가된 날짜 @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 미디어 파일명 @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 원본 파일명 @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 원본 파일 사이즈 @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 원본 MIME 타입 @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 파일 사이즈 기록 @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 원본 문서 메타데이터 @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 문서 메타데이터 기록됨 @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 이력 @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 저장 후 다음 @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 저장 후 닫기 @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 폐기 @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 문서 로딩 중... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 비밀번호 입력 diff --git a/src-ui/src/locale/messages.lb_LU.xlf b/src-ui/src/locale/messages.lb_LU.xlf index bfc412d7c..7b9ca1563 100644 --- a/src-ui/src/locale/messages.lb_LU.xlf +++ b/src-ui/src/locale/messages.lb_LU.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archiv-Seriennummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Wouer @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falsch @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Dokumenter sichen... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Neit Element erstellen @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Element beaarbechten @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detailer @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Erstellungsdatum @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Inhalt @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Verännert um @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Dobäigesat um @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Dateinumm vum Mediefichier @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original Dateinumm @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Dateigréisst vum Original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Urspréngleche MIME-Typ @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archiv-Dateigréisst @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadate vum Original-Dokument @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadate vum Archiv-Dokument @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Späicheren a weider @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Verwerfen @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Passwuert aginn diff --git a/src-ui/src/locale/messages.lt_LT.xlf b/src-ui/src/locale/messages.lt_LT.xlf index e92debeb7..b68a17dbe 100644 --- a/src-ui/src/locale/messages.lt_LT.xlf +++ b/src-ui/src/locale/messages.lt_LT.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archyvo serijinis numeris @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Išsamiau @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Sukūrimo data @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Turinys @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Pakeitimo data @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Pridėta data @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Medijos bylos pavadinimas @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Originalus bylos pavadinimas @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Originalus bylos pavadinimas @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Originalus MIME tipas @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archyvo bylos dydis @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Originalaus dokumento metaduomenys @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archyvuotų dokumentų metaduomenys @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Istorija @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Atmesti @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Įveskite slaptažodį diff --git a/src-ui/src/locale/messages.lv_LV.xlf b/src-ui/src/locale/messages.lv_LV.xlf index c92b42762..c140588f1 100644 --- a/src-ui/src/locale/messages.lv_LV.xlf +++ b/src-ui/src/locale/messages.lv_LV.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Sīkāka informācija @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Izveides datums @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Saturs @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Labošanas datums @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Pievienošanas datums @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arhīva faila izmērs @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arhivētā dokumenta metadati @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.mk_MK.xlf b/src-ui/src/locale/messages.mk_MK.xlf index d1544d27a..3ed6127c0 100644 --- a/src-ui/src/locale/messages.mk_MK.xlf +++ b/src-ui/src/locale/messages.mk_MK.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date created @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Content @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date modified @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date added @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archive file size @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.ms_MY.xlf b/src-ui/src/locale/messages.ms_MY.xlf index 9d8258c40..12a706d19 100644 --- a/src-ui/src/locale/messages.ms_MY.xlf +++ b/src-ui/src/locale/messages.ms_MY.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archive serial number @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Preview @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Date created @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Content @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Date modified @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Date added @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filename @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Original filename @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Original file size @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Original mime type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archive file size @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Discard @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.nl_NL.xlf b/src-ui/src/locale/messages.nl_NL.xlf index 4a1b05352..4f36ecf69 100644 --- a/src-ui/src/locale/messages.nl_NL.xlf +++ b/src-ui/src/locale/messages.nl_NL.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Archief serienummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Waar @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Onwaar @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Zoek documenten... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Niet @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Zoekopdracht toevoegen @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Expressie toevoegen @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Maak nieuw item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Item bewerken @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Voorbeeld @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Details @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Aanmaakdatum @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Inhoud @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Wijzigingsdatum @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum toegevoegd @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media bestandsnaam @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Originele bestandsnaam @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Originele bestandsgrootte @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Oorspronkelijke mime-type @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archief bestandsgrootte @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Originele document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Gearchiveerde document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Geschiedenis @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Dubbele documenten gevonden: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In prullenbak @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Opslaan & volgende @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Opslaan & sluiten @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Negeren @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document laden... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Wachtwoord invoeren diff --git a/src-ui/src/locale/messages.no_NO.xlf b/src-ui/src/locale/messages.no_NO.xlf index 1dd3c9924..316add81f 100644 --- a/src-ui/src/locale/messages.no_NO.xlf +++ b/src-ui/src/locale/messages.no_NO.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arkiver serienummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Sann @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Usann @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Søk etter dokumenter... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Ikke @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Legg til spørring @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Legg til uttrykk @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 + Opprett produkt @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Rediger produkt @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Forhåndsvis @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detaljer @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Dato opprettet @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Innhold @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Dato endret @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Dato lagt til @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filnavn @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Opprinnelig filnavn @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Opprinnelig MD5-sjekksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Opprinnelig filstørrelse @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Opprinnelig mimetype @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Lagret MD5-sjekksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arkivstørrelse @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Opprinnelig dokumentmetadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arkivert dokumentmetadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notater @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historikk @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplikater @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplikate dokumenter oppdaget: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 I papirkurven @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Lagre & Avslutt @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Lagre & Lukk @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Forkast @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokument laster... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Skriv inn passord diff --git a/src-ui/src/locale/messages.pl_PL.xlf b/src-ui/src/locale/messages.pl_PL.xlf index c7e590d37..d9f10d6a7 100644 --- a/src-ui/src/locale/messages.pl_PL.xlf +++ b/src-ui/src/locale/messages.pl_PL.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Numer seryjny archiwum @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Prawda @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Fałsz @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Wyszukaj dokumenty... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nie @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Dodaj zapytanie @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Dodaj wyrażenie @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Utwórz nowy element @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edytuj element @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Podgląd @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Szczegóły @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data utworzenia @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Zawartość @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data modyfikacji @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data dodania @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nazwa pliku @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Oryginalna nazwa pliku @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Rozmiar oryginalnego pliku @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Typ mime oryginału @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Rozmiar pliku archiwalnego @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadane oryginalnego dokumentu @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadane zarchiwizowanego dokumentu @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historia @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Wykryto duplikat dokumentów: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 W koszu @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Zapisz & następny @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Zapisz & zamknij @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Porzuć zmiany @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Ładowanie dokumentu... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Wprowadź hasło diff --git a/src-ui/src/locale/messages.pt_BR.xlf b/src-ui/src/locale/messages.pt_BR.xlf index 34f2c382e..d167f0312 100644 --- a/src-ui/src/locale/messages.pt_BR.xlf +++ b/src-ui/src/locale/messages.pt_BR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Número de série de arquivamento @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Verdadeiro @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falso @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Procura documentos... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Não @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Adicionar consulta @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Adicionar expressão @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Criar novo item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Editar item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Pré-visualizar @@ -8555,7 +8555,7 @@ Erro ao enviar documentos por e-mail Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalhes @@ -8563,7 +8563,7 @@ Erro ao enviar documentos por e-mail Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8587,7 +8587,7 @@ Erro ao enviar documentos por e-mail Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data de criação @@ -8595,7 +8595,7 @@ Erro ao enviar documentos por e-mail Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8607,7 +8607,7 @@ Erro ao enviar documentos por e-mail Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Conteúdo @@ -8615,7 +8615,7 @@ Erro ao enviar documentos por e-mail Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8627,7 +8627,7 @@ Erro ao enviar documentos por e-mail Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data de modificação @@ -8635,7 +8635,7 @@ Erro ao enviar documentos por e-mail Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data de adição @@ -8643,7 +8643,7 @@ Erro ao enviar documentos por e-mail Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nome do arquivo @@ -8651,7 +8651,7 @@ Erro ao enviar documentos por e-mail Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nome do arquivo original @@ -8659,7 +8659,7 @@ Erro ao enviar documentos por e-mail Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8667,7 +8667,7 @@ Erro ao enviar documentos por e-mail Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Tamanho do arquivo original @@ -8675,7 +8675,7 @@ Erro ao enviar documentos por e-mail Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tipo mime original @@ -8683,7 +8683,7 @@ Erro ao enviar documentos por e-mail Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8691,7 +8691,7 @@ Erro ao enviar documentos por e-mail Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Tamanho arquivado @@ -8699,7 +8699,7 @@ Erro ao enviar documentos por e-mail Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadados do documento original @@ -8707,7 +8707,7 @@ Erro ao enviar documentos por e-mail Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadados do documento arquivado @@ -8715,7 +8715,7 @@ Erro ao enviar documentos por e-mail Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8723,7 +8723,7 @@ Erro ao enviar documentos por e-mail History src/app/components/document-detail/document-detail.component.html - 379 + 383 Histórico @@ -8731,7 +8731,7 @@ Erro ao enviar documentos por e-mail Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8739,7 +8739,7 @@ Erro ao enviar documentos por e-mail Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8747,7 +8747,7 @@ Erro ao enviar documentos por e-mail In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8755,7 +8755,7 @@ Erro ao enviar documentos por e-mail Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Salvar & próximo @@ -8763,7 +8763,7 @@ Erro ao enviar documentos por e-mail Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Salvar & Fechar @@ -8771,7 +8771,7 @@ Erro ao enviar documentos por e-mail Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Descartar @@ -8779,7 +8779,7 @@ Erro ao enviar documentos por e-mail Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Carregando documentos... @@ -8787,7 +8787,7 @@ Erro ao enviar documentos por e-mail Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Digite a senha diff --git a/src-ui/src/locale/messages.pt_PT.xlf b/src-ui/src/locale/messages.pt_PT.xlf index 2b13371b7..c2d7533a4 100644 --- a/src-ui/src/locale/messages.pt_PT.xlf +++ b/src-ui/src/locale/messages.pt_PT.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Número de série de arquivamento @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Verdadeiro @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falso @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Não @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Adicionar expressão @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Criar novo item @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Editar item @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Pré-Visualizar @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalhes @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data de criação @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Conteúdo @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data de modificação @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data de adição @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Nome do ficheiro @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Nome original do ficheiro @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Tamanho do ficheiro original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tipo mime original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Tamanho do arquivo @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadados do documento original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadados do documento arquivado @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Guardar & próximo @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Gravar e fechar @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Descartar @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Introduzir Palavra-Passe diff --git a/src-ui/src/locale/messages.ro_RO.xlf b/src-ui/src/locale/messages.ro_RO.xlf index 6fe91c215..9b70cfcd2 100644 --- a/src-ui/src/locale/messages.ro_RO.xlf +++ b/src-ui/src/locale/messages.ro_RO.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Număr serial în arhivă @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Adevărat @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Fals @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Caută documente... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nu @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Adaugă interogare @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Adaugă expresie @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Crează articol nou @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Modifică articol @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Previzualizare @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalii @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Data creării @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Conținut @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Data ultimei modificări @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Data adăugării @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Numele fișierului media @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Numele original al fișierului @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Dimensiunea fișierului original @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Tip MIME original @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Mărimea arhivei @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadatele documentului original @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadatele documentului arhivat @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Istoric @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Salvează și continuă @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Salvează & închide @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Renunță @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Se încarcă documentul... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Introdu Parola diff --git a/src-ui/src/locale/messages.ru_RU.xlf b/src-ui/src/locale/messages.ru_RU.xlf index e9e03e13b..d8daed3fe 100644 --- a/src-ui/src/locale/messages.ru_RU.xlf +++ b/src-ui/src/locale/messages.ru_RU.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Архивный номер (АН) @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Верно @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Ложное @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Поиск документов... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Не @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Добавить запрос @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Добавить выражение @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Создать новый объект @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Редактировать объект @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Предпросмотр @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Детали @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Дата создания @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Содержимое @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Дата изменения @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Дата добавления @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Имя файла @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Исходное имя файла @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Размер оригинального файла @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Оригинальный MIME тип @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Размер архива @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Метаданные оригинального документа @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Метаданные архивного документа @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 История @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Сохранить & следующий @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Сохранить & закрыть @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Отменить @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Документ загружается... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Введите пароль diff --git a/src-ui/src/locale/messages.sk_SK.xlf b/src-ui/src/locale/messages.sk_SK.xlf index 4874fde2e..8f1691846 100644 --- a/src-ui/src/locale/messages.sk_SK.xlf +++ b/src-ui/src/locale/messages.sk_SK.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Sériové číslo archívu @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Vytvoriť novú položku @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Upraviť položku @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Náhľad @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Podrobnosti @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Vytvorené @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Obsah @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Dátum úpravy @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Dátum pridania @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Názov súboru médií @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Originál - názov @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Originál - veľkosť @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Pôvodný MIME typ @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Archív - veľkosť @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metadáta originálu @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metadáta archívu @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Uložiť & nasledujúci @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Uložiť & zatvoriť @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Zahodiť @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Zadajte Heslo diff --git a/src-ui/src/locale/messages.sl_SI.xlf b/src-ui/src/locale/messages.sl_SI.xlf index d291be34f..bae2aa778 100644 --- a/src-ui/src/locale/messages.sl_SI.xlf +++ b/src-ui/src/locale/messages.sl_SI.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arhivska serijska številka @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Resnično @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Neresnično @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Išči dokumente ... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Ne @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Dodaj poizvedbo @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Dodaj izraz @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Ustvari nov element @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Uredi vnos @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Predogled @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Podrobnosti @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Datum nastanka @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Vsebina @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum spremembe @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum vnosa @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Ime medijske datoteke @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Izvirno ime datoteke @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Izvirna kontrolna vsota SHA256 @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Izvirna velikost datoteke @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Izvirna mime vrsta @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Arhivska kontrolna vsota SHA256 @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Velikost arhivske datoteke @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Izvirni metapodatki dokumenta @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arhivirani metapodatki dokumenta @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Opombe @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Zgodovina @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Dvojniki @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Zaznani podvojeni dokumenti: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 V koš @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Shrani & naslednjo @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Shrani & zapri @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Zavrzi @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Nalaganje dokumenta... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Vnesi geslo diff --git a/src-ui/src/locale/messages.sq_AL.xlf b/src-ui/src/locale/messages.sq_AL.xlf index 0a43b5def..0c03a257f 100644 --- a/src-ui/src/locale/messages.sq_AL.xlf +++ b/src-ui/src/locale/messages.sq_AL.xlf @@ -719,7 +719,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -903,7 +903,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1483,7 +1483,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1743,7 +1743,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 [SQ] Archive serial number @@ -1755,7 +1755,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1787,7 +1787,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1819,7 +1819,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2011,7 +2011,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4311,11 +4311,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 [SQ] True @@ -4327,11 +4327,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 [SQ] False @@ -4343,7 +4343,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4351,7 +4351,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4363,7 +4363,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 [SQ] Not @@ -4371,7 +4371,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 [SQ] Add query @@ -4379,7 +4379,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 [SQ] Add expression @@ -4707,7 +4707,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Create new item @@ -4715,7 +4715,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Edit item @@ -5363,7 +5363,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 [SQ] Preview @@ -8555,7 +8555,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 [SQ] Details @@ -8563,7 +8563,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8587,7 +8587,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 [SQ] Date created @@ -8595,7 +8595,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8607,7 +8607,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 [SQ] Content @@ -8615,7 +8615,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8627,7 +8627,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 [SQ] Date modified @@ -8635,7 +8635,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 [SQ] Date added @@ -8643,7 +8643,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 [SQ] Media filename @@ -8651,7 +8651,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 [SQ] Original filename @@ -8659,7 +8659,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8667,7 +8667,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 [SQ] Original file size @@ -8675,7 +8675,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 [SQ] Original mime type @@ -8683,7 +8683,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8691,7 +8691,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 [SQ] Archive file size @@ -8699,7 +8699,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 [SQ] Original document metadata @@ -8707,7 +8707,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 [SQ] Archived document metadata @@ -8715,7 +8715,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8723,7 +8723,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 [SQ] History @@ -8731,7 +8731,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8739,7 +8739,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 [SQ] Duplicate documents detected: @@ -8747,7 +8747,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 [SQ] In trash @@ -8755,7 +8755,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Save & next @@ -8763,7 +8763,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Save & close @@ -8771,7 +8771,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 [SQ] Discard @@ -8779,7 +8779,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8787,7 +8787,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Enter Password diff --git a/src-ui/src/locale/messages.sr_CS.xlf b/src-ui/src/locale/messages.sr_CS.xlf index d33e17fe5..70d7dc96d 100644 --- a/src-ui/src/locale/messages.sr_CS.xlf +++ b/src-ui/src/locale/messages.sr_CS.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arhivski serijski broj (ASN) @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Tačno @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Netačno @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Pretraži dokumenta... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Nije @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Dodaj upit @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Dodaj izraz @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Kreiraj novu stavku @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Izmeni stavku @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Pregled @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detalji @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Datum kreiranja @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Sadržaj @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum izmene @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum dodavanja @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Naziv fajla @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Originalno ime fajla @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Originalna veličina fajla @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Originalni MIME tip @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arhivska veličina fajla @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Metapodaci originalnog dokumenta @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Metapodaci arhivnog dokumenta @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Istorija @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Otkriveni duplikati dokumenata: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 U otpadu @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Sačuvaj i sledeći @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Sačuvaj i zatvori @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Odbaci @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Učitavanje dokumenta.... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Unesite lozinku diff --git a/src-ui/src/locale/messages.sv_SE.xlf b/src-ui/src/locale/messages.sv_SE.xlf index 2d15833aa..e7f851fd6 100644 --- a/src-ui/src/locale/messages.sv_SE.xlf +++ b/src-ui/src/locale/messages.sv_SE.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arkivets serienummer @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Sant @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Falskt @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Sök dokument... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Ej @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Lägg till fråga @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Lägg till uttryck @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Skapa nytt objekt @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Redigera objekt @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Förhandsgranska @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Detaljer @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Datum skapad @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Innehåll @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Datum ändrad @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Datum tillagd @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Media filnamn @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Ursprungligt filnamn @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Ursprunglig filstorlek @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Ursprunglig mime-typ @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arkiv filstorlek @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Ursprungliga dokumentmetadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arkiverade dokumentmetadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Historik @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 I papperskorgen @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Spara & nästa @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Spara & stäng @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Avfärda @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Dokument laddar... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Ange lösenord diff --git a/src-ui/src/locale/messages.th_TH.xlf b/src-ui/src/locale/messages.th_TH.xlf index e8a53835c..30fe4ca9c 100644 --- a/src-ui/src/locale/messages.th_TH.xlf +++ b/src-ui/src/locale/messages.th_TH.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 รหัสการจัดเก็บถาวร @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 True @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 False @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Search docs... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Not @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Add query @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Add expression @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 สร้างรายการใหม่ @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 แก้ไขรายการ @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 ตัวอย่าง @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 รายละเอียด @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 วันที่สร้าง @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 เนื้อหา @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 วันที่แก้ไข @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 วันที่เพิ่ม @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 ชื่อไฟล์สื่อ @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 ชื่อไฟล์ต้นฉบับ @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 ขนาดไฟล์เดิม @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 MIME Type ของไฟล์เดิม @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 ขนาดไฟล์เก็บถาวร @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Original document metadata @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Archived document metadata @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 History @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 บันทึก & ถัดไป @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 บันทึก & ปิด @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 ละทิ้ง @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Document loading... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 กรอกรหัสผ่าน diff --git a/src-ui/src/locale/messages.tr_TR.xlf b/src-ui/src/locale/messages.tr_TR.xlf index 9267d2376..dfa523920 100644 --- a/src-ui/src/locale/messages.tr_TR.xlf +++ b/src-ui/src/locale/messages.tr_TR.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Arşiv seri numarası @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Evet @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Hayır @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Belgelerde ara... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Değil @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Sorgu Ekle @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 İfade Ekle @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Yeni Öğe Oluştur @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Öğeyi Düzenle @@ -5364,7 +5364,7 @@ tüm krite src/app/components/document-detail/document-detail.component.html - 356 + 360 Ön İzleme @@ -8556,7 +8556,7 @@ tüm krite Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Ayrıntılar @@ -8564,7 +8564,7 @@ tüm krite Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8588,7 +8588,7 @@ tüm krite Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Oluşturma tarihi @@ -8596,7 +8596,7 @@ tüm krite Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8608,7 +8608,7 @@ tüm krite Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Içerik @@ -8616,7 +8616,7 @@ tüm krite Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8628,7 +8628,7 @@ tüm krite Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Değiştirilme tarihi @@ -8636,7 +8636,7 @@ tüm krite Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Ekleme tarihi @@ -8644,7 +8644,7 @@ tüm krite Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Medya dosya ismi @@ -8652,7 +8652,7 @@ tüm krite Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Orjinal dosya adı @@ -8660,7 +8660,7 @@ tüm krite Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8668,7 +8668,7 @@ tüm krite Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Orijinal dosya boyutu @@ -8676,7 +8676,7 @@ tüm krite Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Orijinal mime türü @@ -8684,7 +8684,7 @@ tüm krite Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8692,7 +8692,7 @@ tüm krite Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Arşiv dosya boyutu @@ -8700,7 +8700,7 @@ tüm krite Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Orijinal belge meta verisi @@ -8708,7 +8708,7 @@ tüm krite Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Arşivlenen belge meta verileri @@ -8716,7 +8716,7 @@ tüm krite Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8724,7 +8724,7 @@ tüm krite History src/app/components/document-detail/document-detail.component.html - 379 + 383 Geçmiş @@ -8732,7 +8732,7 @@ tüm krite Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8740,7 +8740,7 @@ tüm krite Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8748,7 +8748,7 @@ tüm krite In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8756,7 +8756,7 @@ tüm krite Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Kaydet ve sonrakine geç @@ -8764,7 +8764,7 @@ tüm krite Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Kaydet ve kapat @@ -8772,7 +8772,7 @@ tüm krite Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Vazgeç @@ -8780,7 +8780,7 @@ tüm krite Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Belge Yükleniyor... @@ -8788,7 +8788,7 @@ tüm krite Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Parolayı girin diff --git a/src-ui/src/locale/messages.uk_UA.xlf b/src-ui/src/locale/messages.uk_UA.xlf index 85f1aec49..030963c1d 100644 --- a/src-ui/src/locale/messages.uk_UA.xlf +++ b/src-ui/src/locale/messages.uk_UA.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Архівний серійний номер @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Вірно @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Невірно @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Шукати в документації... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Не @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Додати запит @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Додати вираз @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Створити новий елемент @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Редагувати елемент @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Попередній перегляд @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Деталі @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Дата створення @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Вміст @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Дата зміни @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Дата додавання @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Назва медіафайлу @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Оригінальна назва файлу @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Оригінальний розмір файлу @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Оригінальний тип MIME @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Розмір архіву @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Метадані оригінального документа @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Метадані архівованого документа @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Історія @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Зберегти та перейти до наступного @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Зберегти та закрити @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Скасувати @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Завантаження документа... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Введіть пароль diff --git a/src-ui/src/locale/messages.vi_VN.xlf b/src-ui/src/locale/messages.vi_VN.xlf index 4c792832b..4b625c316 100644 --- a/src-ui/src/locale/messages.vi_VN.xlf +++ b/src-ui/src/locale/messages.vi_VN.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 Số sê-ri lưu trữ (ASN) @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1788,7 +1788,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1820,7 +1820,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2012,7 +2012,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4330,11 +4330,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 Đúng @@ -4346,11 +4346,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 Sai @@ -4362,7 +4362,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 Tìm kiếm tài liệu... @@ -4370,7 +4370,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4382,7 +4382,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 Không @@ -4390,7 +4390,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 Thêm yêu cầu tìm kiếm @@ -4398,7 +4398,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 Thêm biểu thức @@ -4728,7 +4728,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 Tạo mục mới @@ -4736,7 +4736,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 Chỉnh sửa mục @@ -5386,7 +5386,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 Xem trước @@ -8600,7 +8600,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 Chi tiết @@ -8608,7 +8608,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8632,7 +8632,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 Ngày tạo @@ -8640,7 +8640,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8652,7 +8652,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 Nội dung @@ -8660,7 +8660,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8672,7 +8672,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 Ngày sửa đổi @@ -8680,7 +8680,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 Ngày thêm @@ -8688,7 +8688,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 Tên tệp Media @@ -8696,7 +8696,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 Tên tệp gốc @@ -8704,7 +8704,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8712,7 +8712,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 Kích thước tệp gốc @@ -8720,7 +8720,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 Loại MIME gốc @@ -8728,7 +8728,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8736,7 +8736,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 Kích thước tệp lưu trữ @@ -8744,7 +8744,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 Siêu dữ liệu tài liệu gốc @@ -8752,7 +8752,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 Siêu dữ liệu tài liệu lưu trữ @@ -8760,7 +8760,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8768,7 +8768,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 Lịch sử @@ -8776,7 +8776,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8784,7 +8784,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8792,7 +8792,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8800,7 +8800,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 Lưu & Tiếp theo @@ -8810,7 +8810,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 Lưu và đóng @@ -8820,7 +8820,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 Hủy bỏ @@ -8828,7 +8828,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 Tải tài liệu ... @@ -8836,7 +8836,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 Nhập mật khẩu diff --git a/src-ui/src/locale/messages.zh_CN.xlf b/src-ui/src/locale/messages.zh_CN.xlf index 0f8fea1aa..400b15d51 100644 --- a/src-ui/src/locale/messages.zh_CN.xlf +++ b/src-ui/src/locale/messages.zh_CN.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1528,7 +1528,7 @@ src/app/components/admin/settings/settings.component.html 306,308 - Settings apply to this user account for objects (Tags, Mail Rules, etc.) created via the web UI. These settings do not apply to documents. + 这些设置将应用于通过 Web 界面创建的对象(标签、邮件规则等)。这些设置不适用于文档。 Default Owner @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 归档序列号 @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -2644,7 +2644,7 @@ src/app/components/admin/tasks/tasks.component.ts 239 - 取消选择 + 取消选中项 Dismiss visible @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 搜索文档... @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 添加查询 @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 添加表达式 @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 创建新项目 @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 编辑项目 @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 预览 @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 详细信息 @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 创建日期 @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 内容 @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 修改日期 @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 日期已添加 @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 媒体文件名 @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 原文件名 @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 原始 SHA256 校验和 @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 原始文件大小 @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 原始 mime 类型 @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 归档 SHA256 校验和 @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 归档文件大小 @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 原始文档元数据 @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 归档文档元数据 @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 备注 @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 历史 @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 个重复文档 @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 检测到重复文档: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 在回收站中 @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 保存 & 下一个 @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 保存并关闭 @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 放弃 @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 正在加载文档... @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 输入密码 @@ -9719,7 +9719,7 @@ src/app/components/document-list/document-card-small/document-card-small.component.html 8 - thumbnail + 缩略图 Filter by tag diff --git a/src-ui/src/locale/messages.zh_TW.xlf b/src-ui/src/locale/messages.zh_TW.xlf index 447d4c29c..48e10e198 100644 --- a/src-ui/src/locale/messages.zh_TW.xlf +++ b/src-ui/src/locale/messages.zh_TW.xlf @@ -718,7 +718,7 @@ src/app/components/document-detail/document-detail.component.html - 445 + 449 src/app/components/document-list/bulk-editor/custom-fields-bulk-edit-dialog/custom-fields-bulk-edit-dialog.component.html @@ -902,7 +902,7 @@ src/app/components/document-detail/document-detail.component.html - 464 + 468 src/app/components/document-list/document-list.component.html @@ -1482,7 +1482,7 @@ src/app/components/document-detail/document-detail.component.html - 390 + 394 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1742,7 +1742,7 @@ src/app/components/document-detail/document-detail.component.html - 165 + 169 封存序號 @@ -1754,7 +1754,7 @@ src/app/components/document-detail/document-detail.component.html - 170 + 174 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1786,7 +1786,7 @@ src/app/components/document-detail/document-detail.component.html - 174 + 178 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -1818,7 +1818,7 @@ src/app/components/document-detail/document-detail.component.html - 178 + 182 src/app/components/document-list/bulk-editor/bulk-editor.component.html @@ -2010,7 +2010,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 154 + 159 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4310,11 +4310,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 96 + 101 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 102 + 107 @@ -4326,11 +4326,11 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 97 + 102 src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 103 + 108 @@ -4342,7 +4342,7 @@ src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 119 + 124 搜尋文件⋯ @@ -4350,7 +4350,7 @@ Any src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 152 + 157 src/app/components/common/filterable-dropdown/filterable-dropdown.component.html @@ -4362,7 +4362,7 @@ Not src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 157 + 162 不是 @@ -4370,7 +4370,7 @@ Add query src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 176 + 181 新增查詢 @@ -4378,7 +4378,7 @@ Add expression src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.html - 179 + 184 新增表達式 @@ -4706,7 +4706,7 @@ Create new item src/app/components/common/edit-dialog/edit-dialog.component.ts - 119 + 123 建立新項目 @@ -4714,7 +4714,7 @@ Edit item src/app/components/common/edit-dialog/edit-dialog.component.ts - 123 + 127 編輯項目 @@ -5362,7 +5362,7 @@ src/app/components/document-detail/document-detail.component.html - 356 + 360 預覽 @@ -8554,7 +8554,7 @@ Details src/app/components/document-detail/document-detail.component.html - 160 + 164 詳細資訊 @@ -8562,7 +8562,7 @@ Title src/app/components/document-detail/document-detail.component.html - 163 + 167 src/app/components/document-list/document-list.component.html @@ -8586,7 +8586,7 @@ Date created src/app/components/document-detail/document-detail.component.html - 167 + 171 建立日期 @@ -8594,7 +8594,7 @@ Default src/app/components/document-detail/document-detail.component.html - 179 + 183 src/app/components/manage/saved-views/saved-views.component.html @@ -8606,7 +8606,7 @@ Content src/app/components/document-detail/document-detail.component.html - 286 + 290 內容 @@ -8614,7 +8614,7 @@ Metadata src/app/components/document-detail/document-detail.component.html - 295 + 299 src/app/components/document-detail/metadata-collapse/metadata-collapse.component.ts @@ -8626,7 +8626,7 @@ Date modified src/app/components/document-detail/document-detail.component.html - 302 + 306 修改日期 @@ -8634,7 +8634,7 @@ Date added src/app/components/document-detail/document-detail.component.html - 306 + 310 新增日期 @@ -8642,7 +8642,7 @@ Media filename src/app/components/document-detail/document-detail.component.html - 310 + 314 媒體檔案名稱 @@ -8650,7 +8650,7 @@ Original filename src/app/components/document-detail/document-detail.component.html - 314 + 318 原始檔案名稱 @@ -8658,7 +8658,7 @@ Original SHA256 checksum src/app/components/document-detail/document-detail.component.html - 318 + 322 Original SHA256 checksum @@ -8666,7 +8666,7 @@ Original file size src/app/components/document-detail/document-detail.component.html - 322 + 326 原始檔案大小 @@ -8674,7 +8674,7 @@ Original mime type src/app/components/document-detail/document-detail.component.html - 326 + 330 原始 MIME 類型 @@ -8682,7 +8682,7 @@ Archive SHA256 checksum src/app/components/document-detail/document-detail.component.html - 331 + 335 Archive SHA256 checksum @@ -8690,7 +8690,7 @@ Archive file size src/app/components/document-detail/document-detail.component.html - 337 + 341 封存檔案大小 @@ -8698,7 +8698,7 @@ Original document metadata src/app/components/document-detail/document-detail.component.html - 346 + 350 原始文件詮釋資料 @@ -8706,7 +8706,7 @@ Archived document metadata src/app/components/document-detail/document-detail.component.html - 349 + 353 封存文件詮釋資料 @@ -8714,7 +8714,7 @@ Notes src/app/components/document-detail/document-detail.component.html - 368,371 + 372,375 Notes @@ -8722,7 +8722,7 @@ History src/app/components/document-detail/document-detail.component.html - 379 + 383 歷史紀錄 @@ -8730,7 +8730,7 @@ Duplicates src/app/components/document-detail/document-detail.component.html - 401,405 + 405,409 Duplicates @@ -8738,7 +8738,7 @@ Duplicate documents detected: src/app/components/document-detail/document-detail.component.html - 407 + 411 Duplicate documents detected: @@ -8746,7 +8746,7 @@ In trash src/app/components/document-detail/document-detail.component.html - 418 + 422 In trash @@ -8754,7 +8754,7 @@ Save & next src/app/components/document-detail/document-detail.component.html - 447 + 451 儲存 & 下一個 @@ -8762,7 +8762,7 @@ Save & close src/app/components/document-detail/document-detail.component.html - 449 + 453 標題與內容 @@ -8770,7 +8770,7 @@ Discard src/app/components/document-detail/document-detail.component.html - 451 + 455 放棄變更 @@ -8778,7 +8778,7 @@ Document loading... src/app/components/document-detail/document-detail.component.html - 459 + 463 文件讀取中⋯ @@ -8786,7 +8786,7 @@ Enter Password src/app/components/document-detail/document-detail.component.html - 513 + 517 輸入密碼 diff --git a/src/documents/consumer.py b/src/documents/consumer.py index e7f026e71..43185c19a 100644 --- a/src/documents/consumer.py +++ b/src/documents/consumer.py @@ -57,9 +57,7 @@ from paperless.models import ArchiveFileGenerationChoices from paperless.parsers import ParserContext from paperless.parsers import ParserProtocol from paperless.parsers.registry import get_parser_registry -from paperless.parsers.utils import PDF_TEXT_MIN_LENGTH -from paperless.parsers.utils import extract_pdf_text -from paperless.parsers.utils import is_tagged_pdf +from paperless.parsers.utils import pdf_born_digital_text LOGGING_NAME: Final[str] = "paperless.consumer" @@ -138,53 +136,45 @@ def should_produce_archive( # Must produce a PDF so the frontend can display the original format at all. if parser.requires_pdf_rendition: - _log.debug("Archive: yes — parser requires PDF rendition for frontend display") + _log.debug("Archive: yes - parser requires PDF rendition for frontend display") return True # Parser cannot produce an archive (e.g. TextDocumentParser). if not parser.can_produce_archive: - _log.debug("Archive: no — parser cannot produce archives") + _log.debug("Archive: no - parser cannot produce archives") return False generation = OcrConfig().archive_file_generation if generation == ArchiveFileGenerationChoices.ALWAYS: - _log.debug("Archive: yes — ARCHIVE_FILE_GENERATION=always") + _log.debug("Archive: yes - ARCHIVE_FILE_GENERATION=always") return True if generation == ArchiveFileGenerationChoices.NEVER: - _log.debug("Archive: no — ARCHIVE_FILE_GENERATION=never") + _log.debug("Archive: no - ARCHIVE_FILE_GENERATION=never") return False # auto: produce archives for scanned/image documents; skip for born-digital PDFs. if mime_type.startswith("image/"): - _log.debug("Archive: yes — image document, ARCHIVE_FILE_GENERATION=auto") + _log.debug("Archive: yes - image document, ARCHIVE_FILE_GENERATION=auto") return True if mime_type == "application/pdf": - text = extract_pdf_text(document_path) - has_text = text is not None and len(text) > 0 - if has_text and is_tagged_pdf(document_path): + text, born_digital = pdf_born_digital_text(document_path, log=_log) + text_length = len(text) if text else 0 + if born_digital: _log.debug( - "Archive: no — born-digital PDF (structure tags detected)," + "Archive: no - born-digital PDF (text_length=%d)," " ARCHIVE_FILE_GENERATION=auto", + text_length, ) return False - if text is None or len(text) <= PDF_TEXT_MIN_LENGTH: - _log.debug( - "Archive: yes — scanned PDF (text_length=%d ≤ %d)," - " ARCHIVE_FILE_GENERATION=auto", - len(text) if text else 0, - PDF_TEXT_MIN_LENGTH, - ) - return True _log.debug( - "Archive: no — born-digital PDF (text_length=%d > %d)," + "Archive: yes - scanned/textless PDF (text_length=%d)," " ARCHIVE_FILE_GENERATION=auto", - len(text), - PDF_TEXT_MIN_LENGTH, + text_length, ) - return False + return True _log.debug( - "Archive: no — MIME type %r not eligible for auto archive generation", + "Archive: no - MIME type %r not eligible for auto archive generation", mime_type, ) return False diff --git a/src/documents/mail.py b/src/documents/mail.py index 21bf03c7a..e9c4cf6ad 100644 --- a/src/documents/mail.py +++ b/src/documents/mail.py @@ -36,6 +36,9 @@ def send_email( TODO: re-evaluate this pending https://code.djangoproject.com/ticket/35581 / https://github.com/django/django/pull/18966 """ + if "\r" in subject or "\n" in subject: + subject = " ".join(line.strip(" \t") for line in subject.splitlines()) + email = EmailMessage( subject=subject, body=body, diff --git a/src/documents/management/commands/document_importer.py b/src/documents/management/commands/document_importer.py index 90986858b..0e54b0ced 100644 --- a/src/documents/management/commands/document_importer.py +++ b/src/documents/management/commands/document_importer.py @@ -386,10 +386,19 @@ class Command(CryptMixin, PaperlessCommand): raise DeserializationError( f"{model.__name__} has no updatable fields; PK-only models are not supported by the importer", ) + # MySQL/MariaDB support upserts via ON DUPLICATE KEY UPDATE but, + # unlike PostgreSQL/SQLite, cannot target a specific unique field + # for the conflict -- passing unique_fields there raises + # NotSupportedError. + unique_fields = ( + [model._meta.pk.attname] + if connection.features.supports_update_conflicts_with_target + else None + ) model.objects.bulk_create( # type: ignore[attr-defined] instances, update_conflicts=True, - unique_fields=[model._meta.pk.attname], + unique_fields=unique_fields, update_fields=update_fields, ) loaded_models.add(model) diff --git a/src/documents/management/commands/document_llmindex.py b/src/documents/management/commands/document_llmindex.py index 7b34ca9a8..216ab631d 100644 --- a/src/documents/management/commands/document_llmindex.py +++ b/src/documents/management/commands/document_llmindex.py @@ -3,6 +3,7 @@ from typing import Any from documents.management.commands.base import PaperlessCommand from documents.tasks import llmindex_index from paperless_ai.indexing import llm_index_compact +from paperless_ai.indexing import llm_index_migrate class Command(PaperlessCommand): @@ -13,12 +14,18 @@ class Command(PaperlessCommand): def add_arguments(self, parser: Any) -> None: super().add_arguments(parser) - parser.add_argument("command", choices=["rebuild", "update", "compact"]) + parser.add_argument( + "command", + choices=["rebuild", "update", "compact", "migrate"], + ) def handle(self, *args: Any, **options: Any) -> None: if options["command"] == "compact": llm_index_compact() return + if options["command"] == "migrate": + llm_index_migrate() + return llmindex_index( rebuild=options["command"] == "rebuild", iter_wrapper=lambda docs: self.track( diff --git a/src/documents/management/commands/document_sanity_checker.py b/src/documents/management/commands/document_sanity_checker.py index c8921d064..00f6dccb1 100644 --- a/src/documents/management/commands/document_sanity_checker.py +++ b/src/documents/management/commands/document_sanity_checker.py @@ -61,7 +61,7 @@ class Command(PaperlessCommand): ) table.add_column("Level", width=7, no_wrap=True) table.add_column("Document", min_width=20) - table.add_column("Issue", ratio=1) + table.add_column("Issue", ratio=1, overflow="fold") for doc_pk, doc_messages in messages.iter_messages(): if doc_pk is not None: diff --git a/src/documents/search/_backend.py b/src/documents/search/_backend.py index 7464de79a..227d0ccd7 100644 --- a/src/documents/search/_backend.py +++ b/src/documents/search/_backend.py @@ -39,6 +39,7 @@ from documents.search._tokenizer import ascii_fold from documents.search._tokenizer import autocomplete_tokens from documents.search._tokenizer import register_tokenizers from documents.utils import IterWrapper +from documents.utils import QuerySetStream from documents.utils import identity if TYPE_CHECKING: @@ -1035,14 +1036,15 @@ _EMPTY_VIEWER_GRANT: Final[ViewerGrant] = ViewerGrant( ) -class _DocumentViewerStream: +class _DocumentViewerStream(QuerySetStream["Document"]): """Yield document permission data while batch-loading grants. Viewer permissions are fetched in batches (see ``_bulk_get_viewer_permissions``), but documents are yielded individually so a progress bar wrapped around this stream advances per document rather than - jumping a whole chunk at a time. ``__len__`` lets the progress helper still - discover the total (it inspects ``QuerySet``/``Sized``). + jumping a whole chunk at a time. ``__len__`` (inherited from + ``QuerySetStream``) lets the progress helper still discover the total (it + inspects ``QuerySet``/``Sized``). The viewer and group ids travel with each document in the yielded pair rather than through a separate mutable attribute, so the pairing survives @@ -1051,18 +1053,11 @@ class _DocumentViewerStream: generator in lock-step. """ - def __init__(self, documents: QuerySet[Document], *, chunk_size: int) -> None: - self._documents = documents - self._chunk_size = chunk_size - - def __len__(self) -> int: - return self._documents.count() - def __iter__(self) -> Iterator[tuple[Document, ViewerGrant]]: # iterator(chunk_size=…) streams from a server-side cursor instead of # materialising the whole queryset in memory; since Django 4.1 it still # honours prefetch_related, running the prefetches one batch at a time. - documents = self._documents.iterator(chunk_size=self._chunk_size) + documents = self._queryset.iterator(chunk_size=self._chunk_size) for chunk in chunked(documents, self._chunk_size): grants_by_pk = _bulk_get_viewer_permissions([doc.pk for doc in chunk]) for doc in chunk: diff --git a/src/documents/search/_dates.py b/src/documents/search/_dates.py index a94935022..dbdf6b42b 100644 --- a/src/documents/search/_dates.py +++ b/src/documents/search/_dates.py @@ -43,8 +43,16 @@ def _fmt(dt: datetime) -> str: def _iso_range(lo: datetime, hi: datetime) -> str: - """Format a [lo TO hi] range string in ISO 8601 for Tantivy query syntax.""" - return f"[{_fmt(lo)} TO {_fmt(hi)}]" + """ + Format a half-open ``[lo TO hi)`` range in ISO 8601 for Tantivy query syntax. + + ``hi`` is always the exclusive ceiling of a computed period (the start of + the *next* day/week/month/quarter/year), so the closing bracket must be + the Tantivy exclusive-range brace ``}`` rather than ``]`` — otherwise the + first instant of the following period (e.g. the 1st of next month) is + incorrectly included in the match. + """ + return f"[{_fmt(lo)} TO {_fmt(hi)}}}" def _quarter_start(d: date) -> date: diff --git a/src/documents/search/_query.py b/src/documents/search/_query.py index 362f85688..c45e37f80 100644 --- a/src/documents/search/_query.py +++ b/src/documents/search/_query.py @@ -1,7 +1,6 @@ from __future__ import annotations import logging -from datetime import UTC from typing import TYPE_CHECKING from typing import Final @@ -9,12 +8,6 @@ import regex import tantivy from django.conf import settings -from documents.search._dates import ( - _date_only_range, # noqa: F401 — re-exported for test imports -) -from documents.search._dates import ( - _datetime_range, # noqa: F401 — re-exported for test imports -) from documents.search._tokenizer import simple_search_tokens from documents.search._translate import SearchQueryError from documents.search._translate import translate_query @@ -76,42 +69,6 @@ def _build_cjk_query( return None -def rewrite_natural_date_keywords(query: str, tz: tzinfo) -> str: - """ - Rewrite natural date syntax to ISO 8601 format for Tantivy compatibility. - - Delegates to ``translate_query`` which handles all date forms, comma - expansion, field aliasing, relative ranges, and operator normalization. - - Args: - query: Raw user query string - tz: Timezone for converting local date boundaries to UTC - - Returns: - Query with date syntax rewritten to ISO 8601 ranges - - Note: - Bare keywords without field prefixes pass through unchanged. - """ - return translate_query(query, tz) - - -def normalize_query(query: str) -> str: - """ - Normalize query syntax for better search behavior. - - Delegates to ``translate_query`` which handles comma expansion, whitespace - collapsing, operator normalization, and field aliasing. - - Args: - query: Query string after date rewriting - - Returns: - Normalized query string ready for Tantivy parsing - """ - return translate_query(query, UTC) - - def build_permission_filter( schema: tantivy.Schema, user: AbstractBaseUser, diff --git a/src/documents/search/_translate.py b/src/documents/search/_translate.py index 7afa23773..f020f1c89 100644 --- a/src/documents/search/_translate.py +++ b/src/documents/search/_translate.py @@ -391,14 +391,40 @@ _NOW_COMPACT_RE = regex.compile( regex.IGNORECASE, ) -# Matches "±N " Whoosh-style offsets (e.g. -7 days, -1 week, +3 hours) -# Unit is singular or plural; sign prefix is mandatory. +# Matches "±N " Whoosh-style offsets (e.g. -7 days, -1 week, +3 hours). +# Whoosh's own date parser (qparser.dateparse.PlusMinus) additionally accepted +# abbreviated unit spellings (e.g. "yrs", "yr", "y", "mos", "wks", "hrs", "mins", +# "secs"); saved views/searches created under the old Whoosh backend can still +# contain those tokens (e.g. "-999yrs"), so they are accepted here too and +# normalized to a canonical unit via _UNIT_ALIASES below. _NOW_SPACED_RE = regex.compile( r"^(?P[+-])(?P\d+)\s*" - r"(?Psecond|minute|hour|day|week|month|year)s?$", + r"(?Pyears|year|yrs|yr|ys|y" + r"|months|month|mons|mon|mos|mo" + r"|weeks|week|wks|wk|ws|w" + r"|days|day|dys|dy|ds|d" + r"|hours|hour|hrs|hr|hs|h" + r"|minutes|minute|mins|min|ms|m" + r"|seconds|second|secs|sec|s)$", regex.IGNORECASE, ) +# Maps every accepted unit spelling (including Whoosh-era abbreviations) to the +# canonical unit name used as a key into the delta map in _resolve_relative_bound. +_UNIT_ALIASES: dict[str, str] = { + alias: canonical + for canonical, aliases in { + "year": ("years", "year", "yrs", "yr", "ys", "y"), + "month": ("months", "month", "mons", "mon", "mos", "mo"), + "week": ("weeks", "week", "wks", "wk", "ws", "w"), + "day": ("days", "day", "dys", "dy", "ds", "d"), + "hour": ("hours", "hour", "hrs", "hr", "hs", "h"), + "minute": ("minutes", "minute", "mins", "min", "ms", "m"), + "second": ("seconds", "second", "secs", "sec", "s"), + }.items() + for alias in aliases +} + def _resolve_relative_bound(token: str) -> datetime | None: """ @@ -407,7 +433,9 @@ def _resolve_relative_bound(token: str) -> datetime | None: Supported forms: - ``now`` -> current UTC instant - ``now+/-d/h/m`` -> now +/- timedelta (d=days, h=hours, m=minutes) - - ``±N `` -> now +/- delta; month/year use relativedelta + - ``±N `` -> now +/- delta; month/year use relativedelta; + unit also accepts Whoosh-era abbreviations + (e.g. "yrs", "mos", "wks", "hrs", "mins", "secs") """ stripped = token.strip() low = stripped.lower() @@ -435,7 +463,7 @@ def _resolve_relative_bound(token: str) -> datetime | None: if m: sign = 1 if m.group("sign") == "+" else -1 n = int(m.group("n")) - unit = m.group("unit").lower() + unit = _UNIT_ALIASES[m.group("unit").lower()] delta_map: dict[str, timedelta | relativedelta] = { "second": timedelta(seconds=n), "minute": timedelta(minutes=n), @@ -566,6 +594,17 @@ def translate_range(field: str, lo: str, hi: str, tz: tzinfo) -> str: lo_pair, hi_pair = hi_pair, lo_pair lo_iso = _fmt(lo_pair[0]) if lo_pair is not None else OPEN_LO - hi_iso = _fmt(hi_pair[1]) if hi_pair is not None else OPEN_HI - return f"{field}:[{lo_iso} TO {hi_iso}]" + # A bound resolves to (floor, ceil) where floor == ceil for an exact instant + # (a full ISO datetime, "now", or a "+/-N unit" offset) and floor != ceil for + # a coarser period token (year/month/day precision). Only the latter needs a + # half-open close: its ceil is the start of the *next* period and must be + # excluded, or that instant (e.g. the 1st of next month) wrongly matches. + if hi_pair is not None: + hi_iso = _fmt(hi_pair[1]) + hi_close = "]" if hi_pair[0] == hi_pair[1] else "}" + else: + hi_iso = OPEN_HI + hi_close = "]" + + return f"{field}:[{lo_iso} TO {hi_iso}{hi_close}" diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index add3610af..aaded56fe 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -1829,18 +1829,27 @@ class BulkEditSerializer( f"Some custom fields in {name} don't exist or were specified twice.", ) - if isinstance(custom_fields, dict): - custom_field_map = CustomField.objects.in_bulk(ids) - for raw_field_id, value in custom_fields.items(): - field = custom_field_map.get(int(raw_field_id)) - if ( - field is not None - and field.data_type == CustomField.FieldDataType.DOCUMENTLINK - and value is not None - ): - if not isinstance(value, list): - raise serializers.ValidationError("Value must be a list") - validate_documentlink_targets(self.user, value) + def _validate_custom_field_values(self, custom_fields, name): + if not isinstance(custom_fields, dict): + return custom_fields + + validated = {} + errors = {} + for raw_field_id, value in custom_fields.items(): + field_id = int(raw_field_id) + validator = CustomFieldInstanceSerializer( + data={"field": field_id, "value": value}, + context=self.context, + ) + if validator.is_valid(): + validated[field_id] = validator.validated_data["value"] + else: + errors[str(field_id)] = validator.errors + + if errors: + raise serializers.ValidationError({name: errors}) + + return validated def validate_method(self, method): if method == "set_correspondent": @@ -1944,6 +1953,10 @@ class BulkEditSerializer( parameters["add_custom_fields"], "add_custom_fields", ) + parameters["add_custom_fields"] = self._validate_custom_field_values( + parameters["add_custom_fields"], + "add_custom_fields", + ) else: raise serializers.ValidationError("add_custom_fields not specified") diff --git a/src/documents/signals/handlers.py b/src/documents/signals/handlers.py index fe1d1f94d..30c682cbf 100644 --- a/src/documents/signals/handlers.py +++ b/src/documents/signals/handlers.py @@ -1134,6 +1134,11 @@ def before_task_publish_handler( return try: + # Close stale connections without disrupting a transaction publishing a task + for connection in connections.all(initialized_only=True): + if not connection.in_atomic_block: + connection.close_if_unusable_or_obsolete() + _, task_kwargs, _ = body task_id = headers["id"] diff --git a/src/documents/tests/management/test_management_document_llmindex.py b/src/documents/tests/management/test_management_document_llmindex.py index b8a05dd85..3b75338d2 100644 --- a/src/documents/tests/management/test_management_document_llmindex.py +++ b/src/documents/tests/management/test_management_document_llmindex.py @@ -9,6 +9,7 @@ if TYPE_CHECKING: _COMPACT = "documents.management.commands.document_llmindex.llm_index_compact" _INDEX = "documents.management.commands.document_llmindex.llmindex_index" +_MIGRATE = "documents.management.commands.document_llmindex.llm_index_migrate" class TestDocumentLlmindexCommand: @@ -17,6 +18,11 @@ class TestDocumentLlmindexCommand: call_command("document_llmindex", "compact") mock_compact.assert_called_once_with() + def test_migrate_calls_llm_index_migrate(self, mocker: MockerFixture) -> None: + mock_migrate = mocker.patch(_MIGRATE) + call_command("document_llmindex", "migrate") + mock_migrate.assert_called_once_with() + def test_rebuild_calls_llmindex_index_with_rebuild_true( self, mocker: MockerFixture, diff --git a/src/documents/tests/search/test_query.py b/src/documents/tests/search/test_query.py index 60ba2bf2f..6260b67af 100644 --- a/src/documents/tests/search/test_query.py +++ b/src/documents/tests/search/test_query.py @@ -11,16 +11,15 @@ import pytest import tantivy import time_machine -from documents.search._query import _date_only_range -from documents.search._query import _datetime_range +from documents.search._dates import _date_only_range +from documents.search._dates import _datetime_range from documents.search._query import build_permission_filter -from documents.search._query import normalize_query from documents.search._query import parse_simple_text_highlight_query from documents.search._query import parse_user_query -from documents.search._query import rewrite_natural_date_keywords from documents.search._schema import build_schema from documents.search._tokenizer import register_tokenizers from documents.search._translate import InvalidDateQuery +from documents.search._translate import translate_query if TYPE_CHECKING: from django.contrib.auth.base_user import AbstractBaseUser @@ -32,7 +31,9 @@ AUCKLAND = ZoneInfo("Pacific/Auckland") # UTC+13 in southern-hemisphere summer def _range(result: str, field: str) -> tuple[str, str]: - m = re.search(rf"{field}:\[(.+?) TO (.+?)\]", result) + # Half-open period ranges close with "}" (exclusive); exact-instant ranges + # (full ISO datetimes, "now", relative offsets) close with "]" (inclusive). + m = re.search(rf"{field}:\[(.+?) TO (.+?)[\]}}]", result) assert m, f"No range for {field!r} in: {result!r}" return m.group(1), m.group(2) @@ -57,7 +58,7 @@ class TestCreatedDateField: ) @time_machine.travel(datetime(2026, 3, 28, 15, 30, tzinfo=UTC), tick=False) def test_today(self, tz: tzinfo, expected_lo: str, expected_hi: str) -> None: - lo, hi = _range(rewrite_natural_date_keywords("created:today", tz), "created") + lo, hi = _range(translate_query("created:today", tz), "created") assert lo == expected_lo assert hi == expected_hi @@ -65,7 +66,7 @@ class TestCreatedDateField: def test_today_auckland_ahead_of_utc(self) -> None: # UTC 03:00 -> Auckland (UTC+13) = 16:00 same date; local date = 2026-03-28 lo, _ = _range( - rewrite_natural_date_keywords("created:today", AUCKLAND), + translate_query("created:today", AUCKLAND), "created", ) assert lo == "2026-03-28T00:00:00Z" @@ -127,7 +128,7 @@ class TestCreatedDateField: ) -> None: # 2026-03-28 is Saturday; Mon-Sun week calculation built into expectations query = f"{field}:{keyword}" - lo, hi = _range(rewrite_natural_date_keywords(query, UTC), field) + lo, hi = _range(translate_query(query, UTC), field) assert lo == expected_lo assert hi == expected_hi @@ -135,7 +136,7 @@ class TestCreatedDateField: def test_this_month_december_wraps_to_next_year(self) -> None: # December: next month must roll over to January 1 of next year lo, hi = _range( - rewrite_natural_date_keywords("created:this month", UTC), + translate_query("created:this month", UTC), "created", ) assert lo == "2026-12-01T00:00:00Z" @@ -145,7 +146,7 @@ class TestCreatedDateField: def test_last_month_january_wraps_to_previous_year(self) -> None: # January: last month must roll back to December 1 of previous year lo, hi = _range( - rewrite_natural_date_keywords("created:previous month", UTC), + translate_query("created:previous month", UTC), "created", ) assert lo == "2025-12-01T00:00:00Z" @@ -154,7 +155,7 @@ class TestCreatedDateField: @time_machine.travel(datetime(2026, 7, 15, 12, 0, tzinfo=UTC), tick=False) def test_previous_quarter(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords('created:"previous quarter"', UTC), + translate_query('created:"previous quarter"', UTC), "created", ) assert lo == "2026-04-01T00:00:00Z" @@ -174,7 +175,7 @@ class TestDateTimeFields: @time_machine.travel(datetime(2026, 3, 28, 15, 30, tzinfo=UTC), tick=False) def test_added_today_eastern(self) -> None: # EDT = UTC-4; local midnight 2026-03-28 00:00 EDT = 2026-03-28 04:00 UTC - lo, hi = _range(rewrite_natural_date_keywords("added:today", EASTERN), "added") + lo, hi = _range(translate_query("added:today", EASTERN), "added") assert lo == "2026-03-28T04:00:00Z" assert hi == "2026-03-29T04:00:00Z" @@ -182,14 +183,14 @@ class TestDateTimeFields: def test_added_today_auckland_midnight_crossing(self) -> None: # UTC 02:00 on 2026-03-29 -> Auckland (UTC+13) = 2026-03-29 15:00 local # Auckland midnight = UTC 2026-03-28 11:00 - lo, hi = _range(rewrite_natural_date_keywords("added:today", AUCKLAND), "added") + lo, hi = _range(translate_query("added:today", AUCKLAND), "added") assert lo == "2026-03-28T11:00:00Z" assert hi == "2026-03-29T11:00:00Z" @time_machine.travel(datetime(2026, 3, 28, 15, 0, tzinfo=UTC), tick=False) def test_modified_today_utc(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords("modified:today", UTC), + translate_query("modified:today", UTC), "modified", ) assert lo == "2026-03-28T00:00:00Z" @@ -244,14 +245,14 @@ class TestDateTimeFields: expected_hi: str, ) -> None: # 2026-03-28 is Saturday; weekday()==5 so Monday=2026-03-23 - lo, hi = _range(rewrite_natural_date_keywords(f"added:{keyword}", UTC), "added") + lo, hi = _range(translate_query(f"added:{keyword}", UTC), "added") assert lo == expected_lo assert hi == expected_hi @time_machine.travel(datetime(2026, 12, 15, 12, 0, tzinfo=UTC), tick=False) def test_this_month_december_wraps_to_next_year(self) -> None: # December: next month wraps to January of next year - lo, hi = _range(rewrite_natural_date_keywords("added:this month", UTC), "added") + lo, hi = _range(translate_query("added:this month", UTC), "added") assert lo == "2026-12-01T00:00:00Z" assert hi == "2027-01-01T00:00:00Z" @@ -259,7 +260,7 @@ class TestDateTimeFields: def test_last_month_january_wraps_to_previous_year(self) -> None: # January: last month wraps back to December of previous year lo, hi = _range( - rewrite_natural_date_keywords("added:previous month", UTC), + translate_query("added:previous month", UTC), "added", ) assert lo == "2025-12-01T00:00:00Z" @@ -295,7 +296,7 @@ class TestDateTimeFields: expected_lo: str, expected_hi: str, ) -> None: - lo, hi = _range(rewrite_natural_date_keywords(query, UTC), "added") + lo, hi = _range(translate_query(query, UTC), "added") assert lo == expected_lo assert hi == expected_hi @@ -309,20 +310,20 @@ class TestWhooshQueryRewriting: @time_machine.travel(datetime(2026, 3, 28, 15, 0, tzinfo=UTC), tick=False) def test_compact_date_shim_rewrites_to_iso(self) -> None: - result = rewrite_natural_date_keywords("created:20240115120000", UTC) + result = translate_query("created:20240115120000", UTC) assert "2024-01-15" in result assert "20240115120000" not in result @time_machine.travel(datetime(2026, 3, 28, 15, 0, tzinfo=UTC), tick=False) def test_relative_range_shim_removes_now(self) -> None: - result = rewrite_natural_date_keywords("added:[now-7d TO now]", UTC) + result = translate_query("added:[now-7d TO now]", UTC) assert "now" not in result assert "2026-03-" in result @time_machine.travel(datetime(2026, 3, 28, 12, 0, tzinfo=UTC), tick=False) def test_bracket_minus_7_days(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords("added:[-7 days to now]", UTC), + translate_query("added:[-7 days to now]", UTC), "added", ) assert lo == "2026-03-21T12:00:00Z" @@ -331,7 +332,7 @@ class TestWhooshQueryRewriting: @time_machine.travel(datetime(2026, 3, 28, 12, 0, tzinfo=UTC), tick=False) def test_bracket_minus_1_week(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords("added:[-1 week to now]", UTC), + translate_query("added:[-1 week to now]", UTC), "added", ) assert lo == "2026-03-21T12:00:00Z" @@ -341,7 +342,7 @@ class TestWhooshQueryRewriting: def test_bracket_minus_1_month_uses_relativedelta(self) -> None: # relativedelta(months=1) from 2026-03-28 = 2026-02-28 (not 29) lo, hi = _range( - rewrite_natural_date_keywords("created:[-1 month to now]", UTC), + translate_query("created:[-1 month to now]", UTC), "created", ) assert lo == "2026-02-28T12:00:00Z" @@ -350,7 +351,7 @@ class TestWhooshQueryRewriting: @time_machine.travel(datetime(2026, 3, 28, 12, 0, tzinfo=UTC), tick=False) def test_bracket_minus_1_year(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords("modified:[-1 year to now]", UTC), + translate_query("modified:[-1 year to now]", UTC), "modified", ) assert lo == "2025-03-28T12:00:00Z" @@ -359,7 +360,7 @@ class TestWhooshQueryRewriting: @time_machine.travel(datetime(2026, 3, 28, 12, 0, tzinfo=UTC), tick=False) def test_bracket_plural_unit_hours(self) -> None: lo, hi = _range( - rewrite_natural_date_keywords("added:[-3 hours to now]", UTC), + translate_query("added:[-3 hours to now]", UTC), "added", ) assert lo == "2026-03-28T09:00:00Z" @@ -367,7 +368,7 @@ class TestWhooshQueryRewriting: @time_machine.travel(datetime(2026, 3, 28, 12, 0, tzinfo=UTC), tick=False) def test_bracket_case_insensitive(self) -> None: - result = rewrite_natural_date_keywords("added:[-1 WEEK TO NOW]", UTC) + result = translate_query("added:[-1 WEEK TO NOW]", UTC) assert "now" not in result.lower() lo, hi = _range(result, "added") assert lo == "2026-03-21T12:00:00Z" @@ -377,7 +378,7 @@ class TestWhooshQueryRewriting: def test_relative_range_swaps_bounds_when_lo_exceeds_hi(self) -> None: # [now+1h TO now-1h] has lo > hi before substitution; they must be swapped lo, hi = _range( - rewrite_natural_date_keywords("added:[now+1h TO now-1h]", UTC), + translate_query("added:[now+1h TO now-1h]", UTC), "added", ) assert lo == "2026-03-28T11:00:00Z" @@ -385,14 +386,14 @@ class TestWhooshQueryRewriting: def test_8digit_created_date_field_always_uses_utc_midnight(self) -> None: # created is a DateField: boundaries are always UTC midnight, no TZ offset - result = rewrite_natural_date_keywords("created:20231201", EASTERN) + result = translate_query("created:20231201", EASTERN) lo, hi = _range(result, "created") assert lo == "2023-12-01T00:00:00Z" assert hi == "2023-12-02T00:00:00Z" def test_8digit_added_datetime_field_converts_local_midnight_to_utc(self) -> None: # added is DateTimeField: midnight Dec 1 Eastern (EST = UTC-5) = 05:00 UTC - result = rewrite_natural_date_keywords("added:20231201", EASTERN) + result = translate_query("added:20231201", EASTERN) lo, hi = _range(result, "added") assert lo == "2023-12-01T05:00:00Z" assert hi == "2023-12-02T05:00:00Z" @@ -400,7 +401,7 @@ class TestWhooshQueryRewriting: def test_8digit_modified_datetime_field_converts_local_midnight_to_utc( self, ) -> None: - result = rewrite_natural_date_keywords("modified:20231201", EASTERN) + result = translate_query("modified:20231201", EASTERN) lo, hi = _range(result, "modified") assert lo == "2023-12-01T05:00:00Z" assert hi == "2023-12-02T05:00:00Z" @@ -410,7 +411,7 @@ class TestWhooshQueryRewriting: # (e.g. month=13) so the API can surface a 400 telling the user the date # is malformed instead of silently returning zero results. with pytest.raises(InvalidDateQuery) as exc_info: - rewrite_natural_date_keywords("added:20231340", UTC) + translate_query("added:20231340", UTC) assert exc_info.value.field == "added" assert exc_info.value.value == "20231340" @@ -577,7 +578,7 @@ class TestYearRangeRewriting: expected_lo: str, expected_hi: str, ) -> None: - result = rewrite_natural_date_keywords(query, UTC) + result = translate_query(query, UTC) lo, hi = _range(result, field) assert lo == expected_lo assert hi == expected_hi @@ -585,14 +586,14 @@ class TestYearRangeRewriting: def test_reversed_year_range_is_swapped(self) -> None: # A reversed range must not yield lo > hi, which Tantivy treats as an # empty range (silently zero results). The bounds are swapped instead. - result = rewrite_natural_date_keywords("created:[2025 TO 2020]", UTC) + result = translate_query("created:[2025 TO 2020]", UTC) lo, hi = _range(result, "created") assert lo == "2020-01-01T00:00:00Z" assert hi == "2026-01-01T00:00:00Z" def test_year_range_in_complex_boolean_query(self) -> None: query = "tag:steuer AND (title:2020 OR (NOT title:2019 AND NOT title:2018 AND created:[2020 TO 2020]))" - result = rewrite_natural_date_keywords(query, UTC) + result = translate_query(query, UTC) lo, hi = _range(result, "created") assert lo == "2020-01-01T00:00:00Z" assert hi == "2021-01-01T00:00:00Z" @@ -602,7 +603,7 @@ class TestYearRangeRewriting: def test_already_iso_date_range_passes_through_unchanged(self) -> None: original = "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z]" - assert rewrite_natural_date_keywords(original, UTC) == original + assert translate_query(original, UTC) == original def test_8digit_in_brackets_not_matched_as_year_range(self) -> None: # [YYYYMMDD TO YYYYMMDD]: the translation layer converts 8-digit bounds to @@ -611,7 +612,7 @@ class TestYearRangeRewriting: # This is the correct and accepted behavior: old compact form becomes a # proper Tantivy-parseable ISO range. original = "created:[20200101 TO 20201231]" - result = rewrite_natural_date_keywords(original, UTC) + result = translate_query(original, UTC) lo, hi = _range(result, "created") assert lo == "2020-01-01T00:00:00Z" assert hi == "2021-01-01T00:00:00Z" @@ -634,7 +635,7 @@ class TestNonDateFieldsNotRewritten: ], ) def test_8digit_on_integer_field_passes_through_unchanged(self, query: str) -> None: - assert rewrite_natural_date_keywords(query, EASTERN) == query + assert translate_query(query, EASTERN) == query @pytest.mark.parametrize( "query", @@ -648,12 +649,12 @@ class TestNonDateFieldsNotRewritten: self, query: str, ) -> None: - assert rewrite_natural_date_keywords(query, UTC) == query + assert translate_query(query, UTC) == query def test_unknown_field_keyword_passes_through_unchanged(self) -> None: # foobar is not a date field: 'foobar:today' must not become a date range, # which Tantivy would otherwise reject as an unknown/typed field. - assert rewrite_natural_date_keywords("foobar:today", UTC) == "foobar:today" + assert translate_query("foobar:today", UTC) == "foobar:today" class TestPassthrough: @@ -661,37 +662,39 @@ class TestPassthrough: def test_bare_keyword_no_field_prefix_unchanged(self) -> None: # Bare 'today' with no field: prefix passes through unchanged - result = rewrite_natural_date_keywords("bank statement today", UTC) + result = translate_query("bank statement today", UTC) assert "today" in result def test_unrelated_query_unchanged(self) -> None: - assert rewrite_natural_date_keywords("title:invoice", UTC) == "title:invoice" + assert translate_query("title:invoice", UTC) == "title:invoice" class TestNormalizeQuery: - """normalize_query expands comma-separated values and collapses whitespace.""" + """translate_query expands comma-separated values and collapses whitespace.""" def test_normalize_expands_comma_separated_tags(self) -> None: - assert normalize_query("tag:foo,bar") == "tag:foo AND tag:bar" + assert translate_query("tag:foo,bar", UTC) == "tag:foo AND tag:bar" def test_normalize_comma_between_range_expressions(self) -> None: # Comma-separated field range expressions (Whoosh v2 syntax) must be # converted to AND so Tantivy does not receive an invalid comma. q = "created:[2026-01-01T00:00:00Z TO 2026-06-01T00:00:00Z],added:[2026-05-01T00:00:00Z TO 2026-06-01T00:00:00Z]" - assert normalize_query(q) == ( + assert translate_query(q, UTC) == ( "created:[2026-01-01T00:00:00Z TO 2026-06-01T00:00:00Z]" " AND " "added:[2026-05-01T00:00:00Z TO 2026-06-01T00:00:00Z]" ) def test_normalize_expands_three_values(self) -> None: - assert normalize_query("tag:foo,bar,baz") == "tag:foo AND tag:bar AND tag:baz" + assert ( + translate_query("tag:foo,bar,baz", UTC) == "tag:foo AND tag:bar AND tag:baz" + ) def test_normalize_collapses_whitespace(self) -> None: - assert normalize_query("bank statement") == "bank statement" + assert translate_query("bank statement", UTC) == "bank statement" def test_normalize_no_commas_unchanged(self) -> None: - assert normalize_query("bank statement") == "bank statement" + assert translate_query("bank statement", UTC) == "bank statement" @pytest.mark.parametrize( ("raw", "expected"), @@ -734,7 +737,7 @@ class TestNormalizeQuery: ], ) def test_normalize_strips_dangling_operators(self, raw: str, expected: str) -> None: - assert normalize_query(raw) == expected + assert translate_query(raw, UTC) == expected @pytest.mark.parametrize( "query", @@ -746,7 +749,7 @@ class TestNormalizeQuery: ], ) def test_normalize_preserves_valid_operators(self, query: str) -> None: - assert normalize_query(query) == query + assert translate_query(query, UTC) == query class TestParseSimpleTextHighlightQuery: diff --git a/src/documents/tests/search/test_translate.py b/src/documents/tests/search/test_translate.py index ff91cf301..e319564d1 100644 --- a/src/documents/tests/search/test_translate.py +++ b/src/documents/tests/search/test_translate.py @@ -214,27 +214,27 @@ class TestTranslateScalar: ( "created", "2020", - "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z]", + "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z}", ), ( "created", "202003", - "created:[2020-03-01T00:00:00Z TO 2020-04-01T00:00:00Z]", + "created:[2020-03-01T00:00:00Z TO 2020-04-01T00:00:00Z}", ), ( "created", "20200115", - "created:[2020-01-15T00:00:00Z TO 2020-01-16T00:00:00Z]", + "created:[2020-01-15T00:00:00Z TO 2020-01-16T00:00:00Z}", ), ( "created", "2020-01-15", - "created:[2020-01-15T00:00:00Z TO 2020-01-16T00:00:00Z]", + "created:[2020-01-15T00:00:00Z TO 2020-01-16T00:00:00Z}", ), ( "created", "2020-03", - "created:[2020-03-01T00:00:00Z TO 2020-04-01T00:00:00Z]", + "created:[2020-03-01T00:00:00Z TO 2020-04-01T00:00:00Z}", ), ], ) @@ -248,9 +248,9 @@ class TestTranslateScalar: assert exc_info.value.value == "202023" def test_keyword_delegates(self) -> None: - # keyword path produces a range; just assert it is a created range + # keyword path produces a half-open range; just assert it is a created range out = translate_scalar("created", "today", UTC) - assert out.startswith("created:[") and out.endswith("]") + assert out.startswith("created:[") and out.endswith("}") def test_14digit_compact_datetime(self) -> None: out = translate_scalar("created", "20240115120000", UTC) @@ -279,21 +279,21 @@ class TestTranslateRange: @pytest.mark.parametrize( ("lo", "hi", "expected"), [ - ("2005", "2009", "created:[2005-01-01T00:00:00Z TO 2010-01-01T00:00:00Z]"), + ("2005", "2009", "created:[2005-01-01T00:00:00Z TO 2010-01-01T00:00:00Z}"), ( "202001", "202006", - "created:[2020-01-01T00:00:00Z TO 2020-07-01T00:00:00Z]", + "created:[2020-01-01T00:00:00Z TO 2020-07-01T00:00:00Z}", ), ( "20200101", "20201231", - "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z]", + "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z}", ), ( "2020-01-01", "2020-12-31", - "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z]", + "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z}", ), ], ) @@ -302,7 +302,7 @@ class TestTranslateRange: def test_reversed_swaps(self): assert translate_range("created", "2009", "2005", UTC) == ( - "created:[2005-01-01T00:00:00Z TO 2010-01-01T00:00:00Z]" + "created:[2005-01-01T00:00:00Z TO 2010-01-01T00:00:00Z}" ) def test_open_upper(self): @@ -311,7 +311,7 @@ class TestTranslateRange: def test_open_lower(self): out = translate_range("created", "", "2020", UTC) - assert out == f"created:[{OPEN_LO} TO 2021-01-01T00:00:00Z]" + assert out == f"created:[{OPEN_LO} TO 2021-01-01T00:00:00Z}}" def test_invalid_bound_raises(self): with pytest.raises(InvalidDateQuery) as exc_info: @@ -334,16 +334,16 @@ class TestTranslateQuery: [ ( "created:2020", - "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z]", + "created:[2020-01-01T00:00:00Z TO 2021-01-01T00:00:00Z}", ), ("tag:foo,bar", "tag:foo AND tag:bar"), # 'type' is a user-facing alias rewritten to 'document_type' (the real schema field) ("tag:foo,type:bar", "tag:foo AND document_type:bar"), ( "created:[2020 TO 2021],added:[2022 TO 2023]", - "created:[2020-01-01T00:00:00Z TO 2022-01-01T00:00:00Z]" + "created:[2020-01-01T00:00:00Z TO 2022-01-01T00:00:00Z}" " AND " - "added:[2022-01-01T00:00:00Z TO 2024-01-01T00:00:00Z]", + "added:[2022-01-01T00:00:00Z TO 2024-01-01T00:00:00Z}", ), # correspondent is not multi-value: comma stays literal inside the value ("correspondent:foo,bar", "correspondent:foo,bar"), @@ -488,6 +488,66 @@ class TestRelativeRanges: index.parse_query(translated, DEFAULT_SEARCH_FIELDS, field_boosts=_FIELD_BOOSTS) +@pytest.mark.search +class TestWhooshUnitAbbreviations: + """ + Whoosh's PlusMinus date grammar accepted abbreviated unit spellings + (e.g. "yrs", "mos", "wks", "hrs", "mins", "secs"); saved views/searches + created under the old Whoosh backend can contain those tokens (see + https://github.com/paperless-ngx/paperless-ngx/issues/13482), so the + Tantivy translator must still accept them. + """ + + @time_machine.travel(_FROZEN_NOW, tick=False) + def test_minus_999_yrs(self) -> None: + assert translate_query("created:[-999yrs to now]", UTC) == ( + "created:[1027-03-28T12:00:00Z TO 2026-03-28T12:00:00Z]" + ) + + @pytest.mark.parametrize( + ("token", "expected_lo"), + [ + ("-1y", "2025-03-28T12:00:00Z"), + ("-1yr", "2025-03-28T12:00:00Z"), + ("-3mos", "2025-12-28T12:00:00Z"), + ("-3mo", "2025-12-28T12:00:00Z"), + ("-2wks", "2026-03-14T12:00:00Z"), + ("-2wk", "2026-03-14T12:00:00Z"), + ("-5dys", "2026-03-23T12:00:00Z"), + ("-5dy", "2026-03-23T12:00:00Z"), + ("-1hrs", "2026-03-28T11:00:00Z"), + ("-1hr", "2026-03-28T11:00:00Z"), + ("-10mins", "2026-03-28T11:50:00Z"), + ("-10min", "2026-03-28T11:50:00Z"), + ("-30secs", "2026-03-28T11:59:30Z"), + ("-30sec", "2026-03-28T11:59:30Z"), + ], + ) + @time_machine.travel(_FROZEN_NOW, tick=False) + def test_abbreviated_units(self, token: str, expected_lo: str) -> None: + assert translate_query(f"added:[{token} to now]", UTC) == ( + f"added:[{expected_lo} TO 2026-03-28T12:00:00Z]" + ) + + @pytest.mark.parametrize( + "raw", + [ + "created:[-999yrs to now]", + "added:[-1y to now]", + "created:[-3mos to now]", + "added:[-2wks to now]", + "added:[-5dys to now]", + "added:[-1hrs to now]", + "added:[-10mins to now]", + "added:[-30secs to now]", + ], + ) + @time_machine.travel(_FROZEN_NOW, tick=False) + def test_parse_acceptance(self, index: tantivy.Index, raw: str) -> None: + translated = translate_query(raw, UTC) + index.parse_query(translated, DEFAULT_SEARCH_FIELDS, field_boosts=_FIELD_BOOSTS) + + @pytest.mark.search class TestOperatorNormalization: """Post-render operator normalization in translate_query.""" @@ -506,7 +566,7 @@ class TestOperatorNormalization: def test_date_range_preserved(self) -> None: out = translate_query("created:[2020 TO 2021]", UTC) # Must not corrupt the ISO range - assert out == "created:[2020-01-01T00:00:00Z TO 2022-01-01T00:00:00Z]" + assert out == "created:[2020-01-01T00:00:00Z TO 2022-01-01T00:00:00Z}" def test_date_scalar_with_or(self) -> None: out = translate_query("created:2020 OR foo", UTC) @@ -581,42 +641,42 @@ class TestKeywordDateResolution: [ pytest.param( "today", - "created:[2026-03-28T00:00:00Z TO 2026-03-29T00:00:00Z]", + "created:[2026-03-28T00:00:00Z TO 2026-03-29T00:00:00Z}", id="today", ), pytest.param( "yesterday", - "created:[2026-03-27T00:00:00Z TO 2026-03-28T00:00:00Z]", + "created:[2026-03-27T00:00:00Z TO 2026-03-28T00:00:00Z}", id="yesterday", ), pytest.param( "previous week", - "created:[2026-03-16T00:00:00Z TO 2026-03-23T00:00:00Z]", + "created:[2026-03-16T00:00:00Z TO 2026-03-23T00:00:00Z}", id="previous-week", ), pytest.param( "this month", - "created:[2026-03-01T00:00:00Z TO 2026-04-01T00:00:00Z]", + "created:[2026-03-01T00:00:00Z TO 2026-04-01T00:00:00Z}", id="this-month", ), pytest.param( "previous month", - "created:[2026-02-01T00:00:00Z TO 2026-03-01T00:00:00Z]", + "created:[2026-02-01T00:00:00Z TO 2026-03-01T00:00:00Z}", id="previous-month", ), pytest.param( "this year", - "created:[2026-01-01T00:00:00Z TO 2027-01-01T00:00:00Z]", + "created:[2026-01-01T00:00:00Z TO 2027-01-01T00:00:00Z}", id="this-year", ), pytest.param( "previous year", - "created:[2025-01-01T00:00:00Z TO 2026-01-01T00:00:00Z]", + "created:[2025-01-01T00:00:00Z TO 2026-01-01T00:00:00Z}", id="previous-year", ), pytest.param( "previous quarter", - "created:[2025-10-01T00:00:00Z TO 2026-01-01T00:00:00Z]", + "created:[2025-10-01T00:00:00Z TO 2026-01-01T00:00:00Z}", id="previous-quarter", ), ], @@ -637,42 +697,42 @@ class TestKeywordDateResolution: [ pytest.param( "today", - "added:[2026-03-27T15:00:00Z TO 2026-03-28T15:00:00Z]", + "added:[2026-03-27T15:00:00Z TO 2026-03-28T15:00:00Z}", id="today", ), pytest.param( "yesterday", - "added:[2026-03-26T15:00:00Z TO 2026-03-27T15:00:00Z]", + "added:[2026-03-26T15:00:00Z TO 2026-03-27T15:00:00Z}", id="yesterday", ), pytest.param( "previous week", - "added:[2026-03-15T15:00:00Z TO 2026-03-22T15:00:00Z]", + "added:[2026-03-15T15:00:00Z TO 2026-03-22T15:00:00Z}", id="previous-week", ), pytest.param( "this month", - "added:[2026-02-28T15:00:00Z TO 2026-03-31T15:00:00Z]", + "added:[2026-02-28T15:00:00Z TO 2026-03-31T15:00:00Z}", id="this-month", ), pytest.param( "previous month", - "added:[2026-01-31T15:00:00Z TO 2026-02-28T15:00:00Z]", + "added:[2026-01-31T15:00:00Z TO 2026-02-28T15:00:00Z}", id="previous-month", ), pytest.param( "this year", - "added:[2025-12-31T15:00:00Z TO 2026-12-31T15:00:00Z]", + "added:[2025-12-31T15:00:00Z TO 2026-12-31T15:00:00Z}", id="this-year", ), pytest.param( "previous year", - "added:[2024-12-31T15:00:00Z TO 2025-12-31T15:00:00Z]", + "added:[2024-12-31T15:00:00Z TO 2025-12-31T15:00:00Z}", id="previous-year", ), pytest.param( "previous quarter", - "added:[2025-09-30T15:00:00Z TO 2025-12-31T15:00:00Z]", + "added:[2025-09-30T15:00:00Z TO 2025-12-31T15:00:00Z}", id="previous-quarter", ), ], @@ -719,7 +779,7 @@ class TestISODatetimeBounds: def test_translate_query_text_before_comma_separated_date_clause(self) -> None: result = translate_query("schäfersee,created:previous year", UTC) assert result == ( - "schäfersee AND created:[2025-01-01T00:00:00Z TO 2026-01-01T00:00:00Z]" + "schäfersee AND created:[2025-01-01T00:00:00Z TO 2026-01-01T00:00:00Z}" ) def test_invalid_iso_datetime_raises(self) -> None: diff --git a/src/documents/tests/test_api_bulk_edit.py b/src/documents/tests/test_api_bulk_edit.py index e4272e78f..dd62f0c74 100644 --- a/src/documents/tests/test_api_bulk_edit.py +++ b/src/documents/tests/test_api_bulk_edit.py @@ -343,9 +343,33 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase): m.assert_called_once() args, kwargs = m.call_args self.assertListEqual(args[0], [self.doc1.id, self.doc3.id]) - self.assertEqual(kwargs["add_custom_fields"], {str(self.cf1.id): "foo"}) + self.assertEqual(kwargs["add_custom_fields"], {self.cf1.id: "foo"}) self.assertEqual(kwargs["remove_custom_fields"], [self.cf2.id]) + @mock.patch("documents.serialisers.bulk_edit.modify_custom_fields") + def test_api_modify_custom_fields_rejects_invalid_value(self, m) -> None: + self.setup_mock(m, "modify_custom_fields") + + response = self.client.post( + "/api/documents/bulk_edit/", + json.dumps( + { + "documents": [self.doc1.id], + "method": "modify_custom_fields", + "parameters": { + "add_custom_fields": {self.cf1.id: "x" * 129}, + "remove_custom_fields": [], + }, + }, + ), + content_type="application/json", + ) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertIn("add_custom_fields", response.data) + self.assertIn(str(self.cf1.id), response.data["add_custom_fields"]) + m.assert_not_called() + @mock.patch("documents.serialisers.bulk_edit.modify_custom_fields") def test_api_modify_custom_fields_invalid_params(self, m) -> None: """ diff --git a/src/documents/tests/test_api_email.py b/src/documents/tests/test_api_email.py index f6f30a226..90a629e1a 100644 --- a/src/documents/tests/test_api_email.py +++ b/src/documents/tests/test_api_email.py @@ -75,7 +75,7 @@ class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase): { "documents": [self.doc1.pk, self.doc2.pk], "addresses": "hello@paperless-ngx.com,test@example.com", - "subject": "Bulk email test", + "subject": "Bulk email\n test", "message": "Here are your documents", }, ), diff --git a/src/documents/tests/test_api_search.py b/src/documents/tests/test_api_search.py index b42907132..dac1d6fb0 100644 --- a/src/documents/tests/test_api_search.py +++ b/src/documents/tests/test_api_search.py @@ -720,6 +720,48 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase): self.assertEqual(results[0]["id"], 3) self.assertEqual(results[0]["title"], "bank statement 3") + def test_search_added_previous_month_excludes_next_period_start(self) -> None: + """ + GIVEN: + - One document added at the last instant of last month + - One document added exactly at the first instant of this month + WHEN: + - Query for documents added in the previous month + THEN: + - Only the document from last month is returned; the document dated + exactly at the start of this month (the exclusive upper bound of + the range) is not + """ + d1 = DocumentFactory.create( + title="end of last month", + content="last instant of last month", + checksum="A", + pk=1, + added=timezone.make_aware(datetime.datetime(2024, 1, 31, 23, 59, 59)), + ) + d2 = DocumentFactory.create( + title="start of this month", + content="first instant of this month", + checksum="B", + pk=2, + added=timezone.make_aware(datetime.datetime(2024, 2, 1, 0, 0, 0)), + ) + + backend = get_backend() + backend.add_or_update(d1) + backend.add_or_update(d2) + + with time_machine.travel( + timezone.make_aware(datetime.datetime(2024, 2, 15, 12, 0, 0)), + tick=False, + ): + response = self.client.get("/api/documents/?query=added:previous month") + results = response.data["results"] + + self.assertEqual(len(results), 1) + self.assertEqual(results[0]["id"], 1) + self.assertEqual(results[0]["title"], "end of last month") + def test_search_added_invalid_date(self) -> None: """ GIVEN: diff --git a/src/documents/tests/test_consumer.py b/src/documents/tests/test_consumer.py index fccc736f6..e5b988e1d 100644 --- a/src/documents/tests/test_consumer.py +++ b/src/documents/tests/test_consumer.py @@ -1329,7 +1329,7 @@ class PreConsumeTestCase(DirectoriesMixin, GetConsumerMixin, TestCase): with self.get_consumer(self.test_file) as c: c.run() # Verify no pre-consume script subprocess was invoked - # (run_subprocess may still be called by _extract_text_for_archive_check) + # (run_subprocess may still be called by pdf_born_digital_text via pdftotext) script_calls = [ call for call in m.call_args_list @@ -1354,7 +1354,7 @@ class PreConsumeTestCase(DirectoriesMixin, GetConsumerMixin, TestCase): self.assertTrue(m.called) # Find the call that invoked the pre-consume script - # (run_subprocess may also be called by _extract_text_for_archive_check) + # (run_subprocess may also be called by pdf_born_digital_text via pdftotext) script_call = next( call for call in m.call_args_list diff --git a/src/documents/tests/test_consumer_archive.py b/src/documents/tests/test_consumer_archive.py index c179162db..59de1ce42 100644 --- a/src/documents/tests/test_consumer_archive.py +++ b/src/documents/tests/test_consumer_archive.py @@ -134,60 +134,32 @@ class TestShouldProduceArchive: assert should_produce_archive(parser, mime, Path("/tmp/doc")) is expected @pytest.mark.parametrize( - ("extracted_text", "expected"), + ("born_digital", "expected"), [ - pytest.param( - "This is a born-digital PDF with lots of text content. " * 10, - False, - id="born-digital-long-text-skips-archive", - ), - pytest.param(None, True, id="no-text-scanned-produces-archive"), - pytest.param("tiny", True, id="short-text-treated-as-scanned"), + pytest.param(True, False, id="born-digital-skips-archive"), + pytest.param(False, True, id="not-born-digital-produces-archive"), ], ) def test_auto_pdf_archive_decision( self, mocker: MockerFixture, settings, - extracted_text: str | None, + born_digital: bool, # noqa: FBT001 expected: bool, # noqa: FBT001 ) -> None: + """Archive decision tracks pdf_born_digital_text()'s verdict exactly. + + should_produce_archive() defers entirely to pdf_born_digital_text() + for the has-real-text decision, so both callers of that predicate + (this function and RasterisedDocumentParser.parse()) always agree. + """ settings.ARCHIVE_FILE_GENERATION = "auto" - mocker.patch("documents.consumer.is_tagged_pdf", return_value=False) - mocker.patch("documents.consumer.extract_pdf_text", return_value=extracted_text) + mocker.patch( + "documents.consumer.pdf_born_digital_text", + return_value=("some text", born_digital), + ) parser = _parser_instance(can_produce=True, requires_rendition=False) assert ( should_produce_archive(parser, "application/pdf", Path("/tmp/doc.pdf")) is expected ) - - def test_tagged_pdf_skips_archive_in_auto_mode( - self, - mocker: MockerFixture, - settings, - ) -> None: - """Tagged PDFs (e.g. Word exports) with real text are treated as born-digital, even below PDF_TEXT_MIN_LENGTH.""" - settings.ARCHIVE_FILE_GENERATION = "auto" - mocker.patch("documents.consumer.is_tagged_pdf", return_value=True) - mocker.patch("documents.consumer.extract_pdf_text", return_value="tiny") - parser = _parser_instance(can_produce=True, requires_rendition=False) - assert ( - should_produce_archive(parser, "application/pdf", Path("/tmp/doc.pdf")) - is False - ) - - def test_tagged_pdf_without_text_produces_archive( - self, - mocker: MockerFixture, - settings, - ) -> None: - """A tagged PDF with no actual extractable text (e.g. some scanner firmware) is not - trusted as born-digital — the tag alone must not bypass OCR.""" - settings.ARCHIVE_FILE_GENERATION = "auto" - mocker.patch("documents.consumer.is_tagged_pdf", return_value=True) - mocker.patch("documents.consumer.extract_pdf_text", return_value=None) - parser = _parser_instance(can_produce=True, requires_rendition=False) - assert ( - should_produce_archive(parser, "application/pdf", Path("/tmp/doc.pdf")) - is True - ) diff --git a/src/documents/tests/test_task_signals.py b/src/documents/tests/test_task_signals.py index 2c9fde16f..83652b5df 100644 --- a/src/documents/tests/test_task_signals.py +++ b/src/documents/tests/test_task_signals.py @@ -56,6 +56,32 @@ def send_publish( @pytest.mark.django_db class TestBeforeTaskPublishHandler: + @mock.patch("documents.signals.handlers.connections.all") + def test_closes_old_connections_outside_atomic_blocks( + self, + connections_all, + ) -> None: + connection = mock.Mock(in_atomic_block=False) + connections_all.return_value = [connection] + + task_id = send_publish("documents.tasks.train_classifier", (), {}) + + connection.close_if_unusable_or_obsolete.assert_called_once_with() + assert PaperlessTask.objects.filter(task_id=task_id).exists() + + @mock.patch("documents.signals.handlers.connections.all") + def test_keeps_connections_open_inside_atomic_blocks( + self, + connections_all, + ) -> None: + connection = mock.Mock(in_atomic_block=True) + connections_all.return_value = [connection] + + task_id = send_publish("documents.tasks.train_classifier", (), {}) + + connection.close_if_unusable_or_obsolete.assert_not_called() + assert PaperlessTask.objects.filter(task_id=task_id).exists() + def test_creates_task_for_consume_file( self, consume_input_doc, diff --git a/src/documents/tests/test_utils.py b/src/documents/tests/test_utils.py new file mode 100644 index 000000000..af45880ee --- /dev/null +++ b/src/documents/tests/test_utils.py @@ -0,0 +1,35 @@ +import pytest_mock + +from documents.utils import QuerySetStream + + +class TestQuerySetStream: + def test_len_and_iter_delegate_to_streaming_queryset_methods( + self, + mocker: pytest_mock.MockerFixture, + ) -> None: + """ + GIVEN: + - A mock queryset + WHEN: + - A QuerySetStream wrapping it is measured and iterated + THEN: + - len() uses count() (not a materializing len()), and iteration + uses .iterator(chunk_size=...) (not plain iteration, which + would materialize the whole queryset, plus any prefetch + caches, into Django's own result cache at once) + """ + mock_queryset = mocker.MagicMock() + mock_queryset.count.return_value = 42 + mock_queryset.iterator.return_value = iter(["row-1", "row-2"]) + streamed = QuerySetStream(mock_queryset, chunk_size=1000) + + assert len(streamed) == 42 + assert list(streamed) == ["row-1", "row-2"] + # count.call_count isn't asserted exactly: list()'s own size-hint + # optimization calls len(streamed) again internally, on top of the + # explicit len() call above -- both legitimately delegate to + # count(), so only the delegation itself (not the call count) is + # the thing being verified here. + mock_queryset.count.assert_called_with() + mock_queryset.iterator.assert_called_once_with(chunk_size=1000) diff --git a/src/documents/tests/test_views.py b/src/documents/tests/test_views.py index f64b6ea04..0cf1bcdae 100644 --- a/src/documents/tests/test_views.py +++ b/src/documents/tests/test_views.py @@ -491,6 +491,42 @@ class TestAISuggestions(DirectoriesMixin, TestCase): "Titre IA", ) + @patch("documents.views.get_ai_document_classification") + @override_settings( + AI_ENABLED=True, + LLM_BACKEND="mock_backend", + LLM_MODEL="model-a", + LLM_ENDPOINT="http://endpoint-a", + ) + def test_ai_suggestions_cache_key_includes_model_and_endpoint( + self, + mock_get_ai_classification, + ) -> None: + """Cached suggestions are keyed by model and endpoint, so switching + either yields a cache miss instead of a stale hit.""" + mock_get_ai_classification.return_value = { + "title": "Answer A", + "tags": [], + "correspondents": [], + "document_types": [], + "storage_paths": [], + "dates": [], + } + + self.client.force_login(user=self.user) + response = self.client.get( + f"/api/documents/{self.document.pk}/ai_suggestions/", + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Cached under a key that carries model + endpoint... + self.assertIsNotNone( + get_llm_suggestion_cache( + self.document.pk, + backend="mock_backend:model-a:http://endpoint-a", + ), + ) + @patch("documents.views.get_ai_document_classification") @override_settings( AI_ENABLED=True, diff --git a/src/documents/utils.py b/src/documents/utils.py index 2ed6758dd..d6e505aa4 100644 --- a/src/documents/utils.py +++ b/src/documents/utils.py @@ -3,16 +3,24 @@ import logging import shutil from collections.abc import Callable from collections.abc import Iterable +from collections.abc import Iterator from os import utime from pathlib import Path from subprocess import CompletedProcess from subprocess import run +from typing import TYPE_CHECKING +from typing import Generic from typing import TypeVar from django.conf import settings from PIL import Image +if TYPE_CHECKING: + from django.db.models import Model + from django.db.models import QuerySet + _T = TypeVar("_T") +_M = TypeVar("_M", bound="Model") # A function that wraps an iterable — typically used to inject a progress bar. IterWrapper = Callable[[Iterable[_T]], Iterable[_T]] @@ -23,6 +31,40 @@ def identity(iterable: Iterable[_T]) -> Iterable[_T]: return iterable +class QuerySetStream(Generic[_M]): + """Stream a QuerySet via .iterator(chunk_size=...) instead of + materializing it (plus any prefetch caches) all at once, while still + supporting len() via count() so a progress bar wrapped around this + (e.g. via IterWrapper) shows a real total instead of falling back to + indeterminate. + + Plain QuerySet iteration (``for row in queryset:``) is not lazy: Django + fetches every matching row in one query and caches the fully-hydrated + result in the queryset's own ``_result_cache`` before yielding the + first item -- wrapping that in a progress bar or any other iterable + adapter doesn't change this, since none of them alter how the + underlying queryset produces items. ``.iterator(chunk_size=...)`` is + the specific Django API that bypasses ``_result_cache`` and streams + from a server-side cursor instead, discarding each chunk once consumed + (and, since Django 4.1, still honours ``prefetch_related``, running the + prefetches one batch at a time rather than for the whole queryset). + + Subclass to layer additional per-batch work on top (see + ``documents.search._backend._DocumentViewerStream``) by overriding + ``__iter__`` -- ``__len__`` and the constructor are inherited for free. + """ + + def __init__(self, queryset: "QuerySet[_M]", *, chunk_size: int) -> None: + self._queryset = queryset + self._chunk_size = chunk_size + + def __len__(self) -> int: + return self._queryset.count() + + def __iter__(self) -> Iterator[_M]: + return iter(self._queryset.iterator(chunk_size=self._chunk_size)) + + def _coerce_to_path( source: Path | str, dest: Path | str, diff --git a/src/documents/views.py b/src/documents/views.py index 528d6ced5..3d6018d43 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -1530,10 +1530,15 @@ class DocumentViewSet( return HttpResponseBadRequest("AI is required for this feature") output_language = _get_llm_output_language(ai_config=ai_config, request=request) - llm_cache_backend = ( - f"{ai_config.llm_backend}:{output_language}" - if output_language - else ai_config.llm_backend + llm_cache_backend = ":".join( + part + for part in ( + ai_config.llm_backend, + ai_config.llm_model, + ai_config.llm_endpoint, + output_language, + ) + if part ) cached_llm_suggestions = get_llm_suggestion_cache( diff --git a/src/locale/af_ZA/LC_MESSAGES/django.po b/src/locale/af_ZA/LC_MESSAGES/django.po index e4a12fd6f..2be64a7de 100644 --- a/src/locale/af_ZA/LC_MESSAGES/django.po +++ b/src/locale/af_ZA/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Afrikaans\n" "Language: af_ZA\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Ongeldige kleur." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Lêertipe %(type)s word nie ondersteun nie" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ongeldige veranderlike bespeur." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/am_ET/LC_MESSAGES/django.po b/src/locale/am_ET/LC_MESSAGES/django.po index b582ea706..672cd68c1 100644 --- a/src/locale/am_ET/LC_MESSAGES/django.po +++ b/src/locale/am_ET/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Amharic\n" "Language: am_ET\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ar_AR/LC_MESSAGES/django.po b/src/locale/ar_AR/LC_MESSAGES/django.po index 82b160330..a814662f4 100644 --- a/src/locale/ar_AR/LC_MESSAGES/django.po +++ b/src/locale/ar_AR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Arabic\n" "Language: ar_SA\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "لون خاطئ." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "نوع الملف %(type)s غير مدعوم" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "اكتشاف متغير خاطئ." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/be_BY/LC_MESSAGES/django.po b/src/locale/be_BY/LC_MESSAGES/django.po index d1c4b4069..3f016a141 100644 --- a/src/locale/be_BY/LC_MESSAGES/django.po +++ b/src/locale/be_BY/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Belarusian\n" "Language: be_BY\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Няправільны колер." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Тып файла %(type)s не падтрымліваецца" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Выяўлена няправільная зменная." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/bg_BG/LC_MESSAGES/django.po b/src/locale/bg_BG/LC_MESSAGES/django.po index dcce36278..e2987ab9c 100644 --- a/src/locale/bg_BG/LC_MESSAGES/django.po +++ b/src/locale/bg_BG/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Bulgarian\n" "Language: bg_BG\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "стартиране на работните процеси" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Невалиден цвят." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Файловия тип %(type)s не се поддържа" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Засечена е невалидна променлива." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ca_ES/LC_MESSAGES/django.po b/src/locale/ca_ES/LC_MESSAGES/django.po index c7e325744..10ab8befa 100644 --- a/src/locale/ca_ES/LC_MESSAGES/django.po +++ b/src/locale/ca_ES/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Catalan\n" "Language: ca_ES\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "flux corrents" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Permisos insuficients." @@ -1348,38 +1348,38 @@ msgstr "Permisos insuficients." msgid "Invalid color." msgstr "Color Invàlid." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tipus arxiu %(type)s no suportat" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "ID de camp personalizat ha de ser enter: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Camp personalitzat amb ID %(id)s no existeix" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Camps personalitzats han de ser una llista d'enters o un objecte que mapegi els identificadors amb els valors." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Alguns camps personalitzats no existeixen o s'han especificat dues vegades." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variable detectada invàlida." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Duplicat d'identificadors de documents no permès." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documents no trobats: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "L'esquema d'URI '{parts.scheme}' no està permès. Esquemes permesos: {' msgid "Unable to parse URI {value}" msgstr "No s'ha pogut analitzar l'URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Invalid more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Configuració AI invàlida." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Especifica només un dels següents valors: text, title_search, query o more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Permisos insuficients per compartir document %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paquet ja s'està processant." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "El paquet de link encarà s'està preparant. Prova de nou més tard." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "El paquet d'enllaç no està disponible." diff --git a/src/locale/cs_CZ/LC_MESSAGES/django.po b/src/locale/cs_CZ/LC_MESSAGES/django.po index 6a89a08a3..0275dd29f 100644 --- a/src/locale/cs_CZ/LC_MESSAGES/django.po +++ b/src/locale/cs_CZ/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Czech\n" "Language: cs_CZ\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "spuštění pracovních postupů" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Nedostatečná oprávnění." @@ -1348,38 +1348,38 @@ msgstr "Nedostatečná oprávnění." msgid "Invalid color." msgstr "Neplatná barva." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Typ souboru %(type)s není podporován" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Vlastní ID pole musí být celé číslo: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Vlastní pole s ID %(id)s neexistuje" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Vlastní pole musí být seznam celých čísel nebo ID pro mapování objektů na hodnoty." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Některá vlastní pole neexistují nebo byla zadána dvakrát." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Zjištěna neplatná proměnná." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1636,36 +1636,36 @@ msgstr "URI schéma '{parts.scheme}' není povoleno. Povolená schémata: {',\n" msgid "Unable to parse URI {value}" msgstr "Nelze zpracovat URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nedostatečná oprávnění ke sdílení dokumentu %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/da_DK/LC_MESSAGES/django.po b/src/locale/da_DK/LC_MESSAGES/django.po index 376f62469..9030ea25e 100644 --- a/src/locale/da_DK/LC_MESSAGES/django.po +++ b/src/locale/da_DK/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Danish\n" "Language: da_DK\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "workflow-kørsler" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Ugyldig farve." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Filtype %(type)s understøttes ikke" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ugyldig variabel fundet." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/de_CH/LC_MESSAGES/django.po b/src/locale/de_CH/LC_MESSAGES/django.po index d5440e9bb..95cd4bc2e 100644 --- a/src/locale/de_CH/LC_MESSAGES/django.po +++ b/src/locale/de_CH/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: German, Switzerland\n" "Language: de_CH\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "Arbeitsablauf wird ausgeführt" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Unzureichende Berechtigungen." @@ -1348,38 +1348,38 @@ msgstr "Unzureichende Berechtigungen." msgid "Invalid color." msgstr "Ungültige Farbe." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Dateityp %(type)s nicht unterstützt" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Feld-ID eines benutzerdefinierten Felds muss eine Ganzzahl sein: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Benutzerdefiniertes Feld mit ID %(id)s existiert nicht" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Benutzerdefinierte Felder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Einige benutzerdefinierte Felder existieren nicht oder wurden zweimal angegeben." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ungültige Variable erkannt." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumente nicht gefunden: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "URI-Schema „{parts.scheme}“ ist nicht erlaubt. Erlaubte Schemata: {' msgid "Unable to parse URI {value}" msgstr "URI {value} kann nicht gelesen werden" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Ungültige more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Ungültige KI-Konfiguration." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket wird bereits verarbeitet." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Das Freigabelink-Paket ist nicht verfügbar." diff --git a/src/locale/de_DE/LC_MESSAGES/django.po b/src/locale/de_DE/LC_MESSAGES/django.po index 95af669c4..c81210df6 100644 --- a/src/locale/de_DE/LC_MESSAGES/django.po +++ b/src/locale/de_DE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: German\n" "Language: de_DE\n" @@ -722,7 +722,7 @@ msgstr "Wartezeit (Sekunden)" #: documents/models.py:779 msgid "Time from task creation to worker pickup" -msgstr "Zeit von der Aufgabenerstellung bis zur Abholung des Workers" +msgstr "Zeit von der Aufgabenerstellung bis zur Übernahme durch einen Worker" #: documents/models.py:786 msgid "Input Data" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "Arbeitsablauf wird ausgeführt" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Unzureichende Berechtigungen." @@ -1348,38 +1348,38 @@ msgstr "Unzureichende Berechtigungen." msgid "Invalid color." msgstr "Ungültige Farbe." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Dateityp %(type)s nicht unterstützt" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Zusatzfeld-ID muss eine Ganzzahl sein: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Zusatzfeld mit ID %(id)s existiert nicht" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Zusatzfelder müssen eine Liste von Ganzzahlen oder ein Objekt mit Zuordnung von IDs zu Werten sein." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Einige Zusatzfelder existieren nicht oder wurden zweimal angegeben." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ungültige Variable erkannt." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Doppelte Dokumentbezeichner sind nicht erlaubt." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumente nicht gefunden: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "URI-Schema „{parts.scheme}“ ist nicht erlaubt. Erlaubte Schemata: {' msgid "Unable to parse URI {value}" msgstr "URI {value} kann nicht gelesen werden" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Ungültige more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Ungültige KI-Konfiguration." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "Zeitüberschreitung bei der KI-Backendanfrage." -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Geben Sie nur einen von text, title_search, query, oder more_like_id an." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Unzureichende Berechtigungen, um Dokument %(id)s zu teilen." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket wird bereits verarbeitet." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Das Freigabelink-Paket wird noch vorbereitet. Bitte versuchen Sie es später erneut." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Das Freigabelink-Paket ist nicht verfügbar." diff --git a/src/locale/el_GR/LC_MESSAGES/django.po b/src/locale/el_GR/LC_MESSAGES/django.po index 3a03ff0f0..c9d41759d 100644 --- a/src/locale/el_GR/LC_MESSAGES/django.po +++ b/src/locale/el_GR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Greek\n" "Language: el_GR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "εκτελέσεις ροής εργασίας" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Άκυρο χρώμα." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Ο τύπος αρχείου %(type)s δεν υποστηρίζεται" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Εντοπίστηκε μη έγκυρη μεταβλητή." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/en_US/LC_MESSAGES/django.po b/src/locale/en_US/LC_MESSAGES/django.po index 8648046c8..72b1fd215 100644 --- a/src/locale/en_US/LC_MESSAGES/django.po +++ b/src/locale/en_US/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" "PO-Revision-Date: 2022-02-17 04:17\n" "Last-Translator: \n" "Language-Team: English\n" @@ -1352,7 +1352,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1361,39 +1361,39 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "" "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1661,36 +1661,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/es_ES/LC_MESSAGES/django.po b/src/locale/es_ES/LC_MESSAGES/django.po index 52892a3ce..7e9249ad3 100644 --- a/src/locale/es_ES/LC_MESSAGES/django.po +++ b/src/locale/es_ES/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Spanish\n" "Language: es_ES\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "ejecuciones de flujo de trabajo" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Permisos insuficientes." @@ -1348,38 +1348,38 @@ msgstr "Permisos insuficientes." msgid "Invalid color." msgstr "Color inválido." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de fichero %(type)s no suportado" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "El id del campo personalizado debe ser un entero: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "El campo personalizado con identificador %(id)s no existe" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Los campos personalizados deben ser una lista de enteros o un identificador de mapeo de objetos a valores." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Algunos campos personalizados no existen o fueron especificados dos veces." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variable inválida." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "No se permiten identificadores de documento duplicados." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documentos no encontrados: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "El esquema URI '{parts.scheme}' no está permitido. Esquemas permitidos: msgid "Unable to parse URI {value}" msgstr "No se puede analizar la URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Configuración de IA inválida." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Especifique solo uno entre text, title_search, query, o more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Permisos insuficientes para compartir el documento %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "El paquete ya está siendo procesado." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "El paquete de enlace compartido aún está siendo preparado. Por favor, inténtalo de nuevo más tarde." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "El paquete de enlace compartido no está disponible." diff --git a/src/locale/et_EE/LC_MESSAGES/django.po b/src/locale/et_EE/LC_MESSAGES/django.po index 1e8b47b0d..e7c36bbf1 100644 --- a/src/locale/et_EE/LC_MESSAGES/django.po +++ b/src/locale/et_EE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Estonian\n" "Language: et_EE\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/fa_IR/LC_MESSAGES/django.po b/src/locale/fa_IR/LC_MESSAGES/django.po index e6d7a8089..ab24744b2 100644 --- a/src/locale/fa_IR/LC_MESSAGES/django.po +++ b/src/locale/fa_IR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Persian\n" "Language: fa_IR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "گردش کار اجرا می شود" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "رنگ نامعتبر" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "متغیر نامعتبر شناسایی شده است." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/fi_FI/LC_MESSAGES/django.po b/src/locale/fi_FI/LC_MESSAGES/django.po index 965a6d696..887eb9648 100644 --- a/src/locale/fi_FI/LC_MESSAGES/django.po +++ b/src/locale/fi_FI/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Finnish\n" "Language: fi_FI\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Virheellinen väri." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tiedostotyyppiä %(type)s ei tueta" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Virheellinen muuttuja havaittu." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/fr_FR/LC_MESSAGES/django.po b/src/locale/fr_FR/LC_MESSAGES/django.po index 847a11e35..77021a389 100644 --- a/src/locale/fr_FR/LC_MESSAGES/django.po +++ b/src/locale/fr_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "le flux de travail s'exécute" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Droits insuffisants." @@ -1348,38 +1348,38 @@ msgstr "Droits insuffisants." msgid "Invalid color." msgstr "Couleur incorrecte." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Type de fichier %(type)s non pris en charge" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "L'id du champ personnalisé doit être un entier : %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Le champ personnalisé avec l'id %(id)s n'existe pas" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Les champs personnalisés doivent être une liste d'entiers ou un mappage d'identifiants à des valeurs." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Certains champs personnalisés n'existent pas ou ont été spécifiés deux fois." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variable invalide détectée." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Les identificateurs de document en double ne sont pas autorisés." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documents introuvables : %(ids)s" @@ -1634,36 +1634,36 @@ msgstr "Le schéma d'URI « {parts.scheme} » n'est pas autorisé. Schémas aut msgid "Unable to parse URI {value}" msgstr "Impossible d'analyser l'URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "More_like_id invalide" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Configuration IA invalide." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "La requête d'arrière-plan IA a expiré." -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Spécifiez seulement un texte, titre, recherche ou more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Droits d'accès insuffisant pour partager %(id)s document." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Le paquet est déjà en cours de traitement." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Le lot de liens de partage est en cours de préparation. Veuillez réessayer plus tard." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Le lot de liens de partage n'est pas disponible." diff --git a/src/locale/he_IL/LC_MESSAGES/django.po b/src/locale/he_IL/LC_MESSAGES/django.po index da303cae5..88694e358 100644 --- a/src/locale/he_IL/LC_MESSAGES/django.po +++ b/src/locale/he_IL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Hebrew\n" "Language: he_IL\n" @@ -1340,7 +1340,7 @@ msgid "workflow runs" msgstr "הרצות זרימת עבודה" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "הרשאות אינן מספיקות." @@ -1349,38 +1349,38 @@ msgstr "הרשאות אינן מספיקות." msgid "Invalid color." msgstr "צבע לא חוקי." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "סוג קובץ %(type)s לא נתמך" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "שדה מותאם אישית id חייב להיות מספרי: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "שדה מותאם אישית עם מזהה %(id)s איננו קיים" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "שדות מותאמים אישית חייבים להיות רשימה של מספרים שלמים או אובייקט הממפה מזהים לערכים." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "חלק מהשדות המותאמים אישית אינם קיימים או שהוגדרו פעמיים." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "משתנה לא חוקי זוהה." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "מזהי מסמכים כפולים אינם מורשים." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "מסמכים לא נמצאו: %(ids)s" @@ -1636,36 +1636,36 @@ msgstr "פרוטוקול ה-URI ‏'{parts.scheme}' אינו מורשה. הפר msgid "Unable to parse URI {value}" msgstr "לא ניתן לפענח את ה URI ‏{value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "מזהה more_like_id אינו תקין" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "הגדרות בינה מלאכותית שגויות." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "יש לציין רק אחד מהבאים: text‏, title_search‏, query או more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "הרשאות לא מספיקות לשיתוף מסמך %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "החבילה (Bundle) כבר נמצאת בתהליך עיבוד." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "חבילת קישור השיתוף עדיין בהכנה. נא לנסות שוב מאוחר יותר." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "חבילת קישור השיתוף אינה זמינה." diff --git a/src/locale/hi_IN/LC_MESSAGES/django.po b/src/locale/hi_IN/LC_MESSAGES/django.po index 15b93af59..bae011644 100644 --- a/src/locale/hi_IN/LC_MESSAGES/django.po +++ b/src/locale/hi_IN/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Hindi\n" "Language: hi_IN\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/hr_HR/LC_MESSAGES/django.po b/src/locale/hr_HR/LC_MESSAGES/django.po index e16dc4f93..340d5b33e 100644 --- a/src/locale/hr_HR/LC_MESSAGES/django.po +++ b/src/locale/hr_HR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Croatian\n" "Language: hr_HR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "tijek rada pokrenut" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Nedovoljne ovlasti." @@ -1348,38 +1348,38 @@ msgstr "Nedovoljne ovlasti." msgid "Invalid color." msgstr "Nevažeća boja." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s nije podržana" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "ID prilagođenog polja mora biti cijeli broj: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Prilagođeno polje s ID-om %(id)s ne postoji" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Prilagođena polja moraju biti popis cijelih brojeva ili ID-ova objekata koji preslikavaju vrijednosti." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Neka prilagođena polja ne postoje ili su navedena dvaput." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Otkrivena je nevaljana vrsta datoteke." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Duplicirani identifikatori dokumenata nisu dopušteni." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumenti nisu pronađeni: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "URI shema '{parts.scheme}' nije dopuštena. Dopuštene sheme: {', '.join msgid "Unable to parse URI {value}" msgstr "Nije moguće raščlaniti URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Nevažeći more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Nevažeća AI konfiguracija." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Navedite samo jedno od: text, title_search, query ili more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nedovoljne ovlasti za dijeljenje dokumenta %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket se već obrađuje." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Paket linka za dijeljenje se još priprema. Pokušajte ponovo kasnije." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Paket linka za dijeljenje nije dostupan." diff --git a/src/locale/hu_HU/LC_MESSAGES/django.po b/src/locale/hu_HU/LC_MESSAGES/django.po index 890527fc8..329979d83 100644 --- a/src/locale/hu_HU/LC_MESSAGES/django.po +++ b/src/locale/hu_HU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Hungarian\n" "Language: hu_HU\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "munkafolyamat futtatások" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Nincs jogosúltsága." @@ -1348,38 +1348,38 @@ msgstr "Nincs jogosúltsága." msgid "Invalid color." msgstr "Érvénytelen szín." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "%(type)s fájltípus nem támogatott" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Az egyéni mező azonosítójának egész számnak kell lennie: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "A(z) %(id)s azonosítójú egyéni mező nem létezik" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Az egyéni mezőknek egész számok listájának vagy azonosítókat értékekhez rendelő objektumnak kell lenniük." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Néhány egyéni mező nem létezik, vagy kétszer lett megadva." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Érvénytelen változó észlelve." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "A dokumentumazonosítók duplikálása nem megengedett." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumentumok nem találhatók: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "A '{parts.scheme}' séma nem engedélyezett. Engedélyezett sémák: {', msgid "Unable to parse URI {value}" msgstr "A {value} URI értelmezése sikertelen" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Érvénytelen more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Érvénytelen MI konfiguráció." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "A text, title_search, query, vagy more_like_id közül csak egyet adjon meg." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nincs megfelelő jogosultság a %(id)s dokumentum megosztásához." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "A csomag feldolgozása már folyamatban van." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "A megosztási linkcsomag készítése folyamatban. Kérjük, próbálja meg később." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "A megosztási linkcsomag nem elérhető." diff --git a/src/locale/id_ID/LC_MESSAGES/django.po b/src/locale/id_ID/LC_MESSAGES/django.po index e391bcfd7..2d92e7d7f 100644 --- a/src/locale/id_ID/LC_MESSAGES/django.po +++ b/src/locale/id_ID/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Indonesian\n" "Language: id_ID\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "daftar jalankan alur kerja" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Izin tidak mencukupi" @@ -1348,38 +1348,38 @@ msgstr "Izin tidak mencukupi" msgid "Invalid color." msgstr "Warna tidak sesuai." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Jenis berkas %(type)s tidak didukung" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Id kolom kustom harus berupa bilangan bulat: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Kolom kustom dengan id %(id)s tidak ada" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Kolom kustom harus berupa daftar bilangan bulat atau objek yang memetakan id ke nilai." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Beberapa kolom kustom tidak ada atau ditentukan dua kali." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variabel ilegal terdeteksi." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Penggunaan pengenal dokumen ganda tidak diperbolehkan." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumen tidak ditemukan: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Skema URI '{parts.scheme}' tidak diizinkan. Skema yang diizinkan: {', '. msgid "Unable to parse URI {value}" msgstr "Gagal membaca URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Izin tidak mencukupi untuk berbagi dokumen %(id)s" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket sedang diproses." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Bundel tautan berbagi masih dalam proses persiapan. Silakan coba lagi nanti." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Bundel tautan berbagi tidak tersedia." diff --git a/src/locale/it_IT/LC_MESSAGES/django.po b/src/locale/it_IT/LC_MESSAGES/django.po index 91e3c42f2..483e3cf3e 100644 --- a/src/locale/it_IT/LC_MESSAGES/django.po +++ b/src/locale/it_IT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Italian\n" "Language: it_IT\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "esecuzioni del flusso di lavoro" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Autorizzazioni insufficienti." @@ -1348,38 +1348,38 @@ msgstr "Autorizzazioni insufficienti." msgid "Invalid color." msgstr "Colore non valido." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Il tipo di file %(type)s non è supportato" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "L'ID del campo personalizzato deve essere un numero intero: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Il campo personalizzato con ID %(id)s non esiste" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "I campi personalizzati devono essere un elenco di numeri interi o un oggetto che mappa gli ID ai valori." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Alcuni campi personalizzati non esistono o sono stati specificati due volte." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variabile non valida rilevata." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Non sono consentiti identificatori di documenti duplicati." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documenti non trovati: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Lo schema URI '{parts.scheme}' non è consentito. Schemi consentiti: {', msgid "Unable to parse URI {value}" msgstr "Impossibile analizzare l'URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "more_like_id non valido" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Configurazione AI non valida." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "Richiesta di backend AI scaduta." -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Specificare solo uno tra text, title_search, query o more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Autorizzazioni insufficienti per condividere il documento %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Il pacchetto è già in fase di elaborazione." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Il pacchetto di link di condivisione è ancora in fase di preparazione. Riprova più tardi." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Il pacchetto di link di condivisione non è disponibile." diff --git a/src/locale/ja_JP/LC_MESSAGES/django.po b/src/locale/ja_JP/LC_MESSAGES/django.po index dce5e8a5c..07289f4ec 100644 --- a/src/locale/ja_JP/LC_MESSAGES/django.po +++ b/src/locale/ja_JP/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Japanese\n" "Language: ja_JP\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "ワークフローの実行" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "無効な色" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "ファイルタイプ %(type)s はサポートされていません" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "無効な変数を検出しました" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ko_KR/LC_MESSAGES/django.po b/src/locale/ko_KR/LC_MESSAGES/django.po index 105c1f16a..66cd4c097 100644 --- a/src/locale/ko_KR/LC_MESSAGES/django.po +++ b/src/locale/ko_KR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Korean\n" "Language: ko_KR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "워크플로우 실행" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "사용자 정의 ID 필드는 반드시 정수여야 합니다: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "%(id)s를 ID로 가지는 사용자 정의 필드가 존재하지 않습니다." -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "사용자 정의 필드는 정수 리스트이거나, ID를 값에 매핑하는 객체여야 합니다." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "존재하지 않거나 중복된 사용자 정의 필드가 있습니다." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "잘못된 변수가 감지되었습니다." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "URI 스킴 '{parts.scheme}'는 허용되지 않습니다. 허용된 스 msgid "Unable to parse URI {value}" msgstr "{value} URI를 파싱할 수 없음" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/lb_LU/LC_MESSAGES/django.po b/src/locale/lb_LU/LC_MESSAGES/django.po index 500a00b58..f31c88563 100644 --- a/src/locale/lb_LU/LC_MESSAGES/django.po +++ b/src/locale/lb_LU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Luxembourgish\n" "Language: lb_LU\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Ongëlteg Faarf." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Fichierstyp %(type)s net ënnerstëtzt" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ongëlteg Zeechen detektéiert." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/lt_LT/LC_MESSAGES/django.po b/src/locale/lt_LT/LC_MESSAGES/django.po index 478969a1b..abd1f4bb8 100644 --- a/src/locale/lt_LT/LC_MESSAGES/django.po +++ b/src/locale/lt_LT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Lithuanian\n" "Language: lt_LT\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "URI schema '{parts.scheme}' nėra leistina. Galimos schemos: {', '.join( msgid "Unable to parse URI {value}" msgstr "Nepavyko apdoroti URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nepakanka leidimų bendrinti dokumentą %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Rinkinys jau apdorojamas." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Bendrinimo nuorodų rinkinys vis dar ruošiamas. Bandykite dar kartą vėliau." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Dalinimos nuorodų rinkinys yra nepasiekiamas." diff --git a/src/locale/lv_LV/LC_MESSAGES/django.po b/src/locale/lv_LV/LC_MESSAGES/django.po index 988448657..ae55f7202 100644 --- a/src/locale/lv_LV/LC_MESSAGES/django.po +++ b/src/locale/lv_LV/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Latvian\n" "Language: lv_LV\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/mk_MK/LC_MESSAGES/django.po b/src/locale/mk_MK/LC_MESSAGES/django.po index 78f82087e..6bbc45694 100644 --- a/src/locale/mk_MK/LC_MESSAGES/django.po +++ b/src/locale/mk_MK/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Macedonian\n" "Language: mk_MK\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ms_MY/LC_MESSAGES/django.po b/src/locale/ms_MY/LC_MESSAGES/django.po index 1d84c0a81..3af95c69a 100644 --- a/src/locale/ms_MY/LC_MESSAGES/django.po +++ b/src/locale/ms_MY/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Malay\n" "Language: ms_MY\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/nl_NL/LC_MESSAGES/django.po b/src/locale/nl_NL/LC_MESSAGES/django.po index 4d6d74302..f2b257379 100644 --- a/src/locale/nl_NL/LC_MESSAGES/django.po +++ b/src/locale/nl_NL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Dutch\n" "Language: nl_NL\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Ongeldig kleur." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Bestandstype %(type)s niet ondersteund" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Aangepast veld met id %(id)s bestaat niet" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Aangepaste velden moeten een lijst van numerieke waarden zijn of een object mapping id naar waarden." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Sommige aangepaste velden bestaan niet of zijn dubbel opgegeven." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ongeldige variabele ontdekt." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/no_NO/LC_MESSAGES/django.po b/src/locale/no_NO/LC_MESSAGES/django.po index 52ce43aa5..5da76951e 100644 --- a/src/locale/no_NO/LC_MESSAGES/django.po +++ b/src/locale/no_NO/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Norwegian\n" "Language: no_NO\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "workflow runs (NO)" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Insufficient permissions. (NO)" @@ -1348,38 +1348,38 @@ msgstr "Insufficient permissions. (NO)" msgid "Invalid color." msgstr "Ugyldig farge." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Filtype %(type)s støttes ikke" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Egendefinert felt-id må være et heltall: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Egendefinert felt med id %(id)s finnes ikke" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Custom fields must be a list of integers or an object mapping ids to values. (NO)" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Some custom fields don't exist or were specified twice. (NO)" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ugyldig variabel oppdaget." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Duplicate document identifiers are not allowed. (NO)" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documents not found: %(ids)s (NO)" @@ -1635,36 +1635,36 @@ msgstr "URI scheme '{parts.scheme}' is not allowed. Allowed schemes: {', '.join( msgid "Unable to parse URI {value}" msgstr "Unable to parse URI {value} (NO)" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Invalid more_like_id (NO)" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Invalid AI configuration. (NO)" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "Forespørselen til KI-tjenesten fikk tidsavbrudd." -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Specify only one of text, title_search, query, or more_like_id. (NO)" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Insufficient permissions to share document %(id)s. (NO)" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Bundle is already being processed. (NO)" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "The share link bundle is still being prepared. Please try again later. (NO)" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "The share link bundle is unavailable. (NO)" diff --git a/src/locale/pl_PL/LC_MESSAGES/django.po b/src/locale/pl_PL/LC_MESSAGES/django.po index ea5d06eb9..a1e351af2 100644 --- a/src/locale/pl_PL/LC_MESSAGES/django.po +++ b/src/locale/pl_PL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Polish\n" "Language: pl_PL\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "uruchomienia przepływu pracy" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Niewystarczające uprawnienia." @@ -1348,38 +1348,38 @@ msgstr "Niewystarczające uprawnienia." msgid "Invalid color." msgstr "Nieprawidłowy kolor." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Typ pliku %(type)s nie jest obsługiwany" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Identyfikator pola niestandardowego musi być liczbą całkowitą: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Pole niestandardowe z id %(id)s nie istnieje" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Pola niestandardowe muszą być listą liczb całkowitych lub obiektem mapującym identyfikatory na wartości." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Niektóre niestandardowe pola nie istnieją lub zostały określone dwukrotnie." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Wykryto nieprawidłową zmienną." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Nie dopuszcza się powielania identyfikatorów dokumentów." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Nie znaleziono dokumentów: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Schemat URI '{parts.scheme}' jest niedozwolony. Dozwolone schematy: {', msgid "Unable to parse URI {value}" msgstr "Nie można przetworzyć URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Nieprawidłowy more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Brak uprawnień do udostępnienia dokumentu %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Pakiet jest już przetwarzany." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Pakiet do udostępnienia jest nadal przygotowywany. Spróbuj ponownie później." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Pakiet do udostępnienia jest niedostępny." diff --git a/src/locale/pt_BR/LC_MESSAGES/django.po b/src/locale/pt_BR/LC_MESSAGES/django.po index 0d8f2c283..59641ed6b 100644 --- a/src/locale/pt_BR/LC_MESSAGES/django.po +++ b/src/locale/pt_BR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt_BR\n" @@ -1340,7 +1340,7 @@ msgid "workflow runs" msgstr "execução de fluxo de trabalho" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1349,38 +1349,38 @@ msgstr "" msgid "Invalid color." msgstr "Cor inválida." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de arquivo %(type)s não suportado" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "O ID do campo personalizado deve ser um número inteiro: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Não existe um campo personalizado com o ID %(id)s" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Campos personalizados devem estar em uma lista de números inteiros ou em um objeto que relacione IDs a valores." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Campos personalizados inválidos ou duplicados." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variável inválida detectada." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1637,36 +1637,36 @@ msgstr "Esquema URI '{parts.scheme}' não é permitido. Esquemas permitidos:\n" msgid "Unable to parse URI {value}" msgstr "Não é possível analisar o URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/pt_PT/LC_MESSAGES/django.po b/src/locale/pt_PT/LC_MESSAGES/django.po index 05a90e6f8..55f43c4f0 100644 --- a/src/locale/pt_PT/LC_MESSAGES/django.po +++ b/src/locale/pt_PT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Portuguese\n" "Language: pt_PT\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Cor invalida." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tipo de arquivo %(type)s não suportado" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variável inválida detetada." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "Não foi possível analisar o URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ro_RO/LC_MESSAGES/django.po b/src/locale/ro_RO/LC_MESSAGES/django.po index 5d3250a6e..f23c94892 100644 --- a/src/locale/ro_RO/LC_MESSAGES/django.po +++ b/src/locale/ro_RO/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Romanian\n" "Language: ro_RO\n" @@ -626,7 +626,7 @@ msgstr "" #: documents/models.py:692 msgid "Empty Trash" -msgstr "" +msgstr "Golire gunoi" #: documents/models.py:693 msgid "Check Workflows" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "rulări flux de lucru" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Culoare invalidă." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Tip de fișier %(type)s nesuportat" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Id-ul câmpului personalizat trebuie să fie un număr întreg: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Câmp personalizat cu id %(id)s nu există" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Câmpurile personalizate trebuie să fie o listă de numere întregi sau un obiect mapping ids la valori." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Unele câmpuri personalizate nu există sau au fost specificate de două ori." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Variabilă nevalidă detectată." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "Schema URI '{parts.scheme}' nu este permisă. Schemele permise: {', '.jo msgid "Unable to parse URI {value}" msgstr "Nu se poate analiza URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/ru_RU/LC_MESSAGES/django.po b/src/locale/ru_RU/LC_MESSAGES/django.po index 33ce65898..277cc5382 100644 --- a/src/locale/ru_RU/LC_MESSAGES/django.po +++ b/src/locale/ru_RU/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Russian\n" "Language: ru_RU\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "запуски рабочего процесса" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Неверный цвет." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Тип файла %(type)s не поддерживается" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Обнаружена неверная переменная." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "Недопустимая схема URI '{parts.scheme}'. Разреше msgid "Unable to parse URI {value}" msgstr "Невозможно распознать URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/sk_SK/LC_MESSAGES/django.po b/src/locale/sk_SK/LC_MESSAGES/django.po index 0a2409833..316d6c332 100644 --- a/src/locale/sk_SK/LC_MESSAGES/django.po +++ b/src/locale/sk_SK/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Slovak\n" "Language: sk_SK\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "spustenia pracovných postupov" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Neplatná farba." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Typ súboru %(type)s nie je podporovaný" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Zistená neplatná premenná." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/sl_SI/LC_MESSAGES/django.po b/src/locale/sl_SI/LC_MESSAGES/django.po index 93e082904..7b80328b2 100644 --- a/src/locale/sl_SI/LC_MESSAGES/django.po +++ b/src/locale/sl_SI/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Slovenian\n" "Language: sl_SI\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "poteka dela" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Nezadostna dovoljenja." @@ -1348,38 +1348,38 @@ msgstr "Nezadostna dovoljenja." msgid "Invalid color." msgstr "Napačna barva." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s ni podprta" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "ID polja po meri mora biti celo število: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Polje po meri z ID-jem %(id)s ne obstaja" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Polja po meri morajo biti seznam celih števil ali objekt, ki preslika ID-je v vrednosti." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Nekatera polja po meri ne obstajajo ali pa so bila navedena dvakrat." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Zaznani neveljavni znaki." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Podvojeni identifikatorji dokumentov niso dovoljeni." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumentov ni bilo mogoče najti: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Shema URI '{parts.scheme}' ni dovoljena. Dovoljene sheme: {', '.join(all msgid "Unable to parse URI {value}" msgstr "Ni mogoče razčleniti URI-ja {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Neveljaven more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Neveljavna konfiguracija umetne inteligence." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "Časovna omejitev zahteve za umetno inteligenco je potekla." -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Navedite samo eno od naslednjih vrednosti: text, title_search, query ali more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nezadostna dovoljenja za skupno rabo dokumenta %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket se že obdeluje." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Paket povezav za deljenje je še vedno v pripravi. Poskusite znova pozneje." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Paket povezav za deljenje ni na voljo." diff --git a/src/locale/sq_AL/LC_MESSAGES/django.po b/src/locale/sq_AL/LC_MESSAGES/django.po index bd18caa47..c434a7bda 100644 --- a/src/locale/sq_AL/LC_MESSAGES/django.po +++ b/src/locale/sq_AL/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Albanian\n" "Language: sq_AL\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "[SQ] workflow runs" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "[SQ] Insufficient permissions." @@ -1348,38 +1348,38 @@ msgstr "[SQ] Insufficient permissions." msgid "Invalid color." msgstr "Invalid color." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "[SQ] File type %(type)s not supported" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Custom field id must be an integer: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Custom field with id %(id)s does not exist" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Custom fields must be a list of integers or an object mapping ids to values." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "[SQ] Some custom fields don't exist or were specified twice." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Invalid variable detected." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "[SQ] Duplicate document identifiers are not allowed." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Documents not found: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "[SQ] URI scheme '{parts.scheme}' is not allowed. Allowed schemes: {', '. msgid "Unable to parse URI {value}" msgstr "[SQ] Unable to parse URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Invalid more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Invalid AI configuration." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Specify only one of text, title_search, query, or more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "[SQ] Insufficient permissions to share document %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "[SQ] Bundle is already being processed." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "[SQ] The share link bundle is still being prepared. Please try again later." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "[SQ] The share link bundle is unavailable." diff --git a/src/locale/sr_CS/LC_MESSAGES/django.po b/src/locale/sr_CS/LC_MESSAGES/django.po index 7a5ee37cb..3323f7ea1 100644 --- a/src/locale/sr_CS/LC_MESSAGES/django.po +++ b/src/locale/sr_CS/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Serbian (Latin)\n" "Language: sr_CS\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "pokretanje tokova rada" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Nedovoljne dozvole." @@ -1348,38 +1348,38 @@ msgstr "Nedovoljne dozvole." msgid "Invalid color." msgstr "Nevažeća boja." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Vrsta datoteke %(type)s nije podržana" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "ID prilagođenog polja mora biti ceo broj: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Prilagođeno polje sa ID-em %(id)s ne postoji" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Prilagođena polja moraju biti lista celih brojeva ili objekat koji mapira identifikatore na vrednosti." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Neka prilagođena polja ne postoje ili su navedena dva puta." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Otkrivena je nevažeća promenljiva." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Duplirani identifikatori dokumenata nisu dozvoljeni." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumenti nisu pronađeni: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Šema URI-ja '{parts.scheme}' nije dozvoljena. Dozvoljene šeme {', '.jo msgid "Unable to parse URI {value}" msgstr "Nije moguće analizirati URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Nevažeći more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Nevažeća konfiguracija veštačke inteligencije." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "Navedite samo jedno od sledećeg: text, title_search, query ili more_like_id." -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Nedovoljne dozvole za deljenje dokumenta %(id)s." -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Paket se već obrađuje." -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Paket linkova za deljenje se još uvek priprema. Molimo pokušajte ponovo kasnije." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Paket linkova za deljenje nije dostupan." diff --git a/src/locale/sv_SE/LC_MESSAGES/django.po b/src/locale/sv_SE/LC_MESSAGES/django.po index de1ce9a24..9cf0a348d 100644 --- a/src/locale/sv_SE/LC_MESSAGES/django.po +++ b/src/locale/sv_SE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Swedish\n" "Language: sv_SE\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "arbetsflöde körs" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Otillräckliga behörigheter." @@ -1348,38 +1348,38 @@ msgstr "Otillräckliga behörigheter." msgid "Invalid color." msgstr "Ogiltig färg." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Filtypen %(type)s stöds inte" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "Anpassat fält-id måste vara ett heltal: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Vissa anpassade fält finns inte eller har angetts två gånger." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Ogiltig variabel upptäckt." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Dubbletter av dokumentidentifierare är inte tillåtna." -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Dokumenten hittades inte: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "Ogiltig more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "Ogiltig AI-konfiguration." -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/th_TH/LC_MESSAGES/django.po b/src/locale/th_TH/LC_MESSAGES/django.po index 8216507af..6831e4a81 100644 --- a/src/locale/th_TH/LC_MESSAGES/django.po +++ b/src/locale/th_TH/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Thai\n" "Language: th_TH\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "สีไม่ถูกต้อง" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "ไม่รองรับไฟล์ประเภท %(type)s" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "ตรวจพบตัวแปรไม่ถูกต้อง" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1634,36 +1634,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/tr_TR/LC_MESSAGES/django.po b/src/locale/tr_TR/LC_MESSAGES/django.po index bdc0495da..f5c4c67a1 100644 --- a/src/locale/tr_TR/LC_MESSAGES/django.po +++ b/src/locale/tr_TR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "iş akışı çalıştırma" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Geçersiz renk." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Dosya türü %(type)s desteklenmiyor" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "%(id)s özel alan numarası tam sayı olmalıdır" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "%(id)s numaralı özel alan mevcut değil" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Özel alanlar bir tam sayı olarak veya bir nesne haritası numaraları olmalıdır." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Bazı õzel alan numaraları mevcut değil yada iki kez tanımlanmıș." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Geçersiz değişken algılandı." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "URI şeması ‘{parts.scheme}’ izin verilmez. İzin verilen şemalar: msgid "Unable to parse URI {value}" msgstr "URI {value} işlenemiyor" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/uk_UA/LC_MESSAGES/django.po b/src/locale/uk_UA/LC_MESSAGES/django.po index dc7187dfa..44a85f545 100644 --- a/src/locale/uk_UA/LC_MESSAGES/django.po +++ b/src/locale/uk_UA/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "Неправильний колір." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Тип файлу %(type)s не підтримується" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Виявлено неправильну змінну." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "" msgid "Unable to parse URI {value}" msgstr "" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/locale/vi_VN/LC_MESSAGES/django.po b/src/locale/vi_VN/LC_MESSAGES/django.po index b90710588..d3afd2768 100644 --- a/src/locale/vi_VN/LC_MESSAGES/django.po +++ b/src/locale/vi_VN/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Vietnamese\n" "Language: vi_VN\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "các lần chạy quy trình" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "Không có đủ quyền." @@ -1348,38 +1348,38 @@ msgstr "Không có đủ quyền." msgid "Invalid color." msgstr "Màu không hợp lệ." -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "Loại tập tin %(type)s không được hỗ trợ" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "ID trường tùy chỉnh phải là số nguyên: %(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "Trường tùy chỉnh với ID %(id)s không tồn tại" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "Trường tùy chỉnh phải là danh sách số nguyên hoặc đối tượng ánh xạ ID sang giá trị." -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "Một số trường tùy chỉnh không tồn tại hoặc được chỉ định hai lần." -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "Đã phát hiện biến số không hợp lệ." -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "Không cho phép các định danh tài liệu trùng lặp" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "Không tìm thấy tài liệu: %(ids)s" @@ -1635,36 +1635,36 @@ msgstr "Giao thức URI '{parts.scheme}' không được phép. Các giao thức msgid "Unable to parse URI {value}" msgstr "Không thể phân tích URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "Không đủ quyền để chia sẻ tài liệu %(id)s" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "Gói đang được xử lý" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "Liên kết chia sẻ gói vẫn đang được chuẩn bị. Vui lòng thử lại sau." -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "Không tồn tại liên kết chia sẻ gói" diff --git a/src/locale/zh_CN/LC_MESSAGES/django.po b/src/locale/zh_CN/LC_MESSAGES/django.po index fc1c91cc3..d8b6755c6 100644 --- a/src/locale/zh_CN/LC_MESSAGES/django.po +++ b/src/locale/zh_CN/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Chinese Simplified\n" "Language: zh_CN\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "工作流运行" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "权限不足。" @@ -1348,38 +1348,38 @@ msgstr "权限不足。" msgid "Invalid color." msgstr "无效的颜色" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "不支持文件类型 %(type)s" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "自定义字段 id 必须是数字:%(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "自定义字段 id %(id)s 不存在" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "自定义字段必须为整数列表,或是一个将ID映射到值的对象。" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "部分自定义字段不存在或重复指定。" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "检测到无效变量。" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "不允许重复文档标识符。" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "未找到文档:%(ids)s" @@ -1635,36 +1635,36 @@ msgstr "URI 格式 '{parts.scheme}' 不支持。支持的格式有:{', '.join( msgid "Unable to parse URI {value}" msgstr "无法解析 URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "无效的more_like_id" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "无效的 AI 配置。" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "AI 后端请求超时。" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "只能指定 text、title_search、query 或 more_like_id 中的一项。" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "权限不足以分享文件:%(id)s。" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "捆绑包已在处理中。" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "分享链接包仍在准备中,请稍后再试。" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "分享链接包不可用。" diff --git a/src/locale/zh_TW/LC_MESSAGES/django.po b/src/locale/zh_TW/LC_MESSAGES/django.po index 40fbbf94e..3694ea9b4 100644 --- a/src/locale/zh_TW/LC_MESSAGES/django.po +++ b/src/locale/zh_TW/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: paperless-ngx\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-27 19:34+0000\n" -"PO-Revision-Date: 2026-07-27 19:35\n" +"POT-Creation-Date: 2026-07-31 16:14+0000\n" +"PO-Revision-Date: 2026-07-31 16:15\n" "Last-Translator: \n" "Language-Team: Chinese Traditional\n" "Language: zh_TW\n" @@ -1339,7 +1339,7 @@ msgid "workflow runs" msgstr "執行工作流程" #: documents/serialisers.py:522 documents/serialisers.py:874 -#: documents/serialisers.py:2763 documents/views.py:299 documents/views.py:2553 +#: documents/serialisers.py:2776 documents/views.py:299 documents/views.py:2558 #: paperless_mail/serialisers.py:155 msgid "Insufficient permissions." msgstr "" @@ -1348,38 +1348,38 @@ msgstr "" msgid "Invalid color." msgstr "無效的顏色。" -#: documents/serialisers.py:2235 +#: documents/serialisers.py:2248 #, python-format msgid "File type %(type)s not supported" msgstr "不支援檔案類型 %(type)s" -#: documents/serialisers.py:2279 +#: documents/serialisers.py:2292 #, python-format msgid "Custom field id must be an integer: %(id)s" msgstr "自定欄位 ID 必須是整數:%(id)s" -#: documents/serialisers.py:2286 +#: documents/serialisers.py:2299 #, python-format msgid "Custom field with id %(id)s does not exist" msgstr "自定欄位 ID %(id)s 不存在" -#: documents/serialisers.py:2303 documents/serialisers.py:2313 +#: documents/serialisers.py:2316 documents/serialisers.py:2326 msgid "Custom fields must be a list of integers or an object mapping ids to values." msgstr "自定欄位必須為整數列表,或是將 ID 對應到數值的物件。" -#: documents/serialisers.py:2308 +#: documents/serialisers.py:2321 msgid "Some custom fields don't exist or were specified twice." msgstr "部分自定欄位不存在或重復指定。" -#: documents/serialisers.py:2455 +#: documents/serialisers.py:2468 msgid "Invalid variable detected." msgstr "偵測到無效的變數。" -#: documents/serialisers.py:2819 +#: documents/serialisers.py:2832 msgid "Duplicate document identifiers are not allowed." msgstr "" -#: documents/serialisers.py:2849 documents/views.py:4512 +#: documents/serialisers.py:2862 documents/views.py:4517 #, python-format msgid "Documents not found: %(ids)s" msgstr "" @@ -1635,36 +1635,36 @@ msgstr "URI 協定「{parts.scheme}」不被允許。允許的協定有:{', '. msgid "Unable to parse URI {value}" msgstr "無法解析 URI {value}" -#: documents/views.py:292 documents/views.py:2550 +#: documents/views.py:292 documents/views.py:2555 msgid "Invalid more_like_id" msgstr "" -#: documents/views.py:1562 +#: documents/views.py:1567 msgid "Invalid AI configuration." msgstr "" -#: documents/views.py:1571 +#: documents/views.py:1576 msgid "AI backend request timed out." msgstr "" -#: documents/views.py:2375 documents/views.py:2696 +#: documents/views.py:2380 documents/views.py:2701 msgid "Specify only one of text, title_search, query, or more_like_id." msgstr "" -#: documents/views.py:4524 +#: documents/views.py:4529 #, python-format msgid "Insufficient permissions to share document %(id)s." msgstr "" -#: documents/views.py:4570 +#: documents/views.py:4575 msgid "Bundle is already being processed." msgstr "" -#: documents/views.py:4631 +#: documents/views.py:4636 msgid "The share link bundle is still being prepared. Please try again later." msgstr "" -#: documents/views.py:4641 +#: documents/views.py:4646 msgid "The share link bundle is unavailable." msgstr "" diff --git a/src/paperless/parsers/tesseract.py b/src/paperless/parsers/tesseract.py index 78ce4c5c4..f3ebf9925 100644 --- a/src/paperless/parsers/tesseract.py +++ b/src/paperless/parsers/tesseract.py @@ -3,7 +3,6 @@ from __future__ import annotations import importlib.resources import logging import os -import re import shutil import tempfile from pathlib import Path @@ -25,9 +24,9 @@ from paperless.config import OcrConfig from paperless.models import CleanChoices from paperless.models import ModeChoices from paperless.models import OutputTypeChoices -from paperless.parsers.utils import PDF_TEXT_MIN_LENGTH from paperless.parsers.utils import extract_pdf_text -from paperless.parsers.utils import is_tagged_pdf +from paperless.parsers.utils import is_born_digital_text +from paperless.parsers.utils import post_process_text from paperless.parsers.utils import read_file_handle_unicode_errors from paperless.version import __full_version_str__ @@ -510,10 +509,10 @@ class RasterisedDocumentParser: if mime_type == "application/pdf": text_original = self.extract_text(None, document_path) - has_text = text_original is not None and len(text_original) > 0 - original_has_text = has_text and ( - is_tagged_pdf(document_path, log=self.log) - or len(text_original) > PDF_TEXT_MIN_LENGTH + original_has_text = is_born_digital_text( + text_original, + document_path, + log=self.log, ) else: text_original = None @@ -658,17 +657,3 @@ class RasterisedDocumentParser: f"No text was found in {document_path}, the content will be empty.", ) self.text = "" - - -def post_process_text(text: str | None) -> str | None: - if not text: - return None - - collapsed_spaces = re.sub(r"([^\S\r\n]+)", " ", text) - no_leading_whitespace = re.sub(r"([\n\r]+)([^\S\n\r]+)", "\\1", collapsed_spaces) - no_trailing_whitespace = re.sub(r"([^\S\n\r]+)$", "", no_leading_whitespace) - - # TODO: this needs a rework - # replace \0 prevents issues with saving to postgres. - # text may contain \0 when this character is present in PDF files. - return no_trailing_whitespace.strip().replace("\0", " ") diff --git a/src/paperless/parsers/utils.py b/src/paperless/parsers/utils.py index 0257ab736..9fe1d4908 100644 --- a/src/paperless/parsers/utils.py +++ b/src/paperless/parsers/utils.py @@ -111,6 +111,88 @@ def extract_pdf_text( return None +def post_process_text(text: str | None) -> str | None: + """Normalize extracted PDF/OCR text: collapse whitespace, strip padding. + + Returns ``None`` for ``None`` or whitespace-only input, so callers can + treat "no text" and "only layout padding" the same way. + """ + if not text: + return None + + collapsed_spaces = re.sub(r"([^\S\r\n]+)", " ", text) + no_leading_whitespace = re.sub(r"([\n\r]+)([^\S\n\r]+)", "\\1", collapsed_spaces) + no_trailing_whitespace = re.sub(r"([^\S\n\r]+)$", "", no_leading_whitespace) + + # replace \0 prevents issues with saving to postgres. + # text may contain \0 when this character is present in PDF files. + result = no_trailing_whitespace.strip().replace("\0", " ") + return result or None + + +def is_born_digital_text( + text: str | None, + path: Path, + log: logging.Logger | None = None, +) -> bool: + """Decide whether already-extracted, normalized PDF text counts as born-digital. + + This is the single source of truth for "does this PDF already have real + text", used both to decide whether to produce an archive file and to + decide whether OCR can be skipped. Both decisions must agree, or a + tagged-but-textless PDF can end up with no archive AND a forced OCR pass + (see GH #13387): raw ``pdftotext -layout`` output can be non-empty + (whitespace/form-feed padding) even when there is no real content, so + *text* must already be normalized via :func:`post_process_text`, not the + raw extraction. + + Parameters + ---------- + text: + The normalized extracted text (or ``None``) to evaluate. + path: + Absolute path to the PDF file, used for the tagged-PDF check. + log: + Logger for warnings. Falls back to the module-level logger when omitted. + + Returns + ------- + bool + Whether the PDF counts as born-digital (has real text, and is either + tagged or exceeds ``PDF_TEXT_MIN_LENGTH``). + """ + if not text: + return False + return is_tagged_pdf(path, log=log) or len(text) > PDF_TEXT_MIN_LENGTH + + +def pdf_born_digital_text( + path: Path, + log: logging.Logger | None = None, +) -> tuple[str | None, bool]: + """Extract a PDF's text and decide whether it should be treated as born-digital. + + Convenience wrapper around :func:`is_born_digital_text` for callers that + don't already have the PDF's text extracted (e.g. the archive-generation + decision, which runs before any parser has touched the file). + + Parameters + ---------- + path: + Absolute path to the PDF file. + log: + Logger for warnings. Falls back to the module-level logger when omitted. + + Returns + ------- + tuple[str | None, bool] + The normalized extracted text (or ``None``), and whether the PDF + counts as born-digital. + """ + text = post_process_text(extract_pdf_text(path, log=log)) + return text, is_born_digital_text(text, path, log=log) + + def read_file_handle_unicode_errors( filepath: Path, log: logging.Logger | None = None, diff --git a/src/paperless/tests/conftest.py b/src/paperless/tests/conftest.py index b016191c4..c43659506 100644 --- a/src/paperless/tests/conftest.py +++ b/src/paperless/tests/conftest.py @@ -36,6 +36,23 @@ def samples_dir() -> Path: return (Path(__file__).parent / "samples").resolve() +@pytest.fixture(scope="session") +def tagged_no_text_pdf_file(samples_dir: Path) -> Path: + """Path to a tagged PDF whose only "text" is pdftotext layout padding. + + Reproduces GH #13387: ``/MarkInfo /Marked true`` is set, but the only + extractable content is a form-feed byte, not real text. Lives here + rather than in parsers/conftest.py so both parser tests and + paperless/tests/test_parser_utils.py can use it. + + Returns + ------- + Path + Absolute path to ``tesseract/tagged-but-no-text.pdf``. + """ + return samples_dir / "tesseract" / "tagged-but-no-text.pdf" + + @pytest.fixture(autouse=True) def clean_registry() -> Generator[None, None, None]: """Reset the parser registry before and after every test. diff --git a/src/paperless/tests/parsers/test_tesseract_parser.py b/src/paperless/tests/parsers/test_tesseract_parser.py index e56992d0b..f25efccc7 100644 --- a/src/paperless/tests/parsers/test_tesseract_parser.py +++ b/src/paperless/tests/parsers/test_tesseract_parser.py @@ -21,7 +21,7 @@ from documents.parsers import run_convert from paperless.models import ModeChoices from paperless.parsers import ParserProtocol from paperless.parsers.tesseract import RasterisedDocumentParser -from paperless.parsers.tesseract import post_process_text +from paperless.parsers.utils import is_tagged_pdf if TYPE_CHECKING: from pathlib import Path @@ -151,36 +151,6 @@ class TestRasterisedDocumentParserLifecycle: assert tempdir is not None and not tempdir.exists() -# --------------------------------------------------------------------------- -# post_process_text -# --------------------------------------------------------------------------- - - -class TestPostProcessText: - @pytest.mark.parametrize( - ("source", "expected"), - [ - pytest.param( - "simple string", - "simple string", - id="collapse-spaces", - ), - pytest.param( - "simple newline\n testing string", - "simple newline\ntesting string", - id="preserve-newline", - ), - pytest.param( - "utf-8 строка с пробелами в конце ", # noqa: RUF001 - "utf-8 строка с пробелами в конце", # noqa: RUF001 - id="utf8-trailing-spaces", - ), - ], - ) - def test_post_process_text(self, source: str, expected: str) -> None: - assert post_process_text(source) == expected - - # --------------------------------------------------------------------------- # Page count # --------------------------------------------------------------------------- @@ -910,25 +880,25 @@ class TestSkipArchive: self, mocker: MockerFixture, tesseract_parser: RasterisedDocumentParser, - tesseract_samples_dir: Path, + tagged_no_text_pdf_file: Path, ) -> None: """ GIVEN: - - A PDF that reports itself as tagged (/MarkInfo /Marked true) but - has no actual extractable text (some scanner firmware produces - this — see GitHub issue #13349) + - A real PDF that reports itself as tagged (/MarkInfo /Marked + true) but whose only pdftotext output is layout padding (a + lone form-feed byte), not real text (see GitHub issue #13387, + originally reported against #13349's tagged-PDF handling) - Mode: auto, produce_archive=False WHEN: - Document is parsed THEN: - The tag alone is not trusted as "has text"; OCRmyPDF still runs """ + assert is_tagged_pdf(tagged_no_text_pdf_file) is True tesseract_parser.settings.mode = ModeChoices.AUTO - mocker.patch("paperless.parsers.tesseract.is_tagged_pdf", return_value=True) - mocker.patch.object(tesseract_parser, "extract_text", return_value=None) mock_ocr = mocker.patch("ocrmypdf.ocr") tesseract_parser.parse( - tesseract_samples_dir / "multi-page-images.pdf", + tagged_no_text_pdf_file, "application/pdf", produce_archive=False, ) diff --git a/src/paperless/tests/samples/tesseract/tagged-but-no-text.pdf b/src/paperless/tests/samples/tesseract/tagged-but-no-text.pdf new file mode 100644 index 000000000..5a652345a Binary files /dev/null and b/src/paperless/tests/samples/tesseract/tagged-but-no-text.pdf differ diff --git a/src/paperless/tests/test_parser_utils.py b/src/paperless/tests/test_parser_utils.py index c6bb3e34a..f0a63ea44 100644 --- a/src/paperless/tests/test_parser_utils.py +++ b/src/paperless/tests/test_parser_utils.py @@ -4,10 +4,18 @@ from __future__ import annotations import codecs from pathlib import Path +from typing import TYPE_CHECKING + +import pytest from paperless.parsers.utils import is_tagged_pdf +from paperless.parsers.utils import pdf_born_digital_text +from paperless.parsers.utils import post_process_text from paperless.parsers.utils import read_file_handle_unicode_errors +if TYPE_CHECKING: + from pytest_mock import MockerFixture + SAMPLES = Path(__file__).parent / "samples" / "tesseract" @@ -60,3 +68,105 @@ class TestIsTaggedPdf: bad = tmp_path / "bad.pdf" bad.write_bytes(b"not a pdf") assert is_tagged_pdf(bad) is False + + +class TestPostProcessText: + @pytest.mark.parametrize( + ("source", "expected"), + [ + pytest.param( + "simple string", + "simple string", + id="collapse-spaces", + ), + pytest.param( + "simple newline\n testing string", + "simple newline\ntesting string", + id="preserve-newline", + ), + pytest.param( + "utf-8 строка с пробелами в конце ", # noqa: RUF001 + "utf-8 строка с пробелами в конце", # noqa: RUF001 + id="utf8-trailing-spaces", + ), + pytest.param(None, None, id="none-input"), + pytest.param("", None, id="empty-string"), + pytest.param(" \n\x0c \n ", None, id="whitespace-and-formfeed-only"), + ], + ) + def test_post_process_text( + self, + source: str | None, + expected: str | None, + ) -> None: + assert post_process_text(source) == expected + + +class TestPdfBornDigitalText: + """Regression coverage for GH #13387. + + should_produce_archive() and RasterisedDocumentParser.parse() must agree + on whether a PDF has real text, so both go through this one function. + """ + + @pytest.mark.parametrize( + ("extracted", "tagged", "expected_text", "expected_born_digital"), + [ + pytest.param("tiny", True, "tiny", True, id="tagged-with-real-text"), + pytest.param("tiny", False, "tiny", False, id="untagged-below-min-length"), + pytest.param( + "x" * 51, + False, + "x" * 51, + True, + id="untagged-above-min-length", + ), + pytest.param(None, True, None, False, id="tagged-but-no-text"), + ], + ) + def test_born_digital_decision( + self, + mocker: MockerFixture, + tmp_path: Path, + extracted: str | None, + tagged: bool, # noqa: FBT001 + expected_text: str | None, + expected_born_digital: bool, # noqa: FBT001 + ) -> None: + """ + GIVEN: + - A PDF whose pdftotext output and /MarkInfo tag status vary + WHEN: + - pdf_born_digital_text() is called + THEN: + - The normalized text and born-digital verdict match; the tag + alone never counts as "has text" + """ + mocker.patch( + "paperless.parsers.utils.extract_pdf_text", + return_value=extracted, + ) + mocker.patch("paperless.parsers.utils.is_tagged_pdf", return_value=tagged) + text, born_digital = pdf_born_digital_text(tmp_path / "doc.pdf") + assert text == expected_text + assert born_digital is expected_born_digital + + def test_tagged_but_textless_pdf_is_not_born_digital( + self, + tagged_no_text_pdf_file: Path, + ) -> None: + """ + GIVEN: + - A real PDF that is tagged (/MarkInfo /Marked true) but whose + only "text" is layout padding (a stray form-feed byte) + WHEN: + - pdf_born_digital_text() is called with no mocking + THEN: + - The normalized text is None and the PDF is not treated as + born-digital. The raw, unnormalized pdftotext output is + non-empty for this file, which is exactly what caused the + archive decision to disagree with the OCR decision in #13387. + """ + text, born_digital = pdf_born_digital_text(tagged_no_text_pdf_file) + assert text is None + assert born_digital is False diff --git a/src/paperless_ai/ai_classifier.py b/src/paperless_ai/ai_classifier.py index 41bf8e903..13a145709 100644 --- a/src/paperless_ai/ai_classifier.py +++ b/src/paperless_ai/ai_classifier.py @@ -96,19 +96,26 @@ def get_context_for_document( user: User | None = None, max_docs: int = 5, ) -> str: - visible_documents = ( - get_objects_for_user_owner_aware( - user, - "view_document", - Document, - ) - if user - else None - ) + # None means "no restriction" to query_similar_documents. A superuser + # (like no user at all) can see every document, so skip materializing + # every visible pk into a Python list and passing it through as a SQL + # IN filter: for a large library that is a wasted quadratic scan in the + # vector store at best, and past ~32,763 documents a hard + # sqlite3.OperationalError (SQLite's bound-parameter limit) at worst. + # get_objects_for_user_owner_aware() would return every Document for a + # superuser anyway (guardian's own with_superuser shortcut), so this + # changes nothing about which documents are considered -- only how we + # get there. visible_document_ids = ( - list(visible_documents.values_list("pk", flat=True)) - if visible_documents is not None - else None + None + if user is None or user.is_superuser + else list( + get_objects_for_user_owner_aware( + user, + "view_document", + Document, + ).values_list("pk", flat=True), + ) ) similar_docs = query_similar_documents( document=doc, diff --git a/src/paperless_ai/base_model.py b/src/paperless_ai/base_model.py index 61f93b467..3d3820dfc 100644 --- a/src/paperless_ai/base_model.py +++ b/src/paperless_ai/base_model.py @@ -1,12 +1,13 @@ from pydantic import BaseModel +from pydantic import Field class DocumentClassifierSchema(BaseModel): """Schema for document classification suggestions.""" title: str - tags: list[str] - correspondents: list[str] - document_types: list[str] - storage_paths: list[str] - dates: list[str] + tags: list[str] = Field(default_factory=list) + correspondents: list[str] = Field(default_factory=list) + document_types: list[str] = Field(default_factory=list) + storage_paths: list[str] = Field(default_factory=list) + dates: list[str] = Field(default_factory=list) diff --git a/src/paperless_ai/indexing.py b/src/paperless_ai/indexing.py index 93b850cbf..5f90fa051 100644 --- a/src/paperless_ai/indexing.py +++ b/src/paperless_ai/indexing.py @@ -1,3 +1,4 @@ +import enum import logging from collections.abc import Iterable from contextlib import contextmanager @@ -14,6 +15,7 @@ from filelock import Timeout from documents.models import Document from documents.models import PaperlessTask from documents.utils import IterWrapper +from documents.utils import QuerySetStream from documents.utils import identity from paperless.config import AIConfig from paperless_ai.db import db_connection_released @@ -32,6 +34,11 @@ logger = logging.getLogger("paperless_ai.indexing") RAG_NUM_OUTPUT = 512 RAG_CHUNK_OVERLAP = 200 +# update_llm_index(): row count per .iterator() batch when streaming +# documents for a rebuild/update via QuerySetStream, matching +# _DocumentViewerStream's chunk size in documents/search/_backend.py. +_INDEX_STREAM_CHUNK_SIZE = 1000 + def queue_llm_index_update_if_needed(*, rebuild: bool, reason: str) -> bool: # NOTE: The check-then-enqueue sequence below is non-atomic (TOCTOU): two @@ -144,6 +151,24 @@ def _exclude_readers(): lock.close() +def _with_exclusive_access(operation: str, fn): + """Run ``fn()`` with exclusive index access (see ``_exclude_readers()``), + for compaction/migration file swaps that must not run while readers are + active. Returns ``fn()``'s result, or None (after logging) if active + readers do not drain within ``LLM_INDEX_COMPACTION_LOCK_TIMEOUT`` -- + callers skip the operation this run; it retries next time. + """ + try: + with _exclude_readers(): + return fn() + except Timeout: + logger.info( + "Skipping LLM index %s: index readers are active; will retry next run.", + operation, + ) + return None + + @contextmanager def write_store(embed_model_name: str | None = None): """Acquire the write lock and yield the vector store. @@ -168,6 +193,52 @@ def write_store(embed_model_name: str | None = None): yield store +class MigrationCheckResult(enum.Enum): + """Outcome of _check_and_run_migrations(). + + CURRENT: no migration was pending, or a pending structural migration + was applied successfully -- safe to write. + + REEMBED_REQUIRED: a pending migration needs fresh embeddings, which is + never triggered automatically -- the caller must force a rebuild. + + DEFERRED: a migration was pending but could not run because active + index readers did not drain within LLM_INDEX_COMPACTION_LOCK_TIMEOUT -- + the store is still on its old schema. Callers must NOT proceed to + write: collapsing this into the same falsy value as CURRENT (as a + plain bool return once did) would let a write proceed against an + unmigrated schema. + """ + + CURRENT = "current" + REEMBED_REQUIRED = "reembed_required" + DEFERRED = "deferred" + + +def _check_and_run_migrations( + store: "PaperlessSqliteVecVectorStore", +) -> MigrationCheckResult: + """Run any pending structural migrations, reporting the outcome as a + tri-state result. Safe to call before any write, including + delete()/upsert_document(): has_pending_migration() (see its docstring) + keeps this a no-op, with no exclusive access taken, once the store is + current. + """ + if not store.has_pending_migration(): + return MigrationCheckResult.CURRENT + result = _with_exclusive_access( + "migration check", + store.check_and_run_migrations, + ) + if result is None: + return MigrationCheckResult.DEFERRED + return ( + MigrationCheckResult.REEMBED_REQUIRED + if result + else MigrationCheckResult.CURRENT + ) + + def _safe_related_name(document: Document, field: str) -> str | None: """ Returns the ``name`` of a related object (correspondent, document_type, @@ -301,7 +372,7 @@ def _document_id_filters(doc_ids): MetadataFilter( key="document_id", operator=FilterOperator.IN, - value=sorted(doc_ids), + value=list(doc_ids), ), ], ) @@ -339,20 +410,21 @@ def update_llm_index( happens, since a rebuild always covers the whole library regardless. """ with write_store() as store: - try: - with _exclude_readers(): - needs_reembed = store.check_and_run_migrations() - except Timeout: - logger.info( - "Skipping LLM index migration check: index readers are active; " - "will retry next run.", - ) - needs_reembed = False - if needs_reembed: + migration_result = _check_and_run_migrations(store) + if migration_result is MigrationCheckResult.REEMBED_REQUIRED: logger.warning( "LLM index migration requires re-embedding; forcing rebuild.", ) rebuild = True + elif migration_result is MigrationCheckResult.DEFERRED: + logger.info( + "Skipping LLM index update: migration check deferred while " + "index readers are active; will retry next run.", + ) + return ( + "Skipping LLM index update: migration check deferred; " + "will retry next run." + ) documents = Document.objects.select_related( "correspondent", "document_type", @@ -368,12 +440,11 @@ def update_llm_index( config = AIConfig() model_name = get_configured_model_name(config) - if not rebuild and llm_index_exists(): + if not rebuild: with read_store() as store: - config_mismatch = store.config_mismatch(model_name) - if config_mismatch: - logger.warning("Embedding model changed; forcing LLM index rebuild.") - rebuild = True + if store.table_exists() and store.config_mismatch(model_name): + logger.warning("Embedding model changed; forcing LLM index rebuild.") + rebuild = True if no_documents: logger.warning("No documents found to index.") @@ -385,7 +456,9 @@ def update_llm_index( if rebuild or not store.table_exists(): logger.info("Rebuilding LLM index.") store.drop_table() - for document in iter_wrapper(documents): + for document in iter_wrapper( + QuerySetStream(documents, chunk_size=_INDEX_STREAM_CHUNK_SIZE), + ): nodes = build_document_node(document, chunk_size=chunk_size) _embed_nodes(nodes, embed_model) store.add(nodes) @@ -398,7 +471,9 @@ def update_llm_index( ) existing = store.get_modified_times() changed = 0 - for document in iter_wrapper(scoped_documents): + for document in iter_wrapper( + QuerySetStream(scoped_documents, chunk_size=_INDEX_STREAM_CHUNK_SIZE), + ): doc_id = str(document.id) if existing.get(doc_id) == document.modified.isoformat(): continue @@ -412,14 +487,7 @@ def update_llm_index( else "No changes detected in LLM index." ) - try: - with _exclude_readers(): - store.compact() - except Timeout: - logger.info( - "Skipping LLM index compaction: index readers are active; " - "will retry next run.", - ) + _with_exclusive_access("compaction", store.compact) return msg @@ -434,25 +502,82 @@ def llm_index_add_or_update_document(document: Document): _embed_nodes(new_nodes, get_embedding_model(config)) with write_store(embed_model_name=get_configured_model_name(config)) as store: + migration_result = _check_and_run_migrations(store) + if migration_result is MigrationCheckResult.REEMBED_REQUIRED: + logger.warning( + "Skipping incremental LLM index update for document %s: the " + "index requires re-embedding first. Run 'document_llmindex " + "rebuild' to resolve.", + document.id, + ) + return + if migration_result is MigrationCheckResult.DEFERRED: + logger.info( + "Skipping incremental LLM index update for document %s: " + "migration check deferred while index readers are active; " + "will retry on the next write.", + document.id, + ) + return store.upsert_document(str(document.id), new_nodes) +def llm_index_migrate() -> None: + """Apply any pending LLM index schema migrations, with no reindex. + + Intended to run unconditionally on every startup (see the + init-llmindex-migrate container step and the bare-metal upgrade docs): + has_pending_migration() short-circuits to a metadata-only read once the + store is current, so a healthy install pays almost nothing here. Only + ever applies structural migrations -- a pending re-embed migration is + left for the explicit, deliberate rebuild path (``document_llmindex + update``/``rebuild``) to resolve, since re-embedding can be slow and, + for a metered embedding backend, cost money. + """ + if not AIConfig().llm_index_enabled: + return + with write_store() as store: + migration_result = _check_and_run_migrations(store) + if migration_result is MigrationCheckResult.REEMBED_REQUIRED: + logger.warning( + "LLM index requires re-embedding, which this automatic migration " + "check will not do on its own -- it can be slow and, for a " + "metered embedding backend, cost money. Run " + "'document_llmindex rebuild' manually when ready.", + ) + elif migration_result is MigrationCheckResult.DEFERRED: + logger.info( + "LLM index migration check deferred while index readers are " + "active; will retry next run.", + ) + + def llm_index_compact() -> None: """Compact the index immediately, rebuilding the table to reclaim space.""" with write_store() as store: - try: - with _exclude_readers(): - store.compact(force=True) - except Timeout: - logger.info( - "Skipping LLM index compaction: index readers are active; " - "will retry next run.", - ) + _with_exclusive_access("compaction", lambda: store.compact(force=True)) def llm_index_remove_document(document: Document): """Remove a document's chunks from the LLM index.""" with write_store() as store: + migration_result = _check_and_run_migrations(store) + if migration_result is MigrationCheckResult.REEMBED_REQUIRED: + logger.warning( + "Skipping removal of document %s from the LLM index: the " + "index requires re-embedding first. Run 'document_llmindex " + "rebuild' to resolve.", + document.id, + ) + return + if migration_result is MigrationCheckResult.DEFERRED: + logger.info( + "Skipping removal of document %s from the LLM index: " + "migration check deferred while index readers are active; " + "will retry on the next write.", + document.id, + ) + return store.delete(str(document.id)) diff --git a/src/paperless_ai/migrations/__init__.py b/src/paperless_ai/migrations/__init__.py new file mode 100644 index 000000000..af63f3400 --- /dev/null +++ b/src/paperless_ai/migrations/__init__.py @@ -0,0 +1,60 @@ +"""Schema migrations for the sqlite-vec vector store. + +Each migration lives in its own module here, named ``mNNNN_description.py`` +(e.g. ``m0001_v1_to_v2.py`` -- a leading digit isn't a valid Python +identifier, hence the ``m`` prefix, unlike Django's own numbered migrations, +which load via a dynamic ``importlib.import_module()`` call rather than a +static import statement), and registers itself into ``MIGRATIONS`` at import +time. ``vector_store.py`` imports those modules at the bottom of the file, +purely for that registration side effect, after ``PaperlessSqliteVecVectorStore`` +is fully defined -- migrations need it to implement ``apply()`` (see +``Migration`` below). + +To add a new migration: add a new ``mNNNN_description.py`` module here that +imports ``PaperlessSqliteVecVectorStore`` from ``paperless_ai.vector_store``, +defines its ``apply()``, and appends a ``Migration`` to ``MIGRATIONS``; then +import that module at the bottom of ``vector_store.py`` and bump +``SCHEMA_VERSION`` there. A migration must freeze its own historical DDL for +any side table its target version depends on (``DROP TABLE IF EXISTS`` + +its own literal ``CREATE TABLE``/``CREATE INDEX`` statements) rather than +delegating to any "current schema" helper -- see ``m0001_v1_to_v2.py`` for +why and the worked example. +""" + +import sqlite3 +from collections.abc import Callable +from dataclasses import dataclass +from dataclasses import field +from typing import Literal + + +@dataclass +class Migration: + """A schema migration for the sqlite-vec vector store. + + kind="structural": rows are copied into a new-schema file with no + re-embedding needed. Supply ``apply(src_conn, dst_conn, dim)``, which + must create every table its target schema needs in ``dst_conn`` and copy + ``src_conn``'s rows and relevant ``index_meta`` keys into it. + ``schema_version`` is written by the migration runner after ``apply`` + returns, not by ``apply`` itself. + + kind="re-embed": the new schema requires fresh embeddings. + ``check_and_run_migrations()`` returns True when it encounters one of + these so the caller can force a full rebuild (which recreates the table + at the current SCHEMA_VERSION). + """ + + from_version: int + to_version: int + kind: Literal["structural", "re-embed"] + description: str + apply: Callable[[sqlite3.Connection, sqlite3.Connection, int], None] | None = field( + default=None, + repr=False, + ) + + +# Registry of all schema migrations in order, populated by each migration +# module's import-time registration (see the module docstring above). +MIGRATIONS: list[Migration] = [] diff --git a/src/paperless_ai/migrations/m0001_v1_to_v2.py b/src/paperless_ai/migrations/m0001_v1_to_v2.py new file mode 100644 index 000000000..18409d5fc --- /dev/null +++ b/src/paperless_ai/migrations/m0001_v1_to_v2.py @@ -0,0 +1,118 @@ +import sqlite3 + +from paperless_ai.migrations import MIGRATIONS +from paperless_ai.migrations import Migration +from paperless_ai.tables import ChunkRow +from paperless_ai.tables import DocumentChunksTable +from paperless_ai.tables import DocumentMetaRow +from paperless_ai.tables import DocumentMetaTable +from paperless_ai.tables import IndexMetaTable +from paperless_ai.vector_store import BATCH_SIZE +from paperless_ai.vector_store import DEFAULT_TABLE_NAME + +# v1's vec0 shape has never changed since it first shipped and is the ONLY +# real upgrade path -- no store has ever existed at any intermediate +# version, so this migration goes straight from that shipped shape to the +# final v2 target in one pass. +_V1_SELECT = ( + "SELECT id, document_id, modified, node_content, embedding FROM " + + DEFAULT_TABLE_NAME +) + + +def _migrate_v1_to_v2( + src_conn: sqlite3.Connection, + dst_conn: sqlite3.Connection, + dim: int, +) -> None: + """v1 -> v2: document_id TEXT -> INTEGER, modified moves out of vec0 + into document_meta, document_chunks added for O(1) per-document delete. + + Freezes its own v2-shaped vec0/document_chunks/document_meta DDL inline, + rather than delegating to the gateway "create table" helpers or the + store's own vec0-table builder (all of which always reflect the + *current* schema): a later schema version changing any of these tables' + shape must not silently change what this migration produces for someone + upgrading straight from v1. + _open_connection() already created document_chunks/document_meta on + dst_conn (reflecting current HEAD) as a side effect of opening it for + this migration's rebuild -- DROP them first so this migration's own + frozen CREATE TABLE isn't a silent no-op against that. Safe here because + dst_conn is a freshly opened, empty rebuild file with nothing written + yet. + """ + dst_conn.execute( # nosemgrep: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query + "CREATE VIRTUAL TABLE " + + DEFAULT_TABLE_NAME + + " USING vec0(" + + "id TEXT PRIMARY KEY," + + " document_id INTEGER," + + " +node_content TEXT," + + " embedding float[" + + str(int(dim)) + + "] distance_metric=cosine" + + ")", + ) + dst_conn.execute("DROP TABLE IF EXISTS document_chunks") + dst_conn.execute( + "CREATE TABLE document_chunks " + "(chunk_id TEXT PRIMARY KEY, document_id INTEGER NOT NULL)", + ) + dst_conn.execute( + "CREATE INDEX idx_document_chunks_document_id ON document_chunks (document_id)", + ) + dst_conn.execute("DROP TABLE IF EXISTS document_meta") + dst_conn.execute( + "CREATE TABLE document_meta " + "(document_id INTEGER PRIMARY KEY, modified TEXT NOT NULL)", + ) + + IndexMetaTable.set_dim(dst_conn, dim) + embed_model = IndexMetaTable.get_embed_model(src_conn) + if embed_model is not None: + IndexMetaTable.set_embed_model(dst_conn, embed_model) + + dst_conn.execute("BEGIN IMMEDIATE") + src_cursor = src_conn.execute(_V1_SELECT) + live = 0 + while batch := src_cursor.fetchmany(BATCH_SIZE): + vec0_rows = [] + chunk_rows = [] + meta_by_document: dict[int, str] = {} + for r in batch: + document_id = int(r["document_id"]) + vec0_rows.append( + (r["id"], document_id, r["node_content"], bytes(r["embedding"])), + ) + chunk_rows.append(ChunkRow(r["id"], document_id)) + meta_by_document[document_id] = str(r["modified"] or "") + dst_conn.executemany( + "INSERT INTO " + + DEFAULT_TABLE_NAME + + " (id, document_id, node_content, embedding) VALUES (?, ?, ?, ?)", + vec0_rows, + ) + DocumentChunksTable.insert_many(dst_conn, chunk_rows) + DocumentMetaTable.upsert_many( + dst_conn, + (DocumentMetaRow(doc_id, mod) for doc_id, mod in meta_by_document.items()), + ) + live += len(batch) + # This migration only ever copies live rows (like compact()), so the + # cumulative counter resets to match -- the new file has no bloat yet. + IndexMetaTable.reset_total_inserts(dst_conn, live) + dst_conn.execute("COMMIT") + + +MIGRATIONS.append( + Migration( + from_version=1, + to_version=2, + kind="structural", + description=( + "document_id TEXT -> INTEGER; move modified into document_meta; " + "add document_chunks for O(1) per-document delete" + ), + apply=_migrate_v1_to_v2, + ), +) diff --git a/src/paperless_ai/tables.py b/src/paperless_ai/tables.py new file mode 100644 index 000000000..c8d6d838c --- /dev/null +++ b/src/paperless_ai/tables.py @@ -0,0 +1,245 @@ +"""Thin gateways over the plain relational side tables that sit alongside the +vec0 table. Each method takes the sqlite3.Connection to operate on +explicitly, rather than owning one -- the store swaps connections during +compact()/migration, and migrations always work across two connections +(src_conn, dst_conn) at once. + +PRECONDITION: Callers must set conn.row_factory = sqlite3.Row before passing a +connection to any of these gateways' read methods. The read methods across all +three classes (DocumentChunksTable.chunk_ids_for_document, IndexMetaTable._get, +DocumentMetaTable.all_modified_times, DocumentMetaTable.copy_all) use +row["column_name"] dictionary-style indexing, which requires sqlite3.Row as the +row factory -- without it, sqlite3.Row is not set, rows are returned as plain +tuples, and tuple indices must be integers, raising TypeError. +""" + +import sqlite3 +from collections.abc import Iterable +from typing import NamedTuple + + +class ChunkRow(NamedTuple): + chunk_id: str + document_id: int + + +class DocumentMetaRow(NamedTuple): + document_id: int + modified: str + + +class DocumentChunksTable: + """chunk_id -> document_id, indexed by document_id. Gives O(1) + per-document chunk lookup that vec0's own document_id metadata column + cannot (see PaperlessSqliteVecVectorStore._delete_chunks_by_document_id). + """ + + @staticmethod + def create(conn: sqlite3.Connection) -> None: + conn.execute( + "CREATE TABLE IF NOT EXISTS document_chunks " + "(chunk_id TEXT PRIMARY KEY, document_id INTEGER NOT NULL)", + ) + conn.execute( + "CREATE INDEX IF NOT EXISTS idx_document_chunks_document_id " + "ON document_chunks (document_id)", + ) + + @staticmethod + def insert_many(conn: sqlite3.Connection, rows: Iterable[ChunkRow]) -> None: + """rows must already be batch-bounded by the caller (e.g. vec0's own + fetchmany() loop) -- this never reads, so it can't itself introduce + an unbounded scan, but a whole-table iterable defeats the point.""" + conn.executemany( + "INSERT INTO document_chunks (chunk_id, document_id) VALUES (?, ?)", + rows, + ) + + @staticmethod + def chunk_ids_for_document( + conn: sqlite3.Connection, + document_id: int, + ) -> list[str]: + return [ + row["chunk_id"] + for row in conn.execute( + "SELECT chunk_id FROM document_chunks WHERE document_id = ?", + (document_id,), + ).fetchall() + ] + + @staticmethod + def delete_for_document(conn: sqlite3.Connection, document_id: int) -> None: + conn.execute( + "DELETE FROM document_chunks WHERE document_id = ?", + (document_id,), + ) + + @staticmethod + def delete_all(conn: sqlite3.Connection) -> None: + conn.execute("DELETE FROM document_chunks") + + @staticmethod + def count(conn: sqlite3.Connection) -> int: + """Cheap stand-in for vec0's own row count -- see compact().""" + return conn.execute("SELECT count(*) FROM document_chunks").fetchone()[0] + + +class DocumentMetaTable: + """document_id -> modified, one row per document. Lives outside vec0 + because vec0 only inlines TEXT metadata up to 12 bytes and `modified` + (an ISO timestamp) is always longer. + """ + + @staticmethod + def create(conn: sqlite3.Connection) -> None: + conn.execute( + "CREATE TABLE IF NOT EXISTS document_meta " + "(document_id INTEGER PRIMARY KEY, modified TEXT NOT NULL)", + ) + + @staticmethod + def upsert_many( + conn: sqlite3.Connection, + rows: Iterable[DocumentMetaRow], + ) -> None: + conn.executemany( + "INSERT INTO document_meta (document_id, modified) VALUES (?, ?) " + "ON CONFLICT(document_id) DO UPDATE SET modified = excluded.modified", + rows, + ) + + @staticmethod + def delete_for_document(conn: sqlite3.Connection, document_id: int) -> None: + conn.execute( + "DELETE FROM document_meta WHERE document_id = ?", + (document_id,), + ) + + @staticmethod + def delete_all(conn: sqlite3.Connection) -> None: + conn.execute("DELETE FROM document_meta") + + @staticmethod + def copy_all( + src_conn: sqlite3.Connection, + dst_conn: sqlite3.Connection, + batch_size: int, + ) -> None: + """Stream document_meta from src_conn into dst_conn in bounded + batches. The *only* sanctioned way to move this table across + connections (compact()/migrations) -- an unbounded fetchall here + would defeat the same OOM-avoidance the vec0 row copy already relies + on. batch_size has no default: forces the call site to think about + it (pass BATCH_SIZE).""" + cursor = src_conn.execute( + "SELECT document_id, modified FROM document_meta", + ) + while batch := cursor.fetchmany(batch_size): + DocumentMetaTable.upsert_many( + dst_conn, + (DocumentMetaRow(r["document_id"], r["modified"]) for r in batch), + ) + + @staticmethod + def all_modified_times(conn: sqlite3.Connection) -> dict[str, str]: + """Full document_id -> modified map, for get_modified_times()'s + public API only. One unbounded read by design (existing behavior). + Never use this for cross-connection copying; see copy_all().""" + return { + str(row["document_id"]): str(row["modified"] or "") + for row in conn.execute( + "SELECT document_id, modified FROM document_meta", + ) + } + + +class IndexMetaTable: + """Typed accessors over index_meta's key/value rows -- replaces + PaperlessSqliteVecVectorStore._meta_get_on/_meta_set_on, which returned + untyped str | None regardless of whether the key held an int (dim, + schema_version, total_inserts) or a string (embed_model). + """ + + @staticmethod + def create(conn: sqlite3.Connection) -> None: + conn.execute( + "CREATE TABLE IF NOT EXISTS index_meta (key TEXT PRIMARY KEY, value TEXT)", + ) + + @staticmethod + def _get(conn: sqlite3.Connection, key: str) -> str | None: + row = conn.execute( + "SELECT value FROM index_meta WHERE key = ?", + (key,), + ).fetchone() + return row["value"] if row else None + + @staticmethod + def _set(conn: sqlite3.Connection, key: str, value: str) -> None: + conn.execute( + "INSERT INTO index_meta (key, value) VALUES (?, ?) " + "ON CONFLICT(key) DO UPDATE SET value = excluded.value", + (key, value), + ) + + @staticmethod + def get_dim(conn: sqlite3.Connection) -> int | None: + value = IndexMetaTable._get(conn, "dim") + return int(value) if value is not None else None + + @staticmethod + def set_dim(conn: sqlite3.Connection, dim: int) -> None: + IndexMetaTable._set(conn, "dim", str(dim)) + + @staticmethod + def get_embed_model(conn: sqlite3.Connection) -> str | None: + return IndexMetaTable._get(conn, "embed_model") + + @staticmethod + def set_embed_model(conn: sqlite3.Connection, name: str) -> None: + IndexMetaTable._set(conn, "embed_model", name) + + @staticmethod + def get_schema_version(conn: sqlite3.Connection) -> int | None: + value = IndexMetaTable._get(conn, "schema_version") + return int(value) if value is not None else None + + @staticmethod + def set_schema_version(conn: sqlite3.Connection, version: int) -> None: + IndexMetaTable._set(conn, "schema_version", str(version)) + + @staticmethod + def get_total_inserts(conn: sqlite3.Connection) -> int: + value = IndexMetaTable._get(conn, "total_inserts") + return int(value) if value is not None else 0 + + @staticmethod + def increment_total_inserts(conn: sqlite3.Connection, count: int) -> None: + """Add ``count`` to the stored counter in one SQL statement (INSERT + .. ON CONFLICT DO UPDATE with arithmetic), instead of a separate + read-then-write -- called once per add()/upsert_document(), so + halving the statement count here is a real, if small, per-call + saving. This only avoids a read-then-write race within this single + statement; it does not make the counter safe against concurrent + writers in general (callers still rely on the write FileLock for + that). index_meta.value has TEXT affinity, so the incremented + result is stored as its text representation -- get_total_inserts() + already expects that (int(value)), so this is not a behavior + change, only fewer statements. + """ + conn.execute( + "INSERT INTO index_meta (key, value) VALUES ('total_inserts', ?) " + "ON CONFLICT(key) DO UPDATE SET value = " + "CAST(index_meta.value AS INTEGER) + CAST(excluded.value AS INTEGER)", + (str(count),), + ) + + @staticmethod + def reset_total_inserts(conn: sqlite3.Connection, count: int) -> None: + """Set total_inserts to an absolute value -- distinct from + increment_total_inserts(): used by compact()'s rebuild and by + m0001_v1_to_v2 after copying live rows into a fresh file, where + total_inserts must become exactly the live row count, not add to + whatever the source file's counter held.""" + IndexMetaTable._set(conn, "total_inserts", str(count)) diff --git a/src/paperless_ai/tests/test_ai_classifier.py b/src/paperless_ai/tests/test_ai_classifier.py index 470c7fe07..0cc6d8231 100644 --- a/src/paperless_ai/tests/test_ai_classifier.py +++ b/src/paperless_ai/tests/test_ai_classifier.py @@ -3,6 +3,8 @@ from unittest.mock import MagicMock from unittest.mock import patch import pytest +import pytest_mock +from django.contrib.auth.models import User from django.test import override_settings from documents.models import Document @@ -278,3 +280,104 @@ def test_get_context_for_document_no_similar_docs(mock_document): with patch("paperless_ai.ai_classifier.query_similar_documents", return_value=[]): result = get_context_for_document(mock_document) assert result == "" + + +class TestGetContextForDocumentVisibility: + """get_context_for_document must not materialize every visible document + id for a user who can already see the whole library: a superuser (like + no user at all) gets document_ids=None (no restriction) straight + through to query_similar_documents(), instead of a full-library IN + filter that is wasteful at best and, past ~32,763 documents, a hard + sqlite3.OperationalError at worst (SQLite's bound-parameter limit). + """ + + def test_skips_permission_lookup_for_superuser( + self, + mock_document: MagicMock, + mock_similar_documents: list[MagicMock], + mocker: pytest_mock.MockerFixture, + ) -> None: + """ + GIVEN: + - A superuser + WHEN: + - get_context_for_document() is called + THEN: + - get_objects_for_user_owner_aware() is never called, and + query_similar_documents() is called with document_ids=None + """ + mock_query = mocker.patch( + "paperless_ai.ai_classifier.query_similar_documents", + return_value=mock_similar_documents, + ) + mock_get_objects = mocker.patch( + "paperless_ai.ai_classifier.get_objects_for_user_owner_aware", + ) + user = mocker.MagicMock(spec=User) + user.is_superuser = True + + get_context_for_document(mock_document, user, max_docs=2) + + mock_get_objects.assert_not_called() + assert mock_query.call_args.kwargs["document_ids"] is None + + def test_skips_permission_lookup_when_no_user( + self, + mock_document: MagicMock, + mock_similar_documents: list[MagicMock], + mocker: pytest_mock.MockerFixture, + ) -> None: + """ + GIVEN: + - No user (user=None) + WHEN: + - get_context_for_document() is called + THEN: + - get_objects_for_user_owner_aware() is never called, and + query_similar_documents() is called with document_ids=None + """ + mock_query = mocker.patch( + "paperless_ai.ai_classifier.query_similar_documents", + return_value=mock_similar_documents, + ) + mock_get_objects = mocker.patch( + "paperless_ai.ai_classifier.get_objects_for_user_owner_aware", + ) + + get_context_for_document(mock_document, None, max_docs=2) + + mock_get_objects.assert_not_called() + assert mock_query.call_args.kwargs["document_ids"] is None + + def test_restricts_to_visible_documents_for_non_superuser( + self, + mock_document: MagicMock, + mock_similar_documents: list[MagicMock], + mocker: pytest_mock.MockerFixture, + ) -> None: + """ + GIVEN: + - A non-superuser with a specific set of visible documents + WHEN: + - get_context_for_document() is called + THEN: + - query_similar_documents() is called with exactly that user's + visible document ids, unchanged from before this optimization + """ + mock_query = mocker.patch( + "paperless_ai.ai_classifier.query_similar_documents", + return_value=mock_similar_documents, + ) + mock_queryset = mocker.MagicMock() + mock_queryset.values_list.return_value = [1, 2, 3] + mock_get_objects = mocker.patch( + "paperless_ai.ai_classifier.get_objects_for_user_owner_aware", + return_value=mock_queryset, + ) + user = mocker.MagicMock(spec=User) + user.is_superuser = False + + get_context_for_document(mock_document, user, max_docs=2) + + mock_get_objects.assert_called_once_with(user, "view_document", Document) + assert mock_query.call_args.kwargs["document_ids"] == [1, 2, 3] diff --git a/src/paperless_ai/tests/test_ai_indexing.py b/src/paperless_ai/tests/test_ai_indexing.py index 667b43d06..2da225053 100644 --- a/src/paperless_ai/tests/test_ai_indexing.py +++ b/src/paperless_ai/tests/test_ai_indexing.py @@ -1,3 +1,4 @@ +import logging from pathlib import Path from unittest.mock import MagicMock from unittest.mock import patch @@ -8,6 +9,7 @@ from django.db import connection from django.test import override_settings from django.test.utils import CaptureQueriesContext from django.utils import timezone +from filelock import Timeout from llama_index.core.schema import MetadataMode from documents.models import Correspondent @@ -252,6 +254,45 @@ def test_update_llm_index_rebuilds_on_model_name_change( assert store.stored_model_name() == "model-b" +@pytest.mark.django_db +def test_update_llm_index_merges_exists_and_config_mismatch_reads( + temp_llm_index_dir: Path, + real_document: Document, + mock_embed_model: FakeEmbedding, +) -> None: + # Build an initial index so the second call's table_exists()/ + # config_mismatch() checks have something real to check against. + with patch("documents.models.Document.objects.all") as mock_all: + mock_queryset = MagicMock() + mock_queryset.exists.return_value = True + mock_queryset.__iter__.return_value = iter([real_document]) + mock_queryset.select_related.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = mock_queryset + mock_all.return_value = mock_queryset + indexing.update_llm_index(rebuild=True) + + with patch("documents.models.Document.objects.all") as mock_all: + mock_queryset = MagicMock() + mock_queryset.exists.return_value = True + mock_queryset.__iter__.return_value = iter([real_document]) + mock_queryset.select_related.return_value = mock_queryset + mock_queryset.prefetch_related.return_value = mock_queryset + mock_all.return_value = mock_queryset + with patch( + "paperless_ai.indexing.read_store", + wraps=indexing.read_store, + ) as read_store_spy: + indexing.update_llm_index(rebuild=False) + + # Documents exist, so the fast-exit check's `no_documents and ...` + # short-circuits before ever calling llm_index_exists() -- the only + # read_store() call left in this path is the merged table_exists()/ + # config_mismatch() check. Before this task's fix, that merged check + # was two separate read_store() calls (one inside llm_index_exists(), + # one for config_mismatch() right after) -- so this asserts 1, not 2. + assert read_store_spy.call_count == 1 + + @pytest.mark.django_db def test_update_llm_index_partial_update( temp_llm_index_dir: Path, @@ -737,6 +778,7 @@ class TestLlmIndexLocking: mocker: pytest_mock.MockerFixture, ) -> None: mock_store = MagicMock() + mock_store.has_pending_migration.return_value = False mocker.patch( "paperless_ai.indexing.write_store", return_value=mocker.MagicMock( @@ -757,12 +799,83 @@ class TestLlmIndexLocking: mock_store.upsert_document.assert_called_once() + def test_add_or_update_document_skips_write_when_reembed_pending( + self, + temp_llm_index_dir: Path, + mock_embed_model: FakeEmbedding, + mocker: pytest_mock.MockerFixture, + ) -> None: + """A pending re-embed migration must block the incremental write, + not let it proceed against a schema that just changed underneath it. + """ + mock_store = MagicMock() + mock_store.has_pending_migration.return_value = True + mock_store.check_and_run_migrations.return_value = True + mocker.patch( + "paperless_ai.indexing.write_store", + return_value=mocker.MagicMock( + __enter__=mocker.MagicMock(return_value=mock_store), + __exit__=mocker.MagicMock(return_value=False), + ), + ) + mock_node = MagicMock() + mock_node.get_content.return_value = "fake node text" + mocker.patch( + "paperless_ai.indexing.build_document_node", + return_value=[mock_node], + ) + + doc = MagicMock(spec=Document) + doc.id = 1 + indexing.llm_index_add_or_update_document(doc) + + mock_store.upsert_document.assert_not_called() + + def test_add_or_update_document_skips_write_when_migration_check_deferred( + self, + temp_llm_index_dir: Path, + mock_embed_model: FakeEmbedding, + mocker: pytest_mock.MockerFixture, + ) -> None: + """A migration check that times out waiting for readers to drain + must be treated the same as a pending migration -- proceeding to + write would target a store still on its old schema. Regression + test for the tri-state fix: a bare bool collapsed this outcome + into the same falsy value as "already current". + """ + mock_store = MagicMock() + mock_store.has_pending_migration.return_value = True + mocker.patch( + "paperless_ai.indexing.write_store", + return_value=mocker.MagicMock( + __enter__=mocker.MagicMock(return_value=mock_store), + __exit__=mocker.MagicMock(return_value=False), + ), + ) + mocker.patch( + "paperless_ai.indexing._exclude_readers", + side_effect=Timeout("test"), + ) + mock_node = MagicMock() + mock_node.get_content.return_value = "fake node text" + mocker.patch( + "paperless_ai.indexing.build_document_node", + return_value=[mock_node], + ) + + doc = MagicMock(spec=Document) + doc.id = 1 + indexing.llm_index_add_or_update_document(doc) + + mock_store.upsert_document.assert_not_called() + def test_remove_document_uses_write_store( self, temp_llm_index_dir: Path, mocker: pytest_mock.MockerFixture, ) -> None: mock_store = MagicMock() + mock_store.has_pending_migration.return_value = False mocker.patch( "paperless_ai.indexing.write_store", return_value=mocker.MagicMock( @@ -777,6 +890,59 @@ class TestLlmIndexLocking: mock_store.delete.assert_called_once_with("1") + def test_remove_document_skips_write_when_reembed_pending( + self, + temp_llm_index_dir: Path, + mocker: pytest_mock.MockerFixture, + ) -> None: + """A pending re-embed migration must block the delete too, for the + same consistency reason as the incremental-update path. + """ + mock_store = MagicMock() + mock_store.has_pending_migration.return_value = True + mock_store.check_and_run_migrations.return_value = True + mocker.patch( + "paperless_ai.indexing.write_store", + return_value=mocker.MagicMock( + __enter__=mocker.MagicMock(return_value=mock_store), + __exit__=mocker.MagicMock(return_value=False), + ), + ) + + doc = MagicMock(spec=Document) + doc.id = 1 + indexing.llm_index_remove_document(doc) + + mock_store.delete.assert_not_called() + + def test_remove_document_skips_write_when_migration_check_deferred( + self, + temp_llm_index_dir: Path, + mocker: pytest_mock.MockerFixture, + ) -> None: + """A migration check deferred by a reader-lock timeout must block + the delete too, for the same reason as the incremental-update path. + """ + mock_store = MagicMock() + mock_store.has_pending_migration.return_value = True + mocker.patch( + "paperless_ai.indexing.write_store", + return_value=mocker.MagicMock( + __enter__=mocker.MagicMock(return_value=mock_store), + __exit__=mocker.MagicMock(return_value=False), + ), + ) + mocker.patch( + "paperless_ai.indexing._exclude_readers", + side_effect=Timeout("test"), + ) + + doc = MagicMock(spec=Document) + doc.id = 1 + indexing.llm_index_remove_document(doc) + + mock_store.delete.assert_not_called() + def test_update_llm_index_rebuild_uses_write_store( self, temp_llm_index_dir: Path, @@ -800,6 +966,35 @@ class TestLlmIndexLocking: mock_store.drop_table.assert_called_once() + def test_update_llm_index_skips_when_migration_check_deferred( + self, + temp_llm_index_dir: Path, + mocker: pytest_mock.MockerFixture, + ) -> None: + """A migration check deferred by a reader-lock timeout must short- + circuit before the second write_store() block (document scanning, + add/upsert, compaction) ever runs -- that block would otherwise + write against a store still on its old schema. + """ + mock_store = MagicMock() + mock_store.has_pending_migration.return_value = True + write_store_mock = mocker.patch( + "paperless_ai.indexing.write_store", + return_value=mocker.MagicMock( + __enter__=mocker.MagicMock(return_value=mock_store), + __exit__=mocker.MagicMock(return_value=False), + ), + ) + mocker.patch( + "paperless_ai.indexing._exclude_readers", + side_effect=Timeout("test"), + ) + + result = indexing.update_llm_index(rebuild=False) + + assert "deferred" in result + write_store_mock.assert_called_once() + @pytest.mark.django_db @pytest.mark.django_db @@ -849,6 +1044,107 @@ class TestVectorStoreIndexing: assert rows >= 1 +class TestLlmIndexMigrate: + def test_noop_when_ai_disabled(self, mocker: pytest_mock.MockerFixture) -> None: + """ + GIVEN: + - AI/LLM index support is disabled in configuration + WHEN: + - llm_index_migrate() is called + THEN: + - No store is opened and no migration check runs + """ + mocker.patch( + "paperless_ai.indexing.AIConfig", + return_value=mocker.Mock(llm_index_enabled=False), + ) + write_store_mock = mocker.patch("paperless_ai.indexing.write_store") + indexing.llm_index_migrate() + write_store_mock.assert_not_called() + + def test_runs_pending_migration_when_enabled( + self, + mocker: pytest_mock.MockerFixture, + ) -> None: + """ + GIVEN: + - AI/LLM index support is enabled + WHEN: + - llm_index_migrate() is called + THEN: + - The store is opened for write and a migration check runs + """ + mocker.patch( + "paperless_ai.indexing.AIConfig", + return_value=mocker.Mock(llm_index_enabled=True), + ) + store_mock = mocker.MagicMock() + store_mock.has_pending_migration.return_value = False + write_store_cm = mocker.patch("paperless_ai.indexing.write_store") + write_store_cm.return_value.__enter__.return_value = store_mock + indexing.llm_index_migrate() + store_mock.has_pending_migration.assert_called_once() + + def test_logs_warning_when_reembed_needed( + self, + mocker: pytest_mock.MockerFixture, + caplog: pytest.LogCaptureFixture, + ) -> None: + """ + GIVEN: + - AI/LLM index support is enabled + - A pending migration requires re-embedding + WHEN: + - llm_index_migrate() is called + THEN: + - A warning directs the operator to run a manual rebuild, since + this automatic check must never re-embed on its own + """ + mocker.patch( + "paperless_ai.indexing.AIConfig", + return_value=mocker.Mock(llm_index_enabled=True), + ) + store_mock = mocker.MagicMock() + store_mock.has_pending_migration.return_value = True + store_mock.check_and_run_migrations.return_value = True + write_store_cm = mocker.patch("paperless_ai.indexing.write_store") + write_store_cm.return_value.__enter__.return_value = store_mock + with caplog.at_level(logging.WARNING, logger="paperless_ai.indexing"): + indexing.llm_index_migrate() + assert "requires re-embedding" in caplog.text + + def test_logs_info_when_migration_check_deferred( + self, + mocker: pytest_mock.MockerFixture, + caplog: pytest.LogCaptureFixture, + ) -> None: + """ + GIVEN: + - AI/LLM index support is enabled + - A pending migration cannot run because readers are active + WHEN: + - llm_index_migrate() is called + THEN: + - An info line notes the deferral, not the re-embed warning + """ + mocker.patch( + "paperless_ai.indexing.AIConfig", + return_value=mocker.Mock(llm_index_enabled=True), + ) + store_mock = mocker.MagicMock() + store_mock.has_pending_migration.return_value = True + write_store_cm = mocker.patch("paperless_ai.indexing.write_store") + write_store_cm.return_value.__enter__.return_value = store_mock + mocker.patch( + "paperless_ai.indexing._exclude_readers", + side_effect=Timeout("test"), + ) + with caplog.at_level(logging.INFO, logger="paperless_ai.indexing"): + indexing.llm_index_migrate() + assert "deferred" in caplog.text + assert "requires re-embedding" not in caplog.text + + @pytest.mark.django_db class TestQuerySimilarDocuments: def test_query_similar_documents_respects_allowed_ids( diff --git a/src/paperless_ai/tests/test_base_model.py b/src/paperless_ai/tests/test_base_model.py new file mode 100644 index 000000000..c598f1400 --- /dev/null +++ b/src/paperless_ai/tests/test_base_model.py @@ -0,0 +1,35 @@ +import pytest +from pydantic import ValidationError + +from paperless_ai.base_model import DocumentClassifierSchema + + +@pytest.mark.parametrize( + "omitted_field", + [ + "tags", + "correspondents", + "document_types", + "storage_paths", + "dates", + ], +) +def test_document_classifier_schema_defaults_omitted_list_field(omitted_field): + data = { + "title": "Test Title", + "tags": ["test"], + "correspondents": ["Test Correspondent"], + "document_types": ["Test Document Type"], + "storage_paths": ["Test Storage Path"], + "dates": ["2026-07-31"], + } + del data[omitted_field] + + result = DocumentClassifierSchema(**data) + + assert getattr(result, omitted_field) == [] + + +def test_document_classifier_schema_requires_title(): + with pytest.raises(ValidationError, match="title"): + DocumentClassifierSchema() diff --git a/src/paperless_ai/tests/test_tables.py b/src/paperless_ai/tests/test_tables.py new file mode 100644 index 000000000..1feda711c --- /dev/null +++ b/src/paperless_ai/tests/test_tables.py @@ -0,0 +1,340 @@ +import sqlite3 +from collections.abc import Generator + +import pytest +from pytest_mock import MockerFixture + +from paperless_ai.tables import ChunkRow +from paperless_ai.tables import DocumentChunksTable +from paperless_ai.tables import DocumentMetaRow +from paperless_ai.tables import DocumentMetaTable +from paperless_ai.tables import IndexMetaTable + + +@pytest.fixture +def conn() -> Generator[sqlite3.Connection, None, None]: + connection = sqlite3.connect(":memory:") + connection.row_factory = sqlite3.Row + try: + yield connection + finally: + connection.close() + + +class TestDocumentChunksTable: + def test_create_is_idempotent(self, conn: sqlite3.Connection) -> None: + """ + GIVEN: + - A bare sqlite3 connection + WHEN: + - create() is called, a row is inserted, then create() is called again + THEN: + - No error is raised and the row survives uncorrupted + """ + DocumentChunksTable.create(conn) + DocumentChunksTable.insert_many(conn, [ChunkRow("c1", 1)]) + DocumentChunksTable.create(conn) + assert DocumentChunksTable.chunk_ids_for_document(conn, 1) == ["c1"] + + def test_insert_many_then_lookup_by_document_id( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - An empty document_chunks table + WHEN: + - Two chunks for document 1 and one for document 2 are inserted + THEN: + - chunk_ids_for_document returns exactly the matching chunk ids + """ + DocumentChunksTable.create(conn) + DocumentChunksTable.insert_many( + conn, + [ChunkRow("c1", 1), ChunkRow("c2", 1), ChunkRow("c3", 2)], + ) + assert sorted(DocumentChunksTable.chunk_ids_for_document(conn, 1)) == [ + "c1", + "c2", + ] + assert DocumentChunksTable.chunk_ids_for_document(conn, 2) == ["c3"] + assert DocumentChunksTable.chunk_ids_for_document(conn, 999) == [] + + def test_delete_for_document_removes_only_that_document( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - Chunks for two different documents + WHEN: + - delete_for_document() is called for one of them + THEN: + - Only that document's chunks are removed + """ + DocumentChunksTable.create(conn) + DocumentChunksTable.insert_many( + conn, + [ChunkRow("c1", 1), ChunkRow("c2", 2)], + ) + DocumentChunksTable.delete_for_document(conn, 1) + assert DocumentChunksTable.chunk_ids_for_document(conn, 1) == [] + assert DocumentChunksTable.chunk_ids_for_document(conn, 2) == ["c2"] + + def test_delete_all_clears_every_row(self, conn: sqlite3.Connection) -> None: + """ + GIVEN: + - Chunks for multiple documents + WHEN: + - delete_all() is called + THEN: + - count() returns 0 + """ + DocumentChunksTable.create(conn) + DocumentChunksTable.insert_many( + conn, + [ChunkRow("c1", 1), ChunkRow("c2", 2)], + ) + DocumentChunksTable.delete_all(conn) + assert DocumentChunksTable.count(conn) == 0 + + def test_count_reflects_live_rows(self, conn: sqlite3.Connection) -> None: + """ + GIVEN: + - An empty document_chunks table + WHEN: + - Rows are inserted then one document's rows are deleted + THEN: + - count() reflects the remaining row count + """ + DocumentChunksTable.create(conn) + DocumentChunksTable.insert_many( + conn, + [ChunkRow("c1", 1), ChunkRow("c2", 1), ChunkRow("c3", 2)], + ) + assert DocumentChunksTable.count(conn) == 3 + DocumentChunksTable.delete_for_document(conn, 1) + assert DocumentChunksTable.count(conn) == 1 + + +class TestDocumentMetaTable: + def test_upsert_many_then_all_modified_times( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - An empty document_meta table + WHEN: + - Two documents' modified timestamps are upserted + THEN: + - all_modified_times() returns both, keyed by str(document_id) + """ + DocumentMetaTable.create(conn) + DocumentMetaTable.upsert_many( + conn, + [ + DocumentMetaRow(1, "2026-01-01T00:00:00"), + DocumentMetaRow(2, "2026-02-02T00:00:00"), + ], + ) + assert DocumentMetaTable.all_modified_times(conn) == { + "1": "2026-01-01T00:00:00", + "2": "2026-02-02T00:00:00", + } + + def test_upsert_many_overwrites_existing_value( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - A document_meta row for document 1 + WHEN: + - upsert_many() is called again with a new modified value for + the same document_id + THEN: + - The stored value is replaced, not duplicated + """ + DocumentMetaTable.create(conn) + DocumentMetaTable.upsert_many(conn, [DocumentMetaRow(1, "old")]) + DocumentMetaTable.upsert_many(conn, [DocumentMetaRow(1, "new")]) + assert DocumentMetaTable.all_modified_times(conn) == {"1": "new"} + + def test_delete_for_document_removes_only_that_row( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - document_meta rows for two documents + WHEN: + - delete_for_document() is called for one of them + THEN: + - Only that document's row is removed + """ + DocumentMetaTable.create(conn) + DocumentMetaTable.upsert_many( + conn, + [DocumentMetaRow(1, "a"), DocumentMetaRow(2, "b")], + ) + DocumentMetaTable.delete_for_document(conn, 1) + assert DocumentMetaTable.all_modified_times(conn) == {"2": "b"} + + def test_delete_all_clears_every_row(self, conn: sqlite3.Connection) -> None: + """ + GIVEN: + - document_meta rows for multiple documents + WHEN: + - delete_all() is called + THEN: + - all_modified_times() returns an empty dict + """ + DocumentMetaTable.create(conn) + DocumentMetaTable.upsert_many( + conn, + [DocumentMetaRow(1, "a"), DocumentMetaRow(2, "b")], + ) + DocumentMetaTable.delete_all(conn) + assert DocumentMetaTable.all_modified_times(conn) == {} + + def test_copy_all_streams_every_row_to_destination( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - A source connection with document_meta rows for 5 documents + - A separate, empty destination connection + WHEN: + - copy_all() is called with a batch size smaller than the row + count, forcing multiple fetchmany() cycles + THEN: + - Every row is present on the destination connection + """ + DocumentMetaTable.create(conn) + DocumentMetaTable.upsert_many( + conn, + [DocumentMetaRow(i, f"modified-{i}") for i in range(5)], + ) + dst_conn = sqlite3.connect(":memory:") + dst_conn.row_factory = sqlite3.Row + try: + DocumentMetaTable.create(dst_conn) + DocumentMetaTable.copy_all(conn, dst_conn, batch_size=2) + assert DocumentMetaTable.all_modified_times(dst_conn) == { + str(i): f"modified-{i}" for i in range(5) + } + finally: + dst_conn.close() + + +class TestIndexMetaTable: + @pytest.mark.parametrize( + ("setter_name", "getter_name", "value"), + [ + ("set_dim", "get_dim", 384), + ("set_embed_model", "get_embed_model", "model-a"), + ("set_schema_version", "get_schema_version", 2), + ], + ) + def test_typed_accessor_roundtrip( + self, + conn: sqlite3.Connection, + setter_name: str, + getter_name: str, + value: int | str, + ) -> None: + """ + GIVEN: + - An empty index_meta table + WHEN: + - A typed accessor's setter is called then the getter is read back + THEN: + - The same value is returned, correctly typed (int or str) + """ + IndexMetaTable.create(conn) + getter = getattr(IndexMetaTable, getter_name) + setter = getattr(IndexMetaTable, setter_name) + assert getter(conn) is None + setter(conn, value) + assert getter(conn) == value + + def test_total_inserts_starts_at_zero(self, conn: sqlite3.Connection) -> None: + """ + GIVEN: + - An empty index_meta table + WHEN: + - get_total_inserts() is read before anything is set + THEN: + - 0 is returned + """ + IndexMetaTable.create(conn) + assert IndexMetaTable.get_total_inserts(conn) == 0 + + def test_increment_total_inserts_accumulates( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - An empty index_meta table + WHEN: + - increment_total_inserts() is called twice + THEN: + - get_total_inserts() returns the running sum + """ + IndexMetaTable.create(conn) + IndexMetaTable.increment_total_inserts(conn, 5) + IndexMetaTable.increment_total_inserts(conn, 3) + assert IndexMetaTable.get_total_inserts(conn) == 8 + + def test_increment_total_inserts_is_a_single_statement( + self, + mocker: MockerFixture, + ) -> None: + """ + GIVEN: + - An empty index_meta table + WHEN: + - increment_total_inserts() is called + THEN: + - Exactly one conn.execute() call is made (a single INSERT ... + ON CONFLICT DO UPDATE, not a separate read then write) + """ + + # sqlite3.Connection is an immutable C extension type with no + # instance __dict__, so mocker.spy(conn, "execute") can't shadow + # "execute" on a plain connection ("attribute 'execute' is + # read-only"). A trivial Python subclass gets a normal instance + # __dict__, making the instance spyable while still being a real, + # usable sqlite3.Connection. + class _SpyableConnection(sqlite3.Connection): + pass + + conn = sqlite3.connect(":memory:", factory=_SpyableConnection) + try: + conn.row_factory = sqlite3.Row + IndexMetaTable.create(conn) + execute_spy = mocker.spy(conn, "execute") + IndexMetaTable.increment_total_inserts(conn, 5) + assert execute_spy.call_count == 1 + finally: + conn.close() + + def test_reset_total_inserts_sets_absolute_value( + self, + conn: sqlite3.Connection, + ) -> None: + """ + GIVEN: + - A total_inserts counter already at a high value + WHEN: + - reset_total_inserts() is called with a lower value + THEN: + - get_total_inserts() returns exactly that value, not a sum + """ + IndexMetaTable.create(conn) + IndexMetaTable.increment_total_inserts(conn, 100) + IndexMetaTable.reset_total_inserts(conn, 7) + assert IndexMetaTable.get_total_inserts(conn) == 7 diff --git a/src/paperless_ai/tests/test_vector_store.py b/src/paperless_ai/tests/test_vector_store.py index 75cc0d17e..3ed1b7e42 100644 --- a/src/paperless_ai/tests/test_vector_store.py +++ b/src/paperless_ai/tests/test_vector_store.py @@ -1,28 +1,36 @@ +import inspect import sqlite3 from collections.abc import Generator from pathlib import Path import pytest +import sqlite_vec from llama_index.core.schema import TextNode from llama_index.core.vector_stores.types import FilterOperator from llama_index.core.vector_stores.types import MetadataFilter from llama_index.core.vector_stores.types import MetadataFilters from llama_index.core.vector_stores.types import VectorStoreQuery +from pytest_mock import MockerFixture +from paperless_ai.migrations import MIGRATIONS +from paperless_ai.migrations import Migration +from paperless_ai.migrations import m0001_v1_to_v2 +from paperless_ai.tables import DocumentChunksTable +from paperless_ai.tables import DocumentMetaTable +from paperless_ai.vector_store import _MAX_IN_VALUES from paperless_ai.vector_store import DB_FILENAME from paperless_ai.vector_store import DEFAULT_TABLE_NAME -from paperless_ai.vector_store import MIGRATIONS from paperless_ai.vector_store import SCHEMA_VERSION -from paperless_ai.vector_store import Migration from paperless_ai.vector_store import PaperlessSqliteVecVectorStore from paperless_ai.vector_store import _build_where +from paperless_ai.vector_store import _pack DIM = 16 def make_node( node_id: str, - document_id: str, + document_id: int, *, modified: str = "2026-06-10T00:00:00", seed: float = 0.0, @@ -59,13 +67,13 @@ def _query( ) -def _eq_filter(key: str, value: str): +def _eq_filter(key: str, value: int): return MetadataFilters( filters=[MetadataFilter(key=key, operator=FilterOperator.EQ, value=value)], ) -def _in_filter(document_ids: list[str]): +def _in_filter(document_ids: list[int]): return MetadataFilters( filters=[ MetadataFilter( @@ -77,7 +85,7 @@ def _in_filter(document_ids: list[str]): ) -def _ne_filter(document_id: str): +def _ne_filter(document_id: int): return MetadataFilters( filters=[ MetadataFilter( @@ -91,11 +99,11 @@ def _ne_filter(document_id: str): class TestCrud: def test_add_then_query_returns_node(self, store) -> None: - node = make_node("n1", "1") + node = make_node("n1", 1) assert store.add([node]) == ["n1"] result = _query(store, node.embedding, top_k=1) assert result.ids == ["n1"] - assert result.nodes[0].metadata["document_id"] == "1" + assert result.nodes[0].metadata["document_id"] == 1 # cosine distance of the identical vector is 0 -> similarity 1 assert result.similarities[0] == pytest.approx(1.0) @@ -108,58 +116,58 @@ class TestCrud: assert not store.table_exists() def test_delete_removes_all_chunks_of_document(self, store) -> None: - store.add([make_node("a1", "1"), make_node("a2", "1"), make_node("b1", "2")]) - store.delete("1") + store.add([make_node("a1", 1), make_node("a2", 1), make_node("b1", 2)]) + store.delete(1) result = _query(store, [0.0] * DIM, top_k=10) assert result.ids == ["b1"] def test_query_with_in_filter_scopes_results(self, store) -> None: store.add( [ - make_node("a1", "1", seed=0.0), - make_node("b1", "2", seed=1.0), - make_node("c1", "3", seed=2.0), + make_node("a1", 1, seed=0.0), + make_node("b1", 2, seed=1.0), + make_node("c1", 3, seed=2.0), ], ) - result = _query(store, [0.0] * DIM, top_k=10, filters=_in_filter(["2", "3"])) + result = _query(store, [0.0] * DIM, top_k=10, filters=_in_filter([2, 3])) assert sorted(result.ids) == ["b1", "c1"] def test_query_respects_top_k_with_filter(self, store) -> None: # k semantics: global top-k even with IN filters (document_id is a # metadata column, not a partition key -- see design doc). store.add( - [make_node(f"n{i}", str(i % 4), seed=float(i)) for i in range(12)], + [make_node(f"n{i}", i % 4, seed=float(i)) for i in range(12)], ) result = _query( store, [0.0] * DIM, top_k=3, - filters=_in_filter(["0", "1", "2", "3"]), + filters=_in_filter([0, 1, 2, 3]), ) assert len(result.ids) == 3 assert result.similarities == sorted(result.similarities, reverse=True) def test_get_nodes_filter_and_empty_paths(self, store) -> None: - assert store.get_nodes(filters=_in_filter(["1"])) == [] # no table yet - store.add([make_node("a1", "1"), make_node("b1", "2")]) - nodes = store.get_nodes(filters=_in_filter(["1"])) + assert store.get_nodes(filters=_in_filter([1])) == [] # no table yet + store.add([make_node("a1", 1), make_node("b1", 2)]) + nodes = store.get_nodes(filters=_in_filter([1])) assert [n.node_id for n in nodes] == ["a1"] assert nodes[0].embedding is not None - assert store.get_nodes(filters=_in_filter(["999"])) == [] + assert store.get_nodes(filters=_in_filter([999])) == [] def test_query_with_eq_filter_scopes_results(self, store) -> None: store.add( [ - make_node("a1", "1", seed=0.0), - make_node("b1", "2", seed=1.0), - make_node("c1", "3", seed=2.0), + make_node("a1", 1, seed=0.0), + make_node("b1", 2, seed=1.0), + make_node("c1", 3, seed=2.0), ], ) result = _query( store, [0.0] * DIM, top_k=10, - filters=_eq_filter("document_id", "2"), + filters=_eq_filter("document_id", 2), ) assert result.ids == ["b1"] @@ -168,7 +176,7 @@ class TestCrud: store.get_nodes(node_ids=["x"]) def test_fresh_instance_sees_existing_table(self, store, tmp_path: Path) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as reopened: assert reopened.table_exists() assert reopened.vector_dim() == DIM @@ -176,23 +184,98 @@ class TestCrud: def test_table_exists_and_drop(self, store) -> None: assert not store.table_exists() - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert store.table_exists() store.drop_table() assert not store.table_exists() assert store.vector_dim() is None + def test_document_id_stored_as_integer_in_vec0( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - An empty vector store + WHEN: + - A node is added with an int document_id + THEN: + - vec0's own document_id column holds an INTEGER, not TEXT + """ + store.add([make_node("a1", 1)]) + row = store.client.execute( + "SELECT document_id FROM documents WHERE id = 'a1'", + ).fetchone() + assert isinstance(row["document_id"], int) + + def test_drop_table_clears_modified_times( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A store with a tracked document's modified time + WHEN: + - drop_table() is called + THEN: + - document_meta and document_chunks are both cleared directly + (asserted against the tables themselves, not via + get_modified_times()/table_exists() -- those short-circuit on + the vec0 table being gone, which drop_table() does first, so + they would pass even if DocumentMetaTable.delete_all()/ + DocumentChunksTable.delete_all() were never called) + """ + store.add([make_node("a1", 1)]) + store.drop_table() + assert ( + store.client.execute( + "SELECT count(*) FROM document_meta", + ).fetchone()[0] + == 0 + ) + assert ( + store.client.execute( + "SELECT count(*) FROM document_chunks", + ).fetchone()[0] + == 0 + ) + + def test_upsert_document_checks_table_exists_once( + self, + store: PaperlessSqliteVecVectorStore, + mocker: MockerFixture, + ) -> None: + """ + GIVEN: + - An existing store with one document already indexed + WHEN: + - upsert_document() replaces that document's chunks + THEN: + - table_exists() is queried at most once per call, not twice + (previously: once via _ensure_table(), once via the separate + `if self.table_exists():` delete-chunks guard) + """ + store.add([make_node("a1", 1)]) + # store is a pydantic model, whose __setattr__/__delattr__ reject + # arbitrary instance attributes ("object has no attribute + # 'table_exists'"), so mocker.spy(store, "table_exists") can't + # shadow the method on the instance. Spying on the class works + # (bound method lookup on the instance still resolves through it). + exists_spy = mocker.spy(PaperlessSqliteVecVectorStore, "table_exists") + store.upsert_document(1, [make_node("a2", 1)]) + assert exists_spy.call_count == 1 + class TestBuildWhere: def test_ne_filter_translates_to_not_equal_clause(self) -> None: - where, params = _build_where(_ne_filter("1")) + where, params = _build_where(_ne_filter(1)) assert where == "(document_id != ?)" - assert params == ["1"] + assert params == [1] def test_query_with_ne_filter_excludes_matching_document(self, store) -> None: - store.add([make_node("a1", "1"), make_node("b1", "2")]) + store.add([make_node("a1", 1), make_node("b1", 2)]) assert sorted( - _query(store, [0.0] * DIM, top_k=5, filters=_ne_filter("1")).ids, + _query(store, [0.0] * DIM, top_k=5, filters=_ne_filter(1)).ids, ) == [ "b1", ] @@ -206,7 +289,7 @@ class TestBuildWhere: MetadataFilter( key="document_id", operator=FilterOperator.EQ, - value="1", + value=1, ), ], ) @@ -214,14 +297,53 @@ class TestBuildWhere: assert where == "1 = 0" assert params == [] - def test_query_with_untranslatable_filter_returns_no_rows(self, store) -> None: + def test_fails_closed_when_in_filter_exceeds_max_values( + self, + caplog: pytest.LogCaptureFixture, + ) -> None: + """ + GIVEN: + - An IN filter with more values than _MAX_IN_VALUES (SQLite's + own bound-parameter limit is 32766; this guard sits below + that with headroom for the query's other bound parameters) + WHEN: + - _build_where() translates it to SQL + THEN: + - It fails closed ("1 = 0", no params) instead of building an + IN clause SQLite would reject, and logs a warning -- this + filter scopes document access, so refusing to build it must + never widen the scope to "everything" by accident + """ + oversized = _in_filter([str(i) for i in range(_MAX_IN_VALUES + 1)]) + + with caplog.at_level("WARNING"): + where, params = _build_where(oversized) + + assert where == "(1 = 0)" + assert params == [] + assert "document_id" in caplog.text + + def test_query_with_untranslatable_filter_returns_no_rows( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A store with one chunk each for documents 1 and 2 + WHEN: + - A query and a get_nodes() call are issued with a filter whose + only clause is an untranslatable nested MetadataFilters + THEN: + - Neither call raises, and both fail closed by returning no rows + (rather than emitting invalid or unfiltered SQL) + """ store.add([make_node("a1", "1"), make_node("b1", "2")]) nested = MetadataFilters( filters=[ MetadataFilter( key="document_id", operator=FilterOperator.EQ, - value="1", + value=1, ), ], ) @@ -234,19 +356,19 @@ class TestBuildWhere: class TestUpsert: def test_upsert_replaces_and_prunes_stale_chunks(self, store) -> None: store.add( - [make_node("d1c1", "1"), make_node("d1c2", "1"), make_node("d2c1", "2")], + [make_node("d1c1", 1), make_node("d1c2", 1), make_node("d2c1", 2)], ) - store.upsert_document("1", [make_node("d1new", "1")]) + store.upsert_document(1, [make_node("d1new", 1)]) result = _query(store, [0.0] * DIM, top_k=10) assert sorted(result.ids) == ["d1new", "d2c1"] def test_upsert_creates_table_when_missing(self, store) -> None: - store.upsert_document("1", [make_node("a1", "1")]) + store.upsert_document(1, [make_node("a1", 1)]) assert _query(store, [0.0] * DIM, top_k=1).ids == ["a1"] def test_upsert_empty_nodes_removes_document(self, store) -> None: - store.add([make_node("a1", "1"), make_node("b1", "2")]) - store.upsert_document("1", []) + store.add([make_node("a1", 1), make_node("b1", 2)]) + store.upsert_document(1, []) assert _query(store, [0.0] * DIM, top_k=10).ids == ["b1"] def test_upsert_is_atomic_for_concurrent_readers( @@ -255,16 +377,16 @@ class TestUpsert: tmp_path: Path, ) -> None: """A second connection must never observe document 1 half-replaced.""" - store.add([make_node("a1", "1"), make_node("a2", "1")]) + store.add([make_node("a1", 1), make_node("a2", 1)]) with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as reader: - store.upsert_document("1", [make_node("a3", "1")]) - ids = [n.node_id for n in reader.get_nodes(filters=_in_filter(["1"]))] + store.upsert_document(1, [make_node("a3", 1)]) + ids = [n.node_id for n in reader.get_nodes(filters=_in_filter([1]))] assert ids == ["a3"] class TestMetadataCoercion: def test_none_metadata_values_become_empty_strings(self, store) -> None: - node = make_node("a1", "1") + node = make_node("a1", 1) node.metadata["modified"] = None store.add([node]) # must not raise (vec0 rejects NULL metadata) assert store.get_modified_times() == {"1": ""} @@ -283,7 +405,7 @@ class TestModelNameTracking: uri=str(tmp_path), embed_model_name="model-a", ) as store: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert store.stored_model_name() == "model-a" with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as reopened: assert reopened.stored_model_name() == "model-a" @@ -294,7 +416,7 @@ class TestModelNameTracking: embed_model_name="model-a", ) as store: assert not store.config_mismatch("anything") # no table yet - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert not store.config_mismatch("model-a") assert store.config_mismatch("model-b") @@ -303,7 +425,7 @@ class TestModelNameTracking: tmp_path: Path, ) -> None: with PaperlessSqliteVecVectorStore(uri=str(tmp_path)) as store: # no model name - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert not store.config_mismatch("model-a") @@ -314,9 +436,9 @@ class TestGetModifiedTimes: def test_returns_one_entry_per_document(self, store) -> None: store.add( [ - make_node("a1", "1", modified="2026-01-01T00:00:00"), - make_node("a2", "1", modified="2026-01-01T00:00:00"), - make_node("b1", "2", modified="2026-02-02T00:00:00"), + make_node("a1", 1, modified="2026-01-01T00:00:00"), + make_node("a2", 1, modified="2026-01-01T00:00:00"), + make_node("b1", 2, modified="2026-02-02T00:00:00"), ], ) assert store.get_modified_times() == { @@ -341,37 +463,35 @@ class TestCompact: def _churn(self, store, cycles: int) -> None: for i in range(cycles): store.upsert_document( - "1", - [make_node(f"gen{i}-{j}", "1", seed=float(j)) for j in range(20)], + 1, + [make_node(f"gen{i}-{j}", 1, seed=float(j)) for j in range(20)], ) def test_compact_noop_below_threshold(self, store) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) store.compact() assert _query(store, [0.0] * DIM, top_k=1).ids == ["a1"] def test_force_compact_preserves_rows_and_metadata(self, store) -> None: - store.add([make_node("a1", "1"), make_node("b1", "2", seed=3.0)]) + store.add([make_node("a1", 1), make_node("b1", 2, seed=3.0)]) self._churn(store, 5) before = { - n.node_id: n.metadata - for n in store.get_nodes(filters=_in_filter(["1", "2"])) + n.node_id: n.metadata for n in store.get_nodes(filters=_in_filter([1, 2])) } store.compact(force=True) after = { - n.node_id: n.metadata - for n in store.get_nodes(filters=_in_filter(["1", "2"])) + n.node_id: n.metadata for n in store.get_nodes(filters=_in_filter([1, 2])) } assert after == before assert self._bloat_ratio(store) == pytest.approx(1.0) # store remains fully usable after the rebuild; use a seed far from all # existing nodes (gen4-0..gen4-19 have seeds 0..19) so cosine KNN is # unambiguous at top_k=1. - store.upsert_document("3", [make_node("c1", "3", seed=100.0)]) + store.upsert_document(3, [make_node("c1", 3, seed=100.0)]) assert "c1" in _query(store, [100.0] * DIM, top_k=1).ids def test_auto_compact_triggers_on_churn(self, store) -> None: - store.add([make_node(f"s{j}", "1", seed=float(j)) for j in range(20)]) + store.add([make_node(f"s{j}", 1, seed=float(j)) for j in range(20)]) self._churn(store, 5) assert self._bloat_ratio(store) > 2 store.compact() @@ -393,7 +513,7 @@ class TestCompact: but a concurrent reader keeps -wal/-shm alive, so the cleanup must unlink them explicitly (as the structural-migration path does). """ - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) compact_path = str(tmp_path / DB_FILENAME) + ".compact" held: list[sqlite3.Connection] = [] @@ -428,17 +548,76 @@ class TestCompact: A tiny batch size forces several fetchmany()/executemany() cycles so a regression in the streaming loop (dropped tail, off-by-one) surfaces. """ - monkeypatch.setattr("paperless_ai.vector_store.COMPACT_BATCH_SIZE", 3) - store.add([make_node(f"n{i}", "1", seed=float(i)) for i in range(10)]) + monkeypatch.setattr("paperless_ai.vector_store.BATCH_SIZE", 3) + store.add([make_node(f"n{i}", 1, seed=float(i)) for i in range(10)]) store.compact(force=True) - ids = {n.node_id for n in store.get_nodes(filters=_in_filter(["1"]))} + ids = {n.node_id for n in store.get_nodes(filters=_in_filter([1]))} assert ids == {f"n{i}" for i in range(10)} assert self._bloat_ratio(store) == pytest.approx(1.0) + def test_force_compact_preserves_modified_times( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A store with documents whose modified times are tracked + WHEN: + - compact(force=True) rebuilds the database file + THEN: + - get_modified_times() still returns every document's value + (document_meta must be copied across the file-swap, not just + the vec0 rows) + """ + store.add( + [ + make_node("a1", 1, modified="2026-01-01T00:00:00"), + make_node("b1", 2, modified="2026-02-02T00:00:00"), + ], + ) + before = store.get_modified_times() + store.compact(force=True) + assert store.get_modified_times() == before + + def test_compact_on_unmigrated_store_is_noop( + self, + store: PaperlessSqliteVecVectorStore, + mocker: MockerFixture, + ) -> None: + """ + GIVEN: + - A store whose schema_version has been forced behind + SCHEMA_VERSION (has_pending_migration() is True) + WHEN: + - compact(force=True) is called directly, without the caller + having run check_and_run_migrations() first + THEN: + - compact() is a safe no-op: no file-swap rebuild is attempted + at all (asserted via a spy on _rebuild_into, since schema_version + alone is not a reliable signal -- a rebuild would otherwise + copy the stale schema_version across unchanged, making a + before/after equality check pass even when a rebuild *did* + happen). Rebuilding an unmigrated store would silently lose + document_meta and leave the swapped-in file claiming the old + schema_version -- see the class docstring rationale. + """ + store.add([make_node("a1", 1)]) + store.client.execute( + "UPDATE index_meta SET value = '0' WHERE key = 'schema_version'", + ) + assert store.has_pending_migration() is True + rebuild_spy = mocker.spy(PaperlessSqliteVecVectorStore, "_rebuild_into") + store.compact(force=True) + rebuild_spy.assert_not_called() + row = store.client.execute( + "SELECT value FROM index_meta WHERE key = 'schema_version'", + ).fetchone() + assert int(row["value"]) == 0 + class TestDbFile: def test_single_db_file_in_index_dir(self, store, tmp_path: Path) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert (tmp_path / DB_FILENAME).exists() def test_wal_mode_enabled(self, store) -> None: @@ -448,7 +627,26 @@ class TestDbFile: class TestMigrations: - """Tests for the schema migration machinery.""" + """Tests for the schema migration machinery. + + These tests exercise check_and_run_migrations()'s generic dispatch logic + (structural vs. re-embed, version-boundary stopping) using ad hoc test + migrations layered on top of SCHEMA_VERSION -- distinct from + TestV1ToV2Migration, which exercises the real, frozen m0001_v1_to_v2 + migration. Test migrations use version numbers starting at + SCHEMA_VERSION (2) and above so they never collide with the real + from_version=1/to_version=2 migration already registered in MIGRATIONS. + + The fake structural migrations' apply() fixtures (see + test_structural_migration_copies_rows_and_updates_version and + test_stop_at_reembed_boundary below) only populate the rebuilt vec0 + table itself -- they never insert into document_chunks/document_meta on + the destination connection. That's fine here: these tests exist to + verify the generic dispatch mechanism (version bookkeeping, structural- + vs-reembed branching), not full schema correctness of a rebuilt store; + the real migration's data completeness is covered separately by + TestV1ToV2Migration. + """ def _schema_version(self, store: PaperlessSqliteVecVectorStore) -> int | None: row = store.client.execute( @@ -457,21 +655,21 @@ class TestMigrations: return int(row[0]) if row else None def test_new_table_records_schema_version(self, store) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert self._schema_version(store) == SCHEMA_VERSION def test_check_migrations_no_table_returns_false(self, store) -> None: assert store.check_and_run_migrations() is False def test_check_migrations_current_version_returns_false(self, store) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert store.check_and_run_migrations() is False def test_reembed_migration_returns_true(self, store, tmp_path: Path) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) migration = Migration( - from_version=1, - to_version=2, + from_version=SCHEMA_VERSION, + to_version=SCHEMA_VERSION + 1, kind="re-embed", description="test re-embed", ) @@ -480,7 +678,7 @@ class TestMigrations: from paperless_ai import vector_store as vs_mod original = vs_mod.SCHEMA_VERSION - vs_mod.SCHEMA_VERSION = 2 + vs_mod.SCHEMA_VERSION = SCHEMA_VERSION + 1 result = store.check_and_run_migrations() finally: MIGRATIONS.remove(migration) @@ -492,7 +690,7 @@ class TestMigrations: store, tmp_path: Path, ) -> None: - store.add([make_node("a1", "1"), make_node("b1", "2")]) + store.add([make_node("a1", 1), make_node("b1", 2)]) def apply( src: sqlite3.Connection, @@ -511,7 +709,7 @@ class TestMigrations: (str(dim),), ) rows = src.execute( - "SELECT id, document_id, modified, node_content, embedding " + "SELECT id, document_id, node_content, embedding " f"FROM {DEFAULT_TABLE_NAME}", ).fetchall() dst.execute("BEGIN IMMEDIATE") @@ -522,8 +720,8 @@ class TestMigrations: [ ( r["id"], - r["document_id"], - r["modified"], + str(r["document_id"]), + "", r["node_content"], bytes(r["embedding"]), ) @@ -538,8 +736,8 @@ class TestMigrations: dst.execute("COMMIT") migration = Migration( - from_version=1, - to_version=2, + from_version=SCHEMA_VERSION, + to_version=SCHEMA_VERSION + 1, kind="structural", description="test structural", apply=apply, @@ -549,28 +747,29 @@ class TestMigrations: from paperless_ai import vector_store as vs_mod original = vs_mod.SCHEMA_VERSION - vs_mod.SCHEMA_VERSION = 2 + vs_mod.SCHEMA_VERSION = SCHEMA_VERSION + 1 result = store.check_and_run_migrations() finally: MIGRATIONS.remove(migration) vs_mod.SCHEMA_VERSION = original assert result is False - assert self._schema_version(store) == 2 + assert self._schema_version(store) == SCHEMA_VERSION + 1 ids = {n.node_id for n in store.get_nodes()} assert ids == {"a1", "b1"} def test_compact_preserves_schema_version(self, store) -> None: - store.add([make_node("a1", "1")]) + store.add([make_node("a1", 1)]) assert self._schema_version(store) == SCHEMA_VERSION store.compact(force=True) assert self._schema_version(store) == SCHEMA_VERSION def test_stop_at_reembed_boundary(self, store) -> None: - # Registry: structural v2, re-embed v3, structural v4. - # Only v2 should apply; the re-embed boundary must stop execution - # before v4 runs, and the stored version must stay at 2. - store.add([make_node("a1", "1"), make_node("b1", "2")]) + # Registry: structural v(N+1), re-embed v(N+2), structural v(N+3), + # where N = SCHEMA_VERSION. Only v(N+1) should apply; the re-embed + # boundary must stop execution before v(N+3) runs, and the stored + # version must stay at N+1. + store.add([make_node("a1", 1), make_node("b1", 2)]) def copy_apply( src: sqlite3.Connection, @@ -589,7 +788,7 @@ class TestMigrations: (str(dim),), ) rows = src.execute( - "SELECT id, document_id, modified, node_content, embedding " + "SELECT id, document_id, node_content, embedding " f"FROM {DEFAULT_TABLE_NAME}", ).fetchall() dst.execute("BEGIN IMMEDIATE") @@ -600,8 +799,8 @@ class TestMigrations: [ ( r["id"], - r["document_id"], - r["modified"], + str(r["document_id"]), + "", r["node_content"], bytes(r["embedding"]), ) @@ -612,23 +811,23 @@ class TestMigrations: migrations = [ Migration( - from_version=1, - to_version=2, + from_version=SCHEMA_VERSION, + to_version=SCHEMA_VERSION + 1, kind="structural", - description="v2 structural", + description="v(N+1) structural", apply=copy_apply, ), Migration( - from_version=2, - to_version=3, + from_version=SCHEMA_VERSION + 1, + to_version=SCHEMA_VERSION + 2, kind="re-embed", - description="v3 re-embed boundary", + description="v(N+2) re-embed boundary", ), Migration( - from_version=3, - to_version=4, + from_version=SCHEMA_VERSION + 2, + to_version=SCHEMA_VERSION + 3, kind="structural", - description="v4 structural - must not run", + description="v(N+3) structural - must not run", apply=copy_apply, ), ] @@ -637,7 +836,7 @@ class TestMigrations: from paperless_ai import vector_store as vs_mod original = vs_mod.SCHEMA_VERSION - vs_mod.SCHEMA_VERSION = 4 + vs_mod.SCHEMA_VERSION = SCHEMA_VERSION + 3 result = store.check_and_run_migrations() finally: for m in migrations: @@ -645,4 +844,226 @@ class TestMigrations: vs_mod.SCHEMA_VERSION = original assert result is True - assert self._schema_version(store) == 2 + assert self._schema_version(store) == SCHEMA_VERSION + 1 + + def test_has_pending_migration_false_when_no_table( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A vector store with no table created yet + WHEN: + - has_pending_migration() is checked + THEN: + - False is returned (nothing to migrate before anything exists) + """ + assert store.has_pending_migration() is False + + def test_has_pending_migration_false_at_current_version( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A store at the current SCHEMA_VERSION + WHEN: + - has_pending_migration() is checked + THEN: + - False is returned + """ + store.add([make_node("a1", 1)]) + assert store.has_pending_migration() is False + + def test_has_pending_migration_true_when_behind( + self, + store: PaperlessSqliteVecVectorStore, + ) -> None: + """ + GIVEN: + - A store whose schema_version has been forced behind SCHEMA_VERSION + WHEN: + - has_pending_migration() is checked + THEN: + - True is returned + """ + store.add([make_node("a1", 1)]) + store.client.execute( + "UPDATE index_meta SET value = '0' WHERE key = 'schema_version'", + ) + assert store.has_pending_migration() is True + + +class TestV1ToV2Migration: + """m0001_v1_to_v2 migrates a real, historically-shaped v1 store. The + fixture below is a literal, hardcoded v1 DDL string -- NOT derived from + any current code -- so this test keeps testing the actual historical + shape even if vector_store.py's "current" schema changes again later. + """ + + def _build_v1_store(self, db_path: str, dim: int) -> None: + conn = sqlite3.connect(db_path) + conn.row_factory = sqlite3.Row + conn.enable_load_extension(True) # noqa: FBT003 + sqlite_vec.load(conn) + conn.enable_load_extension(False) # noqa: FBT003 + conn.execute("PRAGMA journal_mode=WAL") + conn.execute("PRAGMA synchronous=NORMAL") + conn.execute( + "CREATE TABLE IF NOT EXISTS index_meta (key TEXT PRIMARY KEY, value TEXT)", + ) + conn.execute( # nosemgrep + "CREATE VIRTUAL TABLE documents USING vec0(" + "id TEXT PRIMARY KEY, document_id TEXT, modified TEXT," + f" +node_content TEXT, embedding float[{dim}] distance_metric=cosine" + ")", + ) + conn.execute( + "INSERT INTO index_meta (key, value) VALUES ('dim', ?)", + (str(dim),), + ) + conn.execute( + "INSERT INTO index_meta (key, value) VALUES ('schema_version', '1')", + ) + conn.execute( + "INSERT INTO index_meta (key, value) VALUES ('embed_model', 'model-a')", + ) + rows = [ + ("c1", "1", "2026-01-01T00:00:00", '{"text": "a"}', _pack([0.1] * dim)), + ("c2", "1", "2026-01-01T00:00:00", '{"text": "b"}', _pack([0.2] * dim)), + ("c3", "2", "2026-02-02T00:00:00", '{"text": "c"}', _pack([0.3] * dim)), + ] + conn.executemany( + "INSERT INTO documents (id, document_id, modified, node_content, embedding)" + " VALUES (?, ?, ?, ?, ?)", + rows, + ) + conn.execute( + "INSERT INTO index_meta (key, value) VALUES ('total_inserts', '3')", + ) + conn.commit() + conn.close() + + def test_migration_converts_v1_store_to_v2(self, tmp_path: Path) -> None: + """ + GIVEN: + - A real v1-shaped store (TEXT document_id, modified inline in + vec0, no document_chunks/document_meta) built from a literal, + hardcoded historical DDL + WHEN: + - A PaperlessSqliteVecVectorStore is opened against it + THEN: + - schema_version becomes 2, document_id values become int, + document_chunks/document_meta are backfilled once per chunk/ + document respectively, and dim/embed_model survive + """ + db_dir = tmp_path + self._build_v1_store(str(db_dir / DB_FILENAME), dim=16) + with PaperlessSqliteVecVectorStore(uri=str(db_dir)) as store: + assert store.check_and_run_migrations() is False + row = store.client.execute( + "SELECT value FROM index_meta WHERE key = 'schema_version'", + ).fetchone() + assert int(row["value"]) == 2 + doc_id_row = store.client.execute( + "SELECT document_id FROM documents WHERE id = 'c1'", + ).fetchone() + assert isinstance(doc_id_row["document_id"], int) + assert doc_id_row["document_id"] == 1 + chunk_ids = sorted( + r["chunk_id"] + for r in store.client.execute( + "SELECT chunk_id FROM document_chunks", + ).fetchall() + ) + assert chunk_ids == ["c1", "c2", "c3"] + assert store.get_modified_times() == { + "1": "2026-01-01T00:00:00", + "2": "2026-02-02T00:00:00", + } + assert store.stored_model_name() == "model-a" + assert store.vector_dim() == 16 + + def test_migration_raises_on_malformed_document_id( + self, + tmp_path: Path, + ) -> None: + """ + GIVEN: + - A v1-shaped store with a corrupted, non-integer document_id + value on one row + WHEN: + - The migration runs + THEN: + - A ValueError is raised (fail loudly, no silent data loss) -- + this matches the rest of vector_store.py, which has no + precedent for silently skipping malformed rows + """ + db_dir = tmp_path + self._build_v1_store(str(db_dir / DB_FILENAME), dim=16) + conn = sqlite3.connect(str(db_dir / DB_FILENAME)) + conn.enable_load_extension(True) # noqa: FBT003 + sqlite_vec.load(conn) + conn.enable_load_extension(False) # noqa: FBT003 + conn.execute( + "UPDATE documents SET document_id = 'not-an-int' WHERE id = 'c1'", + ) + conn.commit() + conn.close() + with ( + pytest.raises(ValueError), + PaperlessSqliteVecVectorStore(uri=str(db_dir)) as store, + ): + store.check_and_run_migrations() + + def test_migration_never_delegates_to_current_schema_helpers( + self, + tmp_path: Path, + mocker: MockerFixture, + ) -> None: + """ + GIVEN: + - A real v1-shaped store + WHEN: + - The migration runs, with DocumentChunksTable.create/ + DocumentMetaTable.create/_create_vec_table spied on + THEN: + - None of those "current schema" helpers are ever called during + the migration -- it must freeze its own historical DDL, per + the DDL-freezing rule (see spec), so a future schema bump + can't silently corrupt this migration's output + """ + db_dir = tmp_path + self._build_v1_store(str(db_dir / DB_FILENAME), dim=16) + chunks_create_spy = mocker.spy(DocumentChunksTable, "create") + meta_create_spy = mocker.spy(DocumentMetaTable, "create") + vec_table_spy = mocker.spy( + PaperlessSqliteVecVectorStore, + "_create_vec_table", + ) + with PaperlessSqliteVecVectorStore(uri=str(db_dir)) as store: + store.check_and_run_migrations() + # _open_connection() legitimately calls create() three times across + # a structural migration: once for the store's own live connection + # (construction), once for the migration's temp rebuild file + # (_rebuild_file), and once more when _swap_in_compact() reopens the + # swapped-in file as self._conn. What matters is that + # m0001_v1_to_v2's apply() itself never calls these directly, which + # a source-text check alone can't prove (it can't tell "mentioned in + # a comment" from "actually called", and is trivially evadable by + # importing a symbol under an alias). Asserting the exact call count + # instead: exactly 3 calls to each create() (all from + # _open_connection, never a 4th from inside apply()), and zero calls + # to _create_vec_table (neither _open_connection nor apply() calls + # it -- apply() freezes its own literal CREATE VIRTUAL TABLE DDL + # instead). + assert chunks_create_spy.call_count == 3 + assert meta_create_spy.call_count == 3 + assert vec_table_spy.call_count == 0 + # Cheap secondary signal, kept alongside the spy assertions above + # (not in place of them): the migration module's source should never + # even mention these "current schema" helpers by name. + source = inspect.getsource(m0001_v1_to_v2) + assert "DocumentChunksTable.create" not in source + assert "DocumentMetaTable.create" not in source + assert "_create_vec_table(" not in source diff --git a/src/paperless_ai/vector_store.py b/src/paperless_ai/vector_store.py index f6f333576..b7de0936d 100644 --- a/src/paperless_ai/vector_store.py +++ b/src/paperless_ai/vector_store.py @@ -2,16 +2,13 @@ import json import logging import sqlite3 import struct -from collections.abc import Callable from collections.abc import Iterator from collections.abc import Sequence from contextlib import contextmanager -from dataclasses import dataclass -from dataclasses import field from pathlib import Path from types import TracebackType from typing import Any -from typing import Literal +from typing import NamedTuple import sqlite_vec from llama_index.core.bridge.pydantic import PrivateAttr @@ -26,6 +23,14 @@ from llama_index.core.vector_stores.types import VectorStoreQueryResult from llama_index.core.vector_stores.utils import metadata_dict_to_node from llama_index.core.vector_stores.utils import node_to_metadata_dict +from paperless_ai.migrations import MIGRATIONS +from paperless_ai.migrations import Migration +from paperless_ai.tables import ChunkRow +from paperless_ai.tables import DocumentChunksTable +from paperless_ai.tables import DocumentMetaRow +from paperless_ai.tables import DocumentMetaTable +from paperless_ai.tables import IndexMetaTable + logger = logging.getLogger("paperless_ai.vector_store") DB_FILENAME = "llmindex.db" @@ -34,7 +39,7 @@ DEFAULT_TABLE_NAME = "documents" # Current schema version. Written to index_meta at table creation and bumped # whenever a Migration is added to MIGRATIONS. check_and_run_migrations() uses # this to decide which migrations to run on an existing store. -SCHEMA_VERSION = 1 +SCHEMA_VERSION = 2 # compact(): rebuild when the cumulative rowid count exceeds this multiple of # the live row count. DELETEs on vec0 tables never reclaim space (upstream @@ -42,47 +47,43 @@ SCHEMA_VERSION = 1 # a rebuild copies the live rows into a fresh table. COMPACT_BLOAT_RATIO = 2.0 -# compact(): number of rows copied per executemany() when rebuilding the file. -# Rows are streamed from the source cursor in batches of this size rather than -# materialized all at once, keeping memory bounded regardless of index size. -COMPACT_BATCH_SIZE = 500 +# Number of rows fetched/copied per batch whenever this module streams rows +# instead of materializing them all at once, keeping memory bounded regardless +# of index size -- used by compact()'s rebuild, m0001_v1_to_v2's migration +# copy, and DocumentMetaTable.copy_all(). No longer compact()-specific, hence +# the plain name. +BATCH_SIZE = 500 # Filterable vec0 metadata columns. _build_where() only ever receives filter # keys we construct ourselves, but allowlisting keeps SQL identifiers safe by -# construction. -_FILTER_COLUMNS = frozenset({"document_id", "modified"}) +# construction. "modified" is not here: it is never filtered on, and as of +# schema v2 it isn't even a vec0 column anymore (see document_meta). +_FILTER_COLUMNS = frozenset({"document_id"}) -@dataclass -class Migration: - """A schema migration for the sqlite-vec vector store. - - kind="structural": rows are copied into a new-schema file with no - re-embedding needed. Supply ``apply(src_conn, dst_conn, dim)`` which - must create the vec0 table in ``dst_conn``, copy all rows from - ``src_conn``, and write ``dim`` / ``embed_model`` / ``total_inserts`` to - ``dst_conn``'s ``index_meta``. ``schema_version`` is written by the - migration runner after ``apply`` returns. - - kind="re-embed": the new schema requires fresh embeddings. - ``check_and_run_migrations()`` returns True when it encounters one of - these so the caller can force a full rebuild (which recreates the table - at the current SCHEMA_VERSION). +class _Row(NamedTuple): + """One node, ready to write. ``modified`` is not a vec0 column (see + document_meta) -- it rides along here because every row-producing call + site needs both the vec0 insert values and the document_meta upsert + value from the same node. """ - from_version: int - to_version: int - kind: Literal["structural", "re-embed"] - description: str - apply: Callable[[sqlite3.Connection, sqlite3.Connection, int], None] | None = field( - default=None, - repr=False, - ) + chunk_id: str + document_id: int + modified: str + node_content: str + embedding: bytes -# Registry of all schema migrations in order. Empty at v1 -- this is the -# baseline. Add entries here (and bump SCHEMA_VERSION) when the schema changes. -MIGRATIONS: list[Migration] = [] +# _build_where(): the largest IN value list translated into bound SQL +# parameters. SQLite's own hard limit (SQLITE_MAX_VARIABLE_NUMBER) is 32766 +# by default; this leaves headroom below that for the query's other bound +# parameters (the embedding blob, k, and any NE clause) and for the limit +# itself to move. An IN filter this large should not happen in practice -- +# callers are expected to pass None (no filter) rather than every id when +# the filter would not actually narrow anything -- so this is a guard +# against a future regression, not a normal code path. +_MAX_IN_VALUES = 32700 def _pack(embedding: Sequence[float]) -> bytes: @@ -93,14 +94,30 @@ def _unpack(blob: bytes) -> list[float]: return list(struct.unpack(f"{len(blob) // 4}f", blob)) -def _build_where(filters: MetadataFilters | None) -> tuple[str, list[str]]: - """Translate the EQ / IN / NE filters we use into a parameterized SQL clause - on vec0 metadata columns. Returns ("", []) when there is nothing to filter. +_INSERT = ( + "INSERT INTO " + + DEFAULT_TABLE_NAME + + " (id, document_id, node_content, embedding) VALUES (?, ?, ?, ?)" +) + + +def _vec0_params(rows: list[_Row]) -> list[tuple[str, int, str, bytes]]: + """``rows``, minus the ``modified`` field vec0 no longer stores.""" + return [(r.chunk_id, r.document_id, r.node_content, r.embedding) for r in rows] + + +def _build_where(filters: MetadataFilters | None) -> tuple[str, list[int]]: + """Translate the EQ / IN / NE filters we use into a parameterized SQL + clause on vec0 metadata columns. Returns ("", []) when there is nothing + to filter. document_id is vec0's only filterable column and is INTEGER; + every value is coerced via int() here so callers (which today still pass + strings in places, e.g. indexing.py's MetadataFilter construction) don't + have to be individually correct -- vec0 doesn't coerce types itself. """ if filters is None or not filters.filters: return "", [] clauses: list[str] = [] - params: list[str] = [] + params: list[int] = [] for f in filters.filters: # filters.filters is Union[MetadataFilter, ExactMatchFilter, MetadataFilters]; # we only build MetadataFilter entries, so skip anything else at runtime. @@ -109,19 +126,34 @@ def _build_where(filters: MetadataFilters | None) -> tuple[str, list[str]]: if f.key not in _FILTER_COLUMNS: # pragma: no cover - we build the keys raise NotImplementedError(f"Unsupported filter column: {f.key}") if f.operator == FilterOperator.IN: - values = [str(v) for v in f.value] # type: ignore[union-attr] # value is list when operator is IN + values = [int(v) for v in f.value] # type: ignore[union-attr] if not values: # pragma: no cover clauses.append("1 = 0") continue + if len(values) > _MAX_IN_VALUES: + # Fail closed (see the empty-clauses case below) rather than + # let SQLite raise "too many SQL variables" past its own + # limit: this filter scopes document access, so an IN list + # too large to safely bind must match no rows, never widen + # the scope to "everything" by accident. + logger.warning( + "Refusing to build an IN filter on %r with %d values " + "(over the %d-value safety limit); returning no rows.", + f.key, + len(values), + _MAX_IN_VALUES, + ) + clauses.append("1 = 0") + continue placeholders = ",".join("?" for _ in values) clauses.append(f"{f.key} IN ({placeholders})") params.extend(values) elif f.operator == FilterOperator.EQ: clauses.append(f"{f.key} = ?") - params.append(str(f.value)) + params.append(int(f.value)) elif f.operator == FilterOperator.NE: clauses.append(f"{f.key} != ?") - params.append(str(f.value)) + params.append(int(f.value)) else: # pragma: no cover - we only ever build EQ/IN/NE filters raise NotImplementedError(f"Unsupported filter operator: {f.operator}") if not clauses: @@ -186,9 +218,21 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): conn.enable_load_extension(False) # noqa: FBT003 conn.execute("PRAGMA journal_mode=WAL") conn.execute("PRAGMA synchronous=NORMAL") - conn.execute( - "CREATE TABLE IF NOT EXISTS index_meta (key TEXT PRIMARY KEY, value TEXT)", - ) + IndexMetaTable.create(conn) + # vec0 metadata columns only get an efficient lookup path inside a + # KNN (MATCH) query; a plain `WHERE document_id = ?` is a full table + # scan regardless of index size. This plain, indexed table is how + # delete()/upsert_document() find a document's chunk ids without + # that scan. + DocumentChunksTable.create(conn) + # modified used to be a vec0 metadata column, but vec0 only inlines + # TEXT metadata up to 12 bytes -- an ISO timestamp is always longer, + # so every read recompiled and stepped a fresh SQL statement per row. + # It was never filtered on inside a KNN query either, so it never + # needed to be a vec0 column at all. One row per document here (not + # per chunk, like document_chunks), since every chunk of a document + # shares the same modified value -- see get_modified_times(). + DocumentMetaTable.create(conn) return conn @property @@ -223,24 +267,6 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): else: self._conn.execute("COMMIT") - def _meta_get(self, key: str) -> str | None: - row = self._conn.execute( - "SELECT value FROM index_meta WHERE key = ?", - (key,), - ).fetchone() - return row["value"] if row else None - - @staticmethod - def _meta_set_on(conn: sqlite3.Connection, key: str, value: str) -> None: - conn.execute( - "INSERT INTO index_meta (key, value) VALUES (?, ?) " - "ON CONFLICT(key) DO UPDATE SET value = excluded.value", - (key, value), - ) - - def _meta_set(self, key: str, value: str) -> None: - self._meta_set_on(self._conn, key, value) - def table_exists(self) -> bool: return ( self._conn.execute( @@ -253,18 +279,19 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): def vector_dim(self) -> int | None: if not self.table_exists(): return None - value = self._meta_get("dim") - return int(value) if value else None + return IndexMetaTable.get_dim(self._conn) def drop_table(self) -> None: self._conn.execute("DROP TABLE IF EXISTS " + DEFAULT_TABLE_NAME) self._conn.execute("DELETE FROM index_meta") + DocumentChunksTable.delete_all(self._conn) + DocumentMetaTable.delete_all(self._conn) def stored_model_name(self) -> str | None: """Return the embedding model name recorded at table creation, or None.""" if not self.table_exists(): return None - return self._meta_get("embed_model") + return IndexMetaTable.get_embed_model(self._conn) def config_mismatch(self, model_name: str) -> bool: """True when the stored model name differs from ``model_name``. @@ -282,14 +309,17 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): # document_id is deliberately a metadata column, NOT a partition key: # partition keys change KNN `k` to per-partition semantics under IN # filters (asg017/sqlite-vec#142); metadata columns give a correct - # global top-k. + # global top-k. INTEGER (not TEXT, as in schema v1): EQ/NE/IN + # comparisons become a native i64 array compare instead of per-row + # strncmp against a 16-byte text view, and this drops the unused + # metadatatext shadow table TEXT columns carry. modified is not a + # column here at all as of v2 -- see document_meta. conn.execute( # nosemgrep: python.sqlalchemy.security.sqlalchemy-execute-raw-query.sqlalchemy-execute-raw-query "CREATE VIRTUAL TABLE " + DEFAULT_TABLE_NAME + " USING vec0(" + "id TEXT PRIMARY KEY," - + " document_id TEXT," - + " modified TEXT," + + " document_id INTEGER," + " +node_content TEXT," + " embedding float[" + str(int(dim)) @@ -299,37 +329,78 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): def _create_table(self, dim: int) -> None: self._create_vec_table(self._conn, dim) - self._meta_set("dim", str(dim)) - self._meta_set("schema_version", str(SCHEMA_VERSION)) + IndexMetaTable.set_dim(self._conn, dim) + IndexMetaTable.set_schema_version(self._conn, SCHEMA_VERSION) if self._embed_model_name: - self._meta_set("embed_model", self._embed_model_name) + IndexMetaTable.set_embed_model(self._conn, self._embed_model_name) - def _ensure_table(self, dim: int) -> None: - if not self.table_exists(): + def _ensure_table(self, dim: int, *, table_exists: bool) -> None: + if not table_exists: self._create_table(dim) - def _row(self, node: BaseNode) -> tuple[str, str, str, str, bytes]: + def _row(self, node: BaseNode) -> _Row: meta = node_to_metadata_dict( node, remove_text=False, flat_metadata=self.flat_metadata, ) - # vec0 metadata columns reject NULL (asg017/sqlite-vec#141): coerce - # every value to a string, with "" as the absent sentinel. document_id = node.ref_doc_id or node.metadata.get("document_id") - return ( - node.node_id, - str(document_id or ""), - str(node.metadata.get("modified") or ""), - json.dumps(meta), - _pack(node.get_embedding()), + return _Row( + chunk_id=node.node_id, + # document_id is required -- int(None) raises TypeError and + # int("not-a-number") raises ValueError, both intentional: + # fail loudly on a malformed/missing document_id rather than + # silently indexing a chunk with no owning document. modified, + # below, still uses the str(x or "") sentinel pattern because a + # missing modified value is legitimate (vec0 no longer even + # stores it -- see document_meta), whereas document_id must + # always be present. + document_id=int(document_id), + modified=str(node.metadata.get("modified") or ""), + node_content=json.dumps(meta), + embedding=_pack(node.get_embedding()), ) - _INSERT = ( - "INSERT INTO " - + DEFAULT_TABLE_NAME - + " (id, document_id, modified, node_content, embedding) VALUES (?, ?, ?, ?, ?)" - ) + def _index_chunks(self, rows: list[_Row]) -> None: + """Record each row's (chunk_id, document_id) in document_chunks, and + each row's (document_id, modified) in document_meta -- deduped + within the batch, since every chunk of a document shares the same + modified value -- kept in lockstep with every insert into the vec0 + table. + """ + DocumentChunksTable.insert_many( + self._conn, + (ChunkRow(r.chunk_id, r.document_id) for r in rows), + ) + modified_by_document = {r.document_id: r.modified for r in rows} + DocumentMetaTable.upsert_many( + self._conn, + ( + DocumentMetaRow(doc_id, mod) + for doc_id, mod in modified_by_document.items() + ), + ) + + def _delete_chunks_by_document_id(self, document_id: int) -> None: + """Delete all of a document's chunks via point-deletes on `id`. + + vec0 has no efficient lookup on the document_id metadata column + outside a KNN query, so a plain `DELETE ... WHERE document_id = ?` + is a full table scan regardless of index size. Looking the chunk + ids up in document_chunks first (a real indexed lookup) and + deleting each by its `id` primary key instead turns that scan into + a handful of O(1) point deletes. + """ + chunk_ids = DocumentChunksTable.chunk_ids_for_document( + self._conn, + document_id, + ) + self._conn.executemany( + "DELETE FROM " + DEFAULT_TABLE_NAME + " WHERE id = ?", + [(chunk_id,) for chunk_id in chunk_ids], + ) + DocumentChunksTable.delete_for_document(self._conn, document_id) + DocumentMetaTable.delete_for_document(self._conn, document_id) def _increment_total_inserts(self, count: int) -> None: """Increment the cumulative insert counter stored in index_meta. @@ -339,48 +410,56 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): live_rows exceeds COMPACT_BLOAT_RATIO the table has accumulated enough deleted-but-not-freed rows to warrant a rebuild. """ - current = int(self._meta_get("total_inserts") or "0") - self._meta_set("total_inserts", str(current + count)) + IndexMetaTable.increment_total_inserts(self._conn, count) def add(self, nodes: Sequence[BaseNode], **add_kwargs: Any) -> list[str]: if not nodes: return [] rows = [self._row(node) for node in nodes] with self._transaction(): - self._ensure_table(len(nodes[0].get_embedding())) - self._conn.executemany(self._INSERT, rows) + self._ensure_table( + len(nodes[0].get_embedding()), + table_exists=self.table_exists(), + ) + self._conn.executemany(_INSERT, _vec0_params(rows)) + self._index_chunks(rows) self._increment_total_inserts(len(rows)) return [node.node_id for node in nodes] - def upsert_document(self, document_id: str, nodes: list[BaseNode]) -> list[str]: + def upsert_document( + self, + document_id: int | str, + nodes: list[BaseNode], + ) -> list[str]: """Atomically replace all stored chunks of ``document_id`` with ``nodes``. One transaction deletes the document's existing rows and inserts the - new set (vec0's INSERT OR REPLACE is broken upstream, #259, so - delete+insert it is). WAL readers in other processes see either the - old or the new chunk set, never a partial state. + new set (vec0's INSERT OR REPLACE is broken upstream, so delete+insert + it is). WAL readers in other processes see either the old or the new + chunk set, never a partial state. """ + doc_id = int(document_id) rows = [self._row(node) for node in nodes] with self._transaction(): - if nodes: - self._ensure_table(len(nodes[0].get_embedding())) - if self.table_exists(): - self._conn.execute( - "DELETE FROM " + DEFAULT_TABLE_NAME + " WHERE document_id = ?", - (str(document_id),), + table_exists = self.table_exists() + if nodes and not table_exists: + self._ensure_table( + len(nodes[0].get_embedding()), + table_exists=False, ) + table_exists = True + if table_exists: + self._delete_chunks_by_document_id(doc_id) if rows: - self._conn.executemany(self._INSERT, rows) + self._conn.executemany(_INSERT, _vec0_params(rows)) + self._index_chunks(rows) self._increment_total_inserts(len(rows)) return [node.node_id for node in nodes] - def delete(self, ref_doc_id: str, **delete_kwargs: Any) -> None: + def delete(self, ref_doc_id: int | str, **delete_kwargs: Any) -> None: if self.table_exists(): with self._transaction(): - self._conn.execute( - "DELETE FROM " + DEFAULT_TABLE_NAME + " WHERE document_id = ?", - (str(ref_doc_id),), - ) + self._delete_chunks_by_document_id(int(ref_doc_id)) def _rows_to_nodes(self, rows: list[sqlite3.Row]) -> list[BaseNode]: nodes: list[BaseNode] = [] @@ -450,41 +529,66 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): def get_modified_times(self) -> dict[str, str]: """Return {document_id: stored_modified_isoformat} for all indexed documents. - All chunks of a document share the same ``modified`` value, so the - first row seen per document is sufficient. + document_meta already has exactly one row per document (not per + chunk, unlike the vec0 table), so no dedup is needed here. """ if not self.table_exists(): return {} - result: dict[str, str] = {} - for row in self._conn.execute( - "SELECT document_id, modified FROM " + DEFAULT_TABLE_NAME, - ): - doc_id = str(row["document_id"]) - if doc_id not in result: - result[doc_id] = str(row["modified"] or "") - return result + return DocumentMetaTable.all_modified_times(self._conn) + + @property + def _db_path(self) -> str: + return str(Path(self._uri) / DB_FILENAME) + + @contextmanager + def _rebuild_file(self) -> Iterator[sqlite3.Connection]: + """Open a fresh temp database file for a file-swap rebuild (compact + or structural migration), yielding its connection for the caller to + populate. + + On success, swaps the temp file in as the live database (closing + this store's current connection first -- see _swap_in_compact()). + On any exception, discards the temp file, including its -wal/-shm, + instead, and this store's own connection is left untouched. + """ + compact_path = self._db_path + ".compact" + new_conn = self._open_connection(compact_path) + try: + yield new_conn + except BaseException: + new_conn.close() + for suffix in ["", "-wal", "-shm"]: + Path(compact_path + suffix).unlink(missing_ok=True) + raise + else: + new_conn.close() + self._swap_in_compact(compact_path, self._db_path) def compact(self, *, force: bool = False) -> None: """Rebuild the database file to reclaim space left behind by DELETEs. vec0 DELETE only invalidates rows; the vector data stays in the file - forever (asg017/sqlite-vec#54), and per-document re-indexing is a - delete+insert. The cumulative insert counter in ``index_meta`` tracks - total rows ever written; when that exceeds ``COMPACT_BLOAT_RATIO`` x - the live row count (or when forced), live rows are copied into a fresh - database file and swapped in via ``os.replace``. + forever, and per-document re-indexing is a delete+insert. The + cumulative insert counter in ``index_meta`` tracks total rows ever + written; when that exceeds ``COMPACT_BLOAT_RATIO`` x the live row + count (or when forced), live rows are copied into a fresh database + file and swapped in via ``os.replace``. Note: ``ALTER TABLE ... RENAME TO`` on vec0 virtual tables does NOT - rename the shadow tables (sqlite-vec upstream limitation), so - an in-place rename-based rebuild is not safe. The file-swap approach - is the maintainer-endorsed workaround (asg017/sqlite-vec#205). + rename the shadow tables (sqlite-vec upstream limitation), so an + in-place rename-based rebuild is not safe. The file-swap approach is + the maintainer-endorsed workaround. """ if not self.table_exists(): return - live = self._conn.execute( - "SELECT count(*) FROM " + DEFAULT_TABLE_NAME, - ).fetchone()[0] - total = int(self._meta_get("total_inserts") or str(live)) + if self.has_pending_migration(): + logger.warning( + "Skipping compact: store has a pending schema migration; " + "run check_and_run_migrations() first", + ) + return + live = DocumentChunksTable.count(self._conn) + total = IndexMetaTable.get_total_inserts(self._conn) or live if not force and total <= max(live, 1) * COMPACT_BLOAT_RATIO: return dim = self.vector_dim() @@ -496,50 +600,61 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): live, total, ) - db_path = str(Path(self._uri) / DB_FILENAME) - compact_path = db_path + ".compact" + with self._rebuild_file() as new_conn: + self._rebuild_into(self._conn, new_conn, dim) - # Copy all live rows into a fresh database file. - new_conn = self._open_connection(compact_path) - try: - self._create_vec_table(new_conn, dim) - self._meta_set_on(new_conn, "dim", str(dim)) - for key in ("embed_model", "schema_version"): - value = self._meta_get(key) - if value is not None: - self._meta_set_on(new_conn, key, value) - src_cursor = self._conn.execute( - "SELECT id, document_id, modified, node_content, embedding " - "FROM " + DEFAULT_TABLE_NAME, + @staticmethod + def _rebuild_into( + src_conn: sqlite3.Connection, + dst_conn: sqlite3.Connection, + dim: int, + ) -> None: + """Create the vec0 table in ``dst_conn``, copy dim/embed_model from + ``src_conn``, and stream every live vec0 row, document_chunks row, + and document_meta row across. Used by compact() only -- + m0001_v1_to_v2 freezes its own copy loop instead of calling this, + since this always reflects the *current* schema (see the migration + DDL-freezing rule in the spec). + """ + PaperlessSqliteVecVectorStore._create_vec_table(dst_conn, dim) + dim_value = IndexMetaTable.get_dim(src_conn) + if dim_value is not None: + IndexMetaTable.set_dim(dst_conn, dim_value) + embed_model = IndexMetaTable.get_embed_model(src_conn) + if embed_model is not None: + IndexMetaTable.set_embed_model(dst_conn, embed_model) + schema_version = IndexMetaTable.get_schema_version(src_conn) + if schema_version is not None: + IndexMetaTable.set_schema_version(dst_conn, schema_version) + + dst_conn.execute("BEGIN IMMEDIATE") + src_cursor = src_conn.execute( + "SELECT id, document_id, node_content, embedding FROM " + + DEFAULT_TABLE_NAME, + ) + copied = 0 + while batch := src_cursor.fetchmany(BATCH_SIZE): + dst_conn.executemany( + _INSERT, + [ + ( + r["id"], + r["document_id"], + r["node_content"], + bytes(r["embedding"]), + ) + for r in batch + ], ) - new_conn.execute("BEGIN IMMEDIATE") - # Stream rows from the source cursor in batches instead of - # materializing the whole table in memory, so a large index does - # not cause an OOM during routine maintenance compactions. - while batch := src_cursor.fetchmany(COMPACT_BATCH_SIZE): - new_conn.executemany( - self._INSERT, - [ - ( - r["id"], - r["document_id"], - r["modified"], - r["node_content"], - bytes(r["embedding"]), - ) - for r in batch - ], - ) - # Reset the cumulative counter: after compact, total_inserts == live. - self._meta_set_on(new_conn, "total_inserts", str(live)) - new_conn.execute("COMMIT") - except BaseException: - new_conn.close() - for p in [compact_path, compact_path + "-wal", compact_path + "-shm"]: - Path(p).unlink(missing_ok=True) - raise - new_conn.close() - self._swap_in_compact(compact_path, db_path) + DocumentChunksTable.insert_many( + dst_conn, + (ChunkRow(r["id"], r["document_id"]) for r in batch), + ) + copied += len(batch) + DocumentMetaTable.copy_all(src_conn, dst_conn, BATCH_SIZE) + # Reset the cumulative counter: after a rebuild, total_inserts == live. + IndexMetaTable.reset_total_inserts(dst_conn, copied) + dst_conn.execute("COMMIT") def _swap_in_compact(self, compact_path: str, db_path: str) -> None: """Atomically replace the live database with the compacted copy.""" @@ -551,6 +666,31 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): Path(compact_path).replace(db_path) self._conn = self._open_connection(db_path) + def _stored_schema_version(self) -> int | None: + """The schema_version recorded in index_meta, or None if no table + exists. A missing key (a store predating version tracking) is + treated as SCHEMA_VERSION -- i.e. already current -- since no + migration in MIGRATIONS targets a version before tracking began. + """ + if not self.table_exists(): + return None + raw_version = IndexMetaTable.get_schema_version(self._conn) + return raw_version if raw_version is not None else SCHEMA_VERSION + + def has_pending_migration(self) -> bool: + """Cheaply check whether a migration is pending, with no exclusive + access needed -- just a metadata read under the connection callers + already hold via the write FileLock. + + Callers should only pay for check_and_run_migrations()'s exclusive + access (a structural migration's file swap must not run while + readers are active) when this returns True, so that the common + case -- already at SCHEMA_VERSION -- never contends with readers + or a concurrent compaction. + """ + current = self._stored_schema_version() + return current is not None and current < SCHEMA_VERSION + def check_and_run_migrations(self) -> bool: """Apply any pending schema migrations to the store. @@ -559,15 +699,13 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): this method returns True when one is encountered so the caller can force a full rebuild (which recreates the table at SCHEMA_VERSION). - Must be called under the write FileLock. No-op when the table does - not exist or is already at SCHEMA_VERSION. + Must be called under the write FileLock, with readers excluded (see + has_pending_migration() for a cheap pre-check that avoids paying for + that exclusion in the common case). No-op when the table does not + exist or is already at SCHEMA_VERSION. """ - if not self.table_exists(): - return False - - raw = self._meta_get("schema_version") - current = int(raw) if raw is not None else SCHEMA_VERSION - if current >= SCHEMA_VERSION: + current = self._stored_schema_version() + if current is None or current >= SCHEMA_VERSION: return False pending = sorted( @@ -579,7 +717,7 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): if migration.kind == "re-embed": logger.warning( "LLM index schema v%d -> v%d requires re-embedding (%s); " - "forcing full rebuild.", + "the caller must force a rebuild.", migration.from_version, migration.to_version, migration.description, @@ -601,16 +739,12 @@ class PaperlessSqliteVecVectorStore(BasePydanticVectorStore): dim = self.vector_dim() if dim is None: # pragma: no cover raise RuntimeError("Cannot migrate: no stored vector dimension") - db_path = str(Path(self._uri) / DB_FILENAME) - compact_path = db_path + ".compact" - new_conn = self._open_connection(compact_path) - try: + with self._rebuild_file() as new_conn: migration.apply(self._conn, new_conn, dim) - self._meta_set_on(new_conn, "schema_version", str(migration.to_version)) - except BaseException: # pragma: no cover - new_conn.close() - for p in [compact_path, compact_path + "-wal", compact_path + "-shm"]: - Path(p).unlink(missing_ok=True) - raise - new_conn.close() - self._swap_in_compact(compact_path, db_path) + IndexMetaTable.set_schema_version(new_conn, migration.to_version) + + +# Registers m0001_v1_to_v2 into MIGRATIONS; must be at the bottom (needs +# PaperlessSqliteVecVectorStore fully defined) -- see +# paperless_ai/migrations/__init__.py for the full procedure. +from paperless_ai.migrations import m0001_v1_to_v2 # noqa: E402, F401 diff --git a/uv.lock b/uv.lock index 65317c7a2..30db974d4 100644 --- a/uv.lock +++ b/uv.lock @@ -3735,15 +3735,15 @@ crypto = [ [[package]] name = "pymdown-extensions" -version = "10.21.3" +version = "11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, { name = "pyyaml", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140, upload-time = "2026-05-13T12:57:32.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/47/67/f1e79672a5f91985577c7984c9709ca110e4fd37fe7fd167b60422e6ccc2/pymdown_extensions-11.0.tar.gz", hash = "sha256:8269cef0247f9e2d0a62fcea10860aba05c1cbab5470fd4b63230b96434dc589", size = 857049, upload-time = "2026-06-23T02:27:45.146Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002, upload-time = "2026-05-13T12:57:30.296Z" }, + { url = "https://files.pythonhosted.org/packages/af/b6/1ae53367e28b9cffa3be7574e13fbe4589694272fd47710fbdbafd3d63c6/pymdown_extensions-11.0-py3-none-any.whl", hash = "sha256:fbc4acb641814fa9d17521bbd21a5240ef739a662f11c06330c4b78c93e954d6", size = 269415, upload-time = "2026-06-23T02:27:43.826Z" }, ] [[package]]