Compare commits

..
Author SHA1 Message Date
shamoon 46e0f189dd ID copy shouod be a button 2026-10-18 22:37:26 -07:00
shamoon 31a801135e Fix checksum wrap, make it a badge 2026-10-18 22:34:18 -07:00
shamoon 569205bfbb Remove silly dupe permissions title 2026-10-18 22:33:21 -07:00
shamoon 3ffbc09b45 Fix send aria 2026-10-18 22:27:10 -07:00
shamoon 4a0a7ccee7 Fix undefined title thjing 2026-10-18 22:26:46 -07:00
shamoon 9eb6619c7a Move CF button 2026-10-18 22:12:12 -07:00
shamoon a28642a1eb We got oodles of space 2026-10-18 22:12:12 -07:00
shamoon 55934aea2b Move the pngx viewer page and zoom controls to floating over pdf 2026-10-18 21:40:40 -07:00
13 changed files with 218 additions and 158 deletions

No files matched your search

+63 -63
View File
@@ -259,15 +259,15 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">65</context>
<context context-type="linenumber">63</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">68</context>
<context context-type="linenumber">66</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">71</context>
<context context-type="linenumber">69</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/upload-file-widget/upload-file-widget.component.html</context>
@@ -351,19 +351,19 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">153</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/share-links/share-link-bundle-list/share-link-bundle-list.component.html</context>
@@ -882,19 +882,19 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">54</context>
<context context-type="linenumber">52</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">54</context>
<context context-type="linenumber">52</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">54</context>
<context context-type="linenumber">52</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">54</context>
<context context-type="linenumber">52</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
@@ -2271,19 +2271,19 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">40,41</context>
<context context-type="linenumber">38,39</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">40,41</context>
<context context-type="linenumber">38,39</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">40,41</context>
<context context-type="linenumber">38,39</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">40,41</context>
<context context-type="linenumber">38,39</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
@@ -2399,35 +2399,35 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">46,47</context>
<context context-type="linenumber">44,45</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">46,47</context>
<context context-type="linenumber">44,45</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">46,47</context>
<context context-type="linenumber">44,45</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">46,47</context>
<context context-type="linenumber">44,45</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">118</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
@@ -2987,35 +2987,35 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">123,124</context>
<context context-type="linenumber">121,122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">123,124</context>
<context context-type="linenumber">121,122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">123,124</context>
<context context-type="linenumber">121,122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">123,124</context>
<context context-type="linenumber">121,122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">142</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.ts</context>
@@ -3290,35 +3290,35 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">122,123</context>
<context context-type="linenumber">120,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">122,123</context>
<context context-type="linenumber">120,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">122,123</context>
<context context-type="linenumber">120,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">122,123</context>
<context context-type="linenumber">120,121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">139</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/mail/mail.component.html</context>
@@ -3784,7 +3784,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">125</context>
<context context-type="linenumber">123</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-detail/document-detail.component.html</context>
@@ -3997,7 +3997,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">103</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
@@ -8120,7 +8120,7 @@
<source>Filter by correspondent</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">75</context>
<context context-type="linenumber">73</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
@@ -8135,7 +8135,7 @@
<source>Filter by document type</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">85</context>
<context context-type="linenumber">83</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
@@ -8150,7 +8150,7 @@
<source>Filter by storage path</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">90</context>
<context context-type="linenumber">88</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-card-large/document-card-large.component.html</context>
@@ -8165,14 +8165,14 @@
<source>Filter by owner</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">95</context>
<context context-type="linenumber">93</context>
</context-group>
</trans-unit>
<trans-unit id="3542042671420335679" datatype="html">
<source>No</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">105</context>
<context context-type="linenumber">103</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/document-list/document-list.component.html</context>
@@ -8183,7 +8183,7 @@
<source>No documents</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
<context context-type="linenumber">189,192</context>
<context context-type="linenumber">187,190</context>
</context-group>
</trans-unit>
<trans-unit id="1069523139277190436" datatype="html">
@@ -10528,19 +10528,19 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">131,132</context>
<context context-type="linenumber">129,130</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">131,132</context>
<context context-type="linenumber">129,130</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">131,132</context>
<context context-type="linenumber">129,130</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">131,132</context>
<context context-type="linenumber">129,130</context>
</context-group>
</trans-unit>
<trans-unit id="651372623796033489" datatype="html">
@@ -10718,57 +10718,57 @@
<source>Matching</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">41,42</context>
<context context-type="linenumber">39,40</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">41,42</context>
<context context-type="linenumber">39,40</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">41,42</context>
<context context-type="linenumber">39,40</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">41,42</context>
<context context-type="linenumber">39,40</context>
</context-group>
</trans-unit>
<trans-unit id="1488347670280290838" datatype="html">
<source>Document count</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">42,43</context>
<context context-type="linenumber">40,41</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">42,43</context>
<context context-type="linenumber">40,41</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">42,43</context>
<context context-type="linenumber">40,41</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">42,43</context>
<context context-type="linenumber">40,41</context>
</context-group>
</trans-unit>
<trans-unit id="8095412801504464756" datatype="html">
<source>{VAR_PLURAL, plural, =1 {One <x id="INTERPOLATION"/>} other {<x id="INTERPOLATION_1"/> total <x id="INTERPOLATION_2"/>}}</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/manage/document-attributes/management-list/management-list.component.html</context>
<context context-type="linenumber">69</context>
<context context-type="linenumber">67</context>
</context-group>
</trans-unit>
<trans-unit id="810888510148304696" datatype="html">
@@ -1,5 +1,7 @@
@if (!accordion) {
<h5 i18n>Permissions</h5>
@if (title?.length > 0) {
<h5>{{title}}</h5>
}
<ng-container [ngTemplateOutlet]="permissionsForm"></ng-container>
}
@if (accordion) {
@@ -59,6 +59,9 @@ export class PermissionsFormComponent
@Input()
accordion: boolean = false
@Input()
title: string = $localize`Permissions`
form = new FormGroup({
owner: new FormControl(null),
set_permissions: new FormGroup({
@@ -3,13 +3,13 @@
<h3 class="d-flex align-items-center mb-2 mb-md-1" style="line-height: 1.4">
<span class="text-truncate">{{title()}}</span>
@if (id()) {
<span class="badge bg-primary text-primary-text-contrast ms-3 small fs-normal cursor-pointer" (click)="copyID()">
<button type="button" class="badge border-0 bg-primary text-primary-text-contrast ms-3 small fs-normal" (click)="copyID()" title="Copy ID" i18n-title>
@if (copied()) {
<i-bs width="1em" height="1em" name="clipboard-check" class="me-1"></i-bs><ng-container i18n>Copied!</ng-container>
} @else {
ID: {{id()}}
}
</span>
</button>
}
@if (subTitle()) {
<span class="page-subtitle h6 mb-0 mt-1 fw-normal ms-md-3 text-truncate" style="line-height: 1.4">{{subTitle()}}</span>
@@ -43,6 +43,13 @@ describe('PageHeaderComponent', () => {
expect(titleSpy).toHaveBeenCalledWith(`Foo Bar - ${environment.appTitle}`)
})
it('should set html title to just the app title until a title is available', () => {
const titleSpy = jest.spyOn(titleService, 'setTitle')
fixture.componentRef.setInput('title', undefined)
fixture.detectChanges()
expect(titleSpy).toHaveBeenCalledWith(environment.appTitle)
})
it('should copy id to clipboard, reset after 3 seconds', () => {
jest.useFakeTimers()
fixture.componentRef.setInput('id', 42)
@@ -27,7 +27,10 @@ export class PageHeaderComponent {
constructor() {
effect(() => {
this.titleService.setTitle(`${this.title()} - ${environment.appTitle}`)
const title = this.title()
this.titleService.setTitle(
title ? `${title} - ${environment.appTitle}` : environment.appTitle
)
})
}
@@ -25,8 +25,6 @@
@if (displayFields().includes(field)) {
<th
scope="col"
class="text-truncate"
[title]="getColumnTitle(field)"
[ngClass]="{
'd-none d-md-table-cell': i > 1,
'w-25': field === DisplayField.CREATED || field === DisplayField.ADDED
@@ -1,25 +1,4 @@
<pngx-page-header [title]="title()" [id]="documentId()">
@if (archiveContentRenderType === ContentRenderType.PDF && !useNativePdfViewer) {
@if (previewNumPages()) {
<div class="input-group input-group-sm ms-2 d-none d-md-flex">
<div class="input-group-text" i18n>Page</div>
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages()" [ngModel]="previewCurrentPage()" (ngModelChange)="previewCurrentPage.set($event)" />
<div class="input-group-text" i18n>of {{previewNumPages()}}</div>
</div>
}
<div class="input-group input-group-sm me-md-5 d-none d-md-flex">
<button class="btn btn-outline-secondary" (click)="decreaseZoom()" i18n>-</button>
<select class="form-select" (change)="setZoom($event.target.value)" [ngModel]="currentZoom">
@for (setting of zoomSettings; track setting) {
<option [value]="setting">
{{ getZoomSettingTitle(setting) }}
</option>
}
</select>
<button class="btn btn-outline-secondary" (click)="increaseZoom()" i18n>+</button>
</div>
}
<button type="button" class="btn btn-sm btn-outline-danger me-md-4" (click)="delete()" [disabled]="!userIsOwner" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }" aria-label="Delete" i18n-aria-label>
<i-bs width="1.2em" height="1.2em" name="trash"></i-bs><span class="d-none d-lg-inline ps-1" i18n>Delete</span>
</button>
@@ -34,7 +13,7 @@
(versionsUpdated)="onVersionsUpdated($event)"
/>
<div class="btn-group">
<div class="btn-group ms-4">
<button (click)="download()" class="btn btn-sm btn-outline-primary" [disabled]="downloading()" aria-label="Download" i18n-aria-label>
@if (downloading()) {
<div class="spinner-border spinner-border-sm" role="status"></div>
@@ -94,7 +73,7 @@
<button class="btn btn-sm btn-outline-primary" id="sendDropdown" ngbDropdownToggle aria-label="Send" i18n-aria-label>
<i-bs name="send"></i-bs><div class="d-none d-sm-inline ms-1"><ng-container i18n>Send</ng-container></div>
</button>
<div ngbDropdownMenu aria-labelledby="actionsDropdown" class="shadow">
<div ngbDropdownMenu aria-labelledby="sendDropdown" class="shadow">
<button ngbDropdownItem (click)="openShareLinks()" *pngxIfPermissions="{ action: PermissionAction.Add, type: PermissionType.ShareLink }">
<i-bs name="link" class="me-1"></i-bs><span i18n>Share Links</span>
</button>
@@ -113,8 +92,8 @@
<form [formGroup]='documentForm' (ngSubmit)="save()">
<div class="btn-toolbar justify-content-end mb-1 pb-3 gap-2 row-gap-2 border-bottom">
<div class="btn-group me-auto">
<div class="btn-toolbar mb-1 pb-3 gap-2 row-gap-2 border-bottom">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary" i18n-title title="Close" (click)="close()">
<i-bs width="1.2em" height="1.2em" name="x"></i-bs>
</button>
@@ -127,43 +106,30 @@
</div>
<ng-container *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }">
<div class="d-flex gap-2">
<div class="btn-group">
<pngx-suggestions-dropdown *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }"
[disabled]="!userCanEdit || suggestionsLoading()"
[loading]="suggestionsLoading()"
[suggestions]="suggestions()"
[aiEnabled]="aiEnabled"
[source]="suggestionSource"
[defaultSource]="defaultSuggestionSource"
[fetchedSources]="fetchedSuggestionSources()"
[appliedTags]="documentForm.value.tags"
[appliedCorrespondent]="documentForm.value.correspondent"
[appliedDocumentType]="documentForm.value.document_type"
[appliedStoragePath]="documentForm.value.storage_path"
[appliedTitle]="documentForm.value.title"
[appliedCreated]="documentForm.value.created"
(getSuggestions)="getSuggestions($event)"
(sourceChange)="suggestionSourceOverride.set($event)"
(addTag)="createTag($event)"
(addDocumentType)="createDocumentType($event)"
(addCorrespondent)="createCorrespondent($event)">
</pngx-suggestions-dropdown>
</div>
<div class="btn-group">
<pngx-custom-fields-dropdown
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.CustomField }"
[documentId]="documentId()"
[disabled]="!userCanEdit"
[existingFields]="document()?.custom_fields"
(created)="refreshCustomFields()"
(added)="addField($event)">
</pngx-custom-fields-dropdown>
</div>
<div class="btn-group ms-3">
<pngx-suggestions-dropdown *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }"
[disabled]="!userCanEdit || suggestionsLoading()"
[loading]="suggestionsLoading()"
[suggestions]="suggestions()"
[aiEnabled]="aiEnabled"
[source]="suggestionSource"
[defaultSource]="defaultSuggestionSource"
[fetchedSources]="fetchedSuggestionSources()"
[appliedTags]="documentForm.value.tags"
[appliedCorrespondent]="documentForm.value.correspondent"
[appliedDocumentType]="documentForm.value.document_type"
[appliedStoragePath]="documentForm.value.storage_path"
[appliedTitle]="documentForm.value.title"
[appliedCreated]="documentForm.value.created"
(getSuggestions)="getSuggestions($event)"
(sourceChange)="suggestionSourceOverride.set($event)"
(addTag)="createTag($event)"
(addDocumentType)="createDocumentType($event)"
(addCorrespondent)="createCorrespondent($event)">
</pngx-suggestions-dropdown>
</div>
<div class="ps-3">
<div class="ms-auto">
<ng-container *ngTemplateOutlet="saveButtons"></ng-container>
</div>
</ng-container>
@@ -290,8 +256,20 @@
}
</div>
<div class="d-flex justify-content-end border-top pt-3">
<ng-container *ngTemplateOutlet="saveButtons"></ng-container>
<div class="d-flex border-top pt-3">
<ng-container *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }">
<pngx-custom-fields-dropdown
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.CustomField }"
[documentId]="documentId()"
[disabled]="!userCanEdit"
[existingFields]="document()?.custom_fields"
(created)="refreshCustomFields()"
(added)="addField($event)">
</pngx-custom-fields-dropdown>
</ng-container>
<div class="ms-auto">
<ng-container *ngTemplateOutlet="saveButtons"></ng-container>
</div>
</div>
</ng-template>
</li>
@@ -328,9 +306,9 @@
<td i18n>Original filename</td>
<td>{{metadata()?.original_filename}}</td>
</tr>
<tr>
<tr class="align-middle">
<td i18n>Original SHA256 checksum</td>
<td>{{metadata()?.original_checksum}}</td>
<td><span class="badge bg-light font-monospace text-wrap text-break text-start">{{metadata()?.original_checksum}}</span></td>
</tr>
<tr>
<td i18n>Original file size</td>
@@ -341,9 +319,9 @@
<td>{{metadata()?.original_mime_type}}</td>
</tr>
@if (metadata()?.has_archive_version) {
<tr>
<tr class="align-middle">
<td i18n>Archive SHA256 checksum</td>
<td>{{metadata()?.archive_checksum}}</td>
<td><span class="badge bg-light font-monospace text-wrap text-break text-start">{{metadata()?.archive_checksum}}</span></td>
</tr>
}
@if (metadata()?.has_archive_version) {
@@ -408,7 +386,7 @@
<a ngbNavLink i18n>Permissions</a>
<ng-template ngbNavContent>
<div class="mb-3">
<pngx-permissions-form [users]="users()" formControlName="permissions_form"></pngx-permissions-form>
<pngx-permissions-form title="" [users]="users()" formControlName="permissions_form"></pngx-permissions-form>
</div>
</ng-template>
</li>
@@ -499,6 +477,29 @@
(loadError)="onError($event)"
(afterLoadComplete)="pdfPreviewLoaded($event)">
</pngx-pdf-viewer>
<div class="position-absolute bottom-0 start-50 translate-middle-x z-1 mb-3 d-flex gap-2 p-1 bg-body border rounded shadow">
@if (previewNumPages()) {
<div class="input-group input-group-sm w-auto flex-nowrap">
<input class="form-control flex-grow-0 w-auto" type="number" min="1" [max]="previewNumPages()" [ngModelOptions]="{standalone: true}" [ngModel]="previewCurrentPage()" (ngModelChange)="previewCurrentPage.set($event)" aria-label="Page" i18n-aria-label />
<div class="input-group-text" i18n>of {{previewNumPages()}}</div>
</div>
}
<div class="input-group input-group-sm w-auto flex-nowrap">
<button class="btn btn-outline-secondary" (click)="decreaseZoom()" aria-label="Zoom out" i18n-aria-label>
<i-bs width="1em" height="1em" name="dash"></i-bs>
</button>
<select class="form-select" (change)="setZoom($event.target.value)" [ngModelOptions]="{standalone: true}" [ngModel]="currentZoom" aria-label="Zoom" i18n-aria-label>
@for (setting of zoomSettings; track setting) {
<option [value]="setting">
{{ getZoomSettingTitle(setting) }}
</option>
}
</select>
<button class="btn btn-outline-secondary" (click)="increaseZoom()" aria-label="Zoom in" i18n-aria-label>
<i-bs width="1em" height="1em" name="plus"></i-bs>
</button>
</div>
</div>
</div>
} @else {
<object [data]="previewUrl() | safeUrl" class="preview-sticky" width="100%"></object>
@@ -11,7 +11,7 @@
<div class="input-group input-group-sm w-auto d-none d-md-flex">
<label class="input-group-text bg-transparent border-0" for="managementPageSize" i18n>Show:</label>
</div>
<div class="input-group input-group-sm w-auto">
<div class="input-group input-group-sm w-auto me-3">
<select id="managementPageSize" class="form-select form-select-sm small" [(ngModel)]="pageSize">
<option [ngValue]="25">25</option>
<option [ngValue]="50">50</option>
@@ -19,9 +19,7 @@
</select>
<span class="input-group-text text-muted d-none d-md-flex" i18n>per page</span>
</div>
@if (collectionSize() > pageSize) {
<ngb-pagination [pageSize]="pageSize" [collectionSize]="collectionSize()" [page]="page()" [maxSize]="5" (pageChange)="page.set($event); reloadData()" class="ms-3" size="sm" aria-label="Pagination"></ngb-pagination>
}
<ngb-pagination [pageSize]="pageSize" [collectionSize]="collectionSize()" [page]="page()" [maxSize]="5" (pageChange)="page.set($event); reloadData()" size="sm" aria-label="Pagination"></ngb-pagination>
</div>
</div>
@@ -72,7 +70,7 @@
}
</div>
}
@if (collectionSize() > pageSize) {
@if (collectionSize() > 20) {
<ngb-pagination class="ms-auto" [pageSize]="pageSize" [collectionSize]="collectionSize()" [page]="page()" [maxSize]="5" (pageChange)="page.set($event); reloadData()" size="sm" aria-label="Pagination"></ngb-pagination>
}
</div>
@@ -93,17 +93,15 @@
[disabled]="selectedMailIds().size === 0"
(confirm)="deleteSelected()">
</pngx-confirm-button>
@if (processedMails().length > 50) {
<div class="ms-auto">
<ngb-pagination
[collectionSize]="processedMails().length"
[(page)]="page"
[pageSize]="50"
[maxSize]="5"
(pageChange)="loadProcessedMails()">
</ngb-pagination>
</div>
}
<div class="ms-auto">
<ngb-pagination
[collectionSize]="processedMails().length"
[(page)]="page"
[pageSize]="50"
[maxSize]="5"
(pageChange)="loadProcessedMails()">
</ngb-pagination>
</div>
</div>
}
</div>
+23
View File
@@ -2137,6 +2137,29 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
self.assertEqual(len(response.data["documents"]), 1)
self.assertEqual(response.data["documents"][0]["id"], title_match.id)
def test_global_search_returns_latest_version_content(self) -> None:
root = Document.objects.create(
title="bank statement",
content="superseded content",
checksum="GSV1",
pk=23,
)
Document.objects.create(
title="bank statement v2",
content="latest content",
checksum="GSV2",
pk=24,
root_document=root,
version_index=1,
)
self.client.force_authenticate(self.user)
response = self.client.get("/api/search/?query=bank&db_only=true")
self.assertEqual(response.status_code, status.HTTP_200_OK)
returned = {doc["id"]: doc["content"] for doc in response.data["documents"]}
self.assertEqual(returned.get(root.id), "latest content")
def test_global_search_filters_owned_mail_objects(self) -> None:
user1 = UserFactory(username="mail-search-user")
user2 = UserFactory(username="other-mail-search-user")
@@ -423,3 +423,35 @@ class TestTrashAndGlobalSearchEffectiveContentIsNeverPerInstance:
[result] = [r for r in response.data["results"] if r["id"] == root.id]
assert result["content"] == "own-content"
assert _get_effective_content_fallback_queries(ctx) == []
def test_global_search_db_only_shows_latest_version_content_with_no_extra_query(
self,
admin_client: APIClient,
) -> None:
"""
GIVEN:
- A root document, findable by title, whose own content differs
from its latest version's
WHEN:
- Using the global search endpoint's db_only mode
THEN:
- The response shows the latest version's content, resolved by
GlobalSearchView's own effective_content annotation
- There is no per-instance fallback query
"""
root = DocumentFactory(title="findme", content="own-content")
DocumentFactory(
root_document=root,
version_index=1,
content="version-content",
)
with CaptureQueriesContext(connection) as ctx:
response = admin_client.get(
"/api/search/?query=findme&db_only=true",
)
assert response.status_code == status.HTTP_200_OK
[result] = [d for d in response.data["documents"] if d["id"] == root.id]
assert result["content"] == "version-content"
assert _get_effective_content_fallback_queries(ctx) == []
+1 -6
View File
@@ -3932,12 +3932,7 @@ class GlobalSearchView(PassUserMixin):
"request": request,
}
docs_serializer = DocumentSerializer(
docs,
many=True,
context=context,
fields=("id", "title", "created"),
)
docs_serializer = DocumentSerializer(docs, many=True, context=context)
saved_views_serializer = SavedViewSerializer(
saved_views,
many=True,