mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			64ff422fef
			...
			feature-pr
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					4070cd0e1b | 
@@ -1,10 +1,14 @@
 | 
				
			|||||||
<a [href]="link ?? previewUrl" class="{{linkClasses}}" [target]="linkTarget" [title]="linkTitle"
 | 
					@if (!previewOnly) {
 | 
				
			||||||
 | 
					  <a [href]="link ?? previewUrl" class="{{linkClasses}}" [target]="linkTarget" [title]="linkTitle"
 | 
				
			||||||
    [ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle" container="body"
 | 
					    [ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle" container="body"
 | 
				
			||||||
    autoClose="true" [popoverClass]="popoverClass" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
 | 
					    autoClose="true" [popoverClass]="popoverClass" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
 | 
				
			||||||
    <ng-content></ng-content>
 | 
					    <ng-content></ng-content>
 | 
				
			||||||
</a>
 | 
					  </a>
 | 
				
			||||||
 | 
					} @else {
 | 
				
			||||||
 | 
					  <ng-container [ngTemplateOutlet]="previewContent" [ngTemplateOutletContext]="{ $implicit: document }"></ng-container>
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
<ng-template #previewContent>
 | 
					<ng-template #previewContent>
 | 
				
			||||||
  <div class="preview-popup-container" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview(); close()">
 | 
					  <div class="preview-popup-container" [class.full-size]="previewOnly" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview(); close()">
 | 
				
			||||||
    @if (error) {
 | 
					    @if (error) {
 | 
				
			||||||
      <div class="w-100 h-100 position-relative">
 | 
					      <div class="w-100 h-100 position-relative">
 | 
				
			||||||
        <p class="fst-italic position-absolute top-50 start-50 translate-middle" i18n>Error loading preview</p>
 | 
					        <p class="fst-italic position-absolute top-50 start-50 translate-middle" i18n>Error loading preview</p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,16 @@
 | 
				
			|||||||
    overflow-y: scroll;
 | 
					    overflow-y: scroll;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.preview-popup-container.full-size {
 | 
				
			||||||
 | 
					  width: 100% !important;
 | 
				
			||||||
 | 
					  height: 100% !important;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  > * {
 | 
				
			||||||
 | 
					    width: 100% !important;
 | 
				
			||||||
 | 
					    height: 100% !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
::ng-deep .popover.popover-preview {
 | 
					::ng-deep .popover.popover-preview {
 | 
				
			||||||
    max-width: 32rem;
 | 
					    max-width: 32rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import { NgTemplateOutlet } from '@angular/common'
 | 
				
			||||||
import { HttpClient } from '@angular/common/http'
 | 
					import { HttpClient } from '@angular/common/http'
 | 
				
			||||||
import { Component, Input, OnDestroy, ViewChild } from '@angular/core'
 | 
					import { Component, Input, OnDestroy, ViewChild } from '@angular/core'
 | 
				
			||||||
import { NgbPopover, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
 | 
					import { NgbPopover, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
 | 
				
			||||||
@@ -17,6 +18,7 @@ import { SettingsService } from 'src/app/services/settings.service'
 | 
				
			|||||||
  styleUrls: ['./preview-popup.component.scss'],
 | 
					  styleUrls: ['./preview-popup.component.scss'],
 | 
				
			||||||
  imports: [
 | 
					  imports: [
 | 
				
			||||||
    NgbPopoverModule,
 | 
					    NgbPopoverModule,
 | 
				
			||||||
 | 
					    NgTemplateOutlet,
 | 
				
			||||||
    DocumentTitlePipe,
 | 
					    DocumentTitlePipe,
 | 
				
			||||||
    PdfViewerModule,
 | 
					    PdfViewerModule,
 | 
				
			||||||
    SafeUrlPipe,
 | 
					    SafeUrlPipe,
 | 
				
			||||||
@@ -47,6 +49,9 @@ export class PreviewPopupComponent implements OnDestroy {
 | 
				
			|||||||
  @Input()
 | 
					  @Input()
 | 
				
			||||||
  linkTitle: string = $localize`Open preview`
 | 
					  linkTitle: string = $localize`Open preview`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Input()
 | 
				
			||||||
 | 
					  previewOnly: boolean = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsubscribeNotifier: Subject<any> = new Subject()
 | 
					  unsubscribeNotifier: Subject<any> = new Subject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  error = false
 | 
					  error = false
 | 
				
			||||||
@@ -91,6 +96,8 @@ export class PreviewPopupComponent implements OnDestroy {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init() {
 | 
					  init() {
 | 
				
			||||||
 | 
					    this.error = false
 | 
				
			||||||
 | 
					    this.requiresPassword = false
 | 
				
			||||||
    if (this.document.mime_type?.includes('text')) {
 | 
					    if (this.document.mime_type?.includes('text')) {
 | 
				
			||||||
      this.http
 | 
					      this.http
 | 
				
			||||||
        .get(this.previewURL, { responseType: 'text' })
 | 
					        .get(this.previewURL, { responseType: 'text' })
 | 
				
			||||||
@@ -119,6 +126,7 @@ export class PreviewPopupComponent implements OnDestroy {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mouseEnterPreview() {
 | 
					  mouseEnterPreview() {
 | 
				
			||||||
 | 
					    if (this.previewOnly) return
 | 
				
			||||||
    this.mouseOnPreview = true
 | 
					    this.mouseOnPreview = true
 | 
				
			||||||
    if (!this.popover.isOpen()) {
 | 
					    if (!this.popover.isOpen()) {
 | 
				
			||||||
      // we're going to open but hide to pre-load content during hover delay
 | 
					      // we're going to open but hide to pre-load content during hover delay
 | 
				
			||||||
@@ -136,10 +144,12 @@ export class PreviewPopupComponent implements OnDestroy {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mouseLeavePreview() {
 | 
					  mouseLeavePreview() {
 | 
				
			||||||
 | 
					    if (this.previewOnly) return
 | 
				
			||||||
    this.mouseOnPreview = false
 | 
					    this.mouseOnPreview = false
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public close(immediate: boolean = false) {
 | 
					  public close(immediate: boolean = false) {
 | 
				
			||||||
 | 
					    if (this.previewOnly) return
 | 
				
			||||||
    setTimeout(
 | 
					    setTimeout(
 | 
				
			||||||
      () => {
 | 
					      () => {
 | 
				
			||||||
        if (!this.mouseOnPreview) this.popover.close()
 | 
					        if (!this.mouseOnPreview) this.popover.close()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div class="btn-group flex-fill" role="group">
 | 
					  <div class="btn-group flex-fill" role="group">
 | 
				
			||||||
    <input type="radio" class="btn-check" [(ngModel)]="list.displayMode" value="table" id="displayModeDetails" name="displayModeDetails">
 | 
					    <input type="radio" class="btn-check" [(ngModel)]="list.displayMode" value="table" id="displayModeDetails" name="displayModeDetails">
 | 
				
			||||||
    <label for="displayModeDetails" class="btn btn-outline-primary btn-sm">
 | 
					    <label for="displayModeDetails" class="btn btn-outline-primary btn-sm">
 | 
				
			||||||
@@ -42,6 +43,13 @@
 | 
				
			|||||||
    </label>
 | 
					    </label>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="btn-group flex-fill" role="group">
 | 
				
			||||||
 | 
					    <input type="checkbox" class="btn-check" [(ngModel)]="list.showPreviewPane" value="table" id="previewPane" name="previewPane">
 | 
				
			||||||
 | 
					    <label for="previewPane" class="btn btn-outline-primary btn-sm">
 | 
				
			||||||
 | 
					      <i-bs name="window-split"></i-bs>
 | 
				
			||||||
 | 
					    </label>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div ngbDropdown class="btn-group flex-fill">
 | 
					  <div ngbDropdown class="btn-group flex-fill">
 | 
				
			||||||
    <button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>
 | 
					    <button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>
 | 
				
			||||||
      <i-bs name="arrow-down-up"></i-bs>
 | 
					      <i-bs name="arrow-down-up"></i-bs>
 | 
				
			||||||
@@ -105,8 +113,9 @@
 | 
				
			|||||||
  <pngx-bulk-editor [hidden]="!isBulkEditing" [disabled]="!isBulkEditing"></pngx-bulk-editor>
 | 
					  <pngx-bulk-editor [hidden]="!isBulkEditing" [disabled]="!isBulkEditing"></pngx-bulk-editor>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
<ng-template #pagination>
 | 
					  <div [class.col-lg-6]="list.showPreviewPane" [class.col]="!list.showPreviewPane">
 | 
				
			||||||
 | 
					  <ng-template #pagination>
 | 
				
			||||||
    <div class="d-flex flex-wrap gap-3 justify-content-between align-items-center mb-3">
 | 
					    <div class="d-flex flex-wrap gap-3 justify-content-between align-items-center mb-3">
 | 
				
			||||||
      <div class="d-flex align-items-center">
 | 
					      <div class="d-flex align-items-center">
 | 
				
			||||||
        @if (list.isReloading) {
 | 
					        @if (list.isReloading) {
 | 
				
			||||||
@@ -400,3 +409,39 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  @if (list.showPreviewPane) {
 | 
				
			||||||
 | 
					    <div class="col-lg-6">
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="btn-toolbar mb-1 border-bottom align-items-center">
 | 
				
			||||||
 | 
					          <div class="btn-group pb-3">
 | 
				
			||||||
 | 
					            <button type="button" class="btn btn-sm btn-outline-secondary" i18n-title title="Previous" (click)="previousDoc()" [disabled]="list.documents.length === 0 || !hasPrevious">
 | 
				
			||||||
 | 
					              <i-bs width="1.2em" height="1.2em" name="arrow-left" class="me-1"></i-bs><ng-container i18n>Previous</ng-container>
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					            <button type="button" class="btn btn-sm btn-outline-secondary"  i18n-title title="Next" (click)="nextDoc()" [disabled]="list.documents.length === 0 || !hasNext">
 | 
				
			||||||
 | 
					              <ng-container i18n>Next</ng-container><i-bs width="1.2em" height="1.2em" name="arrow-right" class="ms-1"></i-bs>
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="input-group pb-3 ms-auto">
 | 
				
			||||||
 | 
					            <h5 class="mb-0">
 | 
				
			||||||
 | 
					              {{list.firstSelectedDocument?.title}}
 | 
				
			||||||
 | 
					            </h5>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="row">
 | 
				
			||||||
 | 
					        <div class="col preview-pane">
 | 
				
			||||||
 | 
					          @if (list.selected.size > 0) {
 | 
				
			||||||
 | 
					            <pngx-preview-popup [document]="list.firstSelectedDocument" [previewOnly]="true"></pngx-preview-popup>
 | 
				
			||||||
 | 
					          } @else {
 | 
				
			||||||
 | 
					            <div class="w-100 h-100 position-relative">
 | 
				
			||||||
 | 
					              <p class="fst-italic">
 | 
				
			||||||
 | 
					                <ng-container i18n>No document selected</ng-container>
 | 
				
			||||||
 | 
					              </p>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,3 +80,9 @@ a {
 | 
				
			|||||||
pngx-page-header .dropdown-menu {
 | 
					pngx-page-header .dropdown-menu {
 | 
				
			||||||
  --bs-dropdown-min-width: 12em;
 | 
					  --bs-dropdown-min-width: 12em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.preview-pane {
 | 
				
			||||||
 | 
					  height: 60rem;
 | 
				
			||||||
 | 
					  top: 70px;
 | 
				
			||||||
 | 
					  position: sticky;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -326,25 +326,37 @@ export class DocumentListComponent
 | 
				
			|||||||
    this.hotKeyService
 | 
					    this.hotKeyService
 | 
				
			||||||
      .addShortcut({
 | 
					      .addShortcut({
 | 
				
			||||||
        keys: 'control.arrowleft',
 | 
					        keys: 'control.arrowleft',
 | 
				
			||||||
        description: $localize`Previous page`,
 | 
					        description: $localize`Previous page / document`,
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
					      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
				
			||||||
      .subscribe(() => {
 | 
					      .subscribe(() => {
 | 
				
			||||||
 | 
					        if (this.list.showPreviewPane) {
 | 
				
			||||||
 | 
					          if (this.hasPrevious) {
 | 
				
			||||||
 | 
					            this.previousDoc()
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
          if (this.list.currentPage > 1) {
 | 
					          if (this.list.currentPage > 1) {
 | 
				
			||||||
            this.list.currentPage--
 | 
					            this.list.currentPage--
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.hotKeyService
 | 
					    this.hotKeyService
 | 
				
			||||||
      .addShortcut({
 | 
					      .addShortcut({
 | 
				
			||||||
        keys: 'control.arrowright',
 | 
					        keys: 'control.arrowright',
 | 
				
			||||||
        description: $localize`Next page`,
 | 
					        description: $localize`Next page / document`,
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
					      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
				
			||||||
      .subscribe(() => {
 | 
					      .subscribe(() => {
 | 
				
			||||||
 | 
					        if (this.list.showPreviewPane) {
 | 
				
			||||||
 | 
					          if (this.hasNext) {
 | 
				
			||||||
 | 
					            this.nextDoc()
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
          if (this.list.currentPage < this.list.getLastPage()) {
 | 
					          if (this.list.currentPage < this.list.getLastPage()) {
 | 
				
			||||||
            this.list.currentPage++
 | 
					            this.list.currentPage++
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -473,4 +485,45 @@ export class DocumentListComponent
 | 
				
			|||||||
  resetFilters() {
 | 
					  resetFilters() {
 | 
				
			||||||
    this.filterEditor.resetSelected()
 | 
					    this.filterEditor.resetSelected()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public get hasPrevious(): boolean {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      (this.list.selected.size > 0 &&
 | 
				
			||||||
 | 
					        this.list.documents.indexOf(this.list.firstSelectedDocument) > 0) ||
 | 
				
			||||||
 | 
					      (this.list.selected.size === 0 && this.list.documents.length > 0)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public get hasNext(): boolean {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      (this.list.selected.size > 0 &&
 | 
				
			||||||
 | 
					        this.list.documents.indexOf(this.list.firstSelectedDocument) <
 | 
				
			||||||
 | 
					          this.list.documents.length - 1) ||
 | 
				
			||||||
 | 
					      (this.list.selected.size === 0 && this.list.documents.length > 0)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public nextDoc(): void {
 | 
				
			||||||
 | 
					    const index =
 | 
				
			||||||
 | 
					      this.list.selected.size === 0
 | 
				
			||||||
 | 
					        ? 0
 | 
				
			||||||
 | 
					        : Math.min(
 | 
				
			||||||
 | 
					            this.list.documents.indexOf(this.list.firstSelectedDocument) + 1,
 | 
				
			||||||
 | 
					            this.list.documents.length - 1
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					    this.list.selected.clear()
 | 
				
			||||||
 | 
					    this.list.selected.add(this.list.documents[index].id)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public previousDoc(): void {
 | 
				
			||||||
 | 
					    const index =
 | 
				
			||||||
 | 
					      this.list.selected.size === 0
 | 
				
			||||||
 | 
					        ? 0
 | 
				
			||||||
 | 
					        : Math.max(
 | 
				
			||||||
 | 
					            this.list.documents.indexOf(this.list.firstSelectedDocument) - 1,
 | 
				
			||||||
 | 
					            0
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					    this.list.selected.clear()
 | 
				
			||||||
 | 
					    this.list.selected.add(this.list.documents[index].id)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,6 +79,11 @@ export interface ListViewState {
 | 
				
			|||||||
   * The fields to display in the document list.
 | 
					   * The fields to display in the document list.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  displayFields?: DisplayField[]
 | 
					  displayFields?: DisplayField[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Whether the preview pane is shown.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  showPreviewPane?: boolean
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -165,6 +170,7 @@ export class DocumentListViewService {
 | 
				
			|||||||
      sortReverse: true,
 | 
					      sortReverse: true,
 | 
				
			||||||
      filterRules: [],
 | 
					      filterRules: [],
 | 
				
			||||||
      selected: new Set<number>(),
 | 
					      selected: new Set<number>(),
 | 
				
			||||||
 | 
					      showPreviewPane: false,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -451,6 +457,15 @@ export class DocumentListViewService {
 | 
				
			|||||||
    this.saveDocumentListView()
 | 
					    this.saveDocumentListView()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get showPreviewPane(): boolean {
 | 
				
			||||||
 | 
					    return this.activeListViewState.showPreviewPane
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  set showPreviewPane(show: boolean) {
 | 
				
			||||||
 | 
					    this.activeListViewState.showPreviewPane = show
 | 
				
			||||||
 | 
					    this.saveDocumentListView()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private saveDocumentListView() {
 | 
					  private saveDocumentListView() {
 | 
				
			||||||
    if (this._activeSavedViewId == null) {
 | 
					    if (this._activeSavedViewId == null) {
 | 
				
			||||||
      let savedState: ListViewState = {
 | 
					      let savedState: ListViewState = {
 | 
				
			||||||
@@ -461,6 +476,7 @@ export class DocumentListViewService {
 | 
				
			|||||||
        sortReverse: this.activeListViewState.sortReverse,
 | 
					        sortReverse: this.activeListViewState.sortReverse,
 | 
				
			||||||
        displayMode: this.activeListViewState.displayMode,
 | 
					        displayMode: this.activeListViewState.displayMode,
 | 
				
			||||||
        displayFields: this.activeListViewState.displayFields,
 | 
					        displayFields: this.activeListViewState.displayFields,
 | 
				
			||||||
 | 
					        showPreviewPane: this.activeListViewState.showPreviewPane,
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      localStorage.setItem(
 | 
					      localStorage.setItem(
 | 
				
			||||||
        DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG,
 | 
					        DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG,
 | 
				
			||||||
@@ -626,4 +642,8 @@ export class DocumentListViewService {
 | 
				
			|||||||
  documentIndexInCurrentView(documentID: number): number {
 | 
					  documentIndexInCurrentView(documentID: number): number {
 | 
				
			||||||
    return this.documents.map((d) => d.id).indexOf(documentID)
 | 
					    return this.documents.map((d) => d.id).indexOf(documentID)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get firstSelectedDocument(): Document {
 | 
				
			||||||
 | 
					    return this.documents.find((d) => this.selected.has(d.id))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -125,6 +125,7 @@ import {
 | 
				
			|||||||
  trash,
 | 
					  trash,
 | 
				
			||||||
  uiRadios,
 | 
					  uiRadios,
 | 
				
			||||||
  upcScan,
 | 
					  upcScan,
 | 
				
			||||||
 | 
					  windowSplit,
 | 
				
			||||||
  windowStack,
 | 
					  windowStack,
 | 
				
			||||||
  x,
 | 
					  x,
 | 
				
			||||||
  xCircle,
 | 
					  xCircle,
 | 
				
			||||||
@@ -323,6 +324,7 @@ const icons = {
 | 
				
			|||||||
  trash,
 | 
					  trash,
 | 
				
			||||||
  uiRadios,
 | 
					  uiRadios,
 | 
				
			||||||
  upcScan,
 | 
					  upcScan,
 | 
				
			||||||
 | 
					  windowSplit,
 | 
				
			||||||
  windowStack,
 | 
					  windowStack,
 | 
				
			||||||
  x,
 | 
					  x,
 | 
				
			||||||
  xCircle,
 | 
					  xCircle,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user