mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-04 03:27:12 -05:00 
			
		
		
		
	Support large cards
This commit is contained in:
		
							parent
							
								
									83c88ca472
								
							
						
					
					
						commit
						ee92ab1136
					
				@ -1,4 +1,4 @@
 | 
				
			|||||||
<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable">
 | 
					<div class="card mb-3 shadow-sm" [class.card-selected]="selected" [class.document-card]="selectable" [class.popover-hidden]="popoverHidden" (mouseleave)="mouseLeaveCard()">
 | 
				
			||||||
  <div class="row no-gutters">
 | 
					  <div class="row no-gutters">
 | 
				
			||||||
    <div class="col-md-2 d-none d-lg-block doc-img-background rounded-left" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)">
 | 
					    <div class="col-md-2 d-none d-lg-block doc-img-background rounded-left" [class.doc-img-background-selected]="selected" (click)="this.toggleSelected.emit($event)">
 | 
				
			||||||
      <img [src]="getThumbUrl()" class="card-img doc-img border-right rounded-left">
 | 
					      <img [src]="getThumbUrl()" class="card-img doc-img border-right rounded-left">
 | 
				
			||||||
@ -43,19 +43,30 @@
 | 
				
			|||||||
                <path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
 | 
					                <path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
 | 
				
			||||||
              </svg> <span class="d-block d-md-inline" i18n>Edit</span>
 | 
					              </svg> <span class="d-block d-md-inline" i18n>Edit</span>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
            <a class="btn btn-sm btn-outline-secondary" [href]="getPreviewUrl()">
 | 
					            <a class="btn btn-sm btn-outline-secondary" [href]="previewUrl" title="Hover to preview, click to view in browser" i18n-title
 | 
				
			||||||
 | 
					            [ngbPopover]="previewContent" [popoverTitle]="document.title | documentTitle"
 | 
				
			||||||
 | 
					            autoClose="true" popoverClass="shadow" (mouseenter)="mouseEnterPreview()" (mouseleave)="mouseLeavePreview()" #popover="ngbPopover">
 | 
				
			||||||
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
 | 
					              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
 | 
				
			||||||
                <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
 | 
					                <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
 | 
				
			||||||
                <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
 | 
					                <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
 | 
				
			||||||
              </svg> <span class="d-block d-md-inline" i18n>View</span>
 | 
					              </svg> <span class="d-block d-md-inline" i18n>View</span>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					            <ng-template #previewContent>
 | 
				
			||||||
 | 
					              <ng-container *ngIf="getContentType() == 'application/pdf'">
 | 
				
			||||||
 | 
					                  <div class="preview">
 | 
				
			||||||
 | 
					                    <object [data]="previewUrl | safe" class="preview" width="100%"></object>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					              </ng-container>
 | 
				
			||||||
 | 
					              <ng-container *ngIf="getContentType() == 'text/plain'">
 | 
				
			||||||
 | 
					                  <object [data]="previewUrl | safe" type="text/plain" class="preview" width="100%"></object>
 | 
				
			||||||
 | 
					              </ng-container>
 | 
				
			||||||
 | 
					            </ng-template>
 | 
				
			||||||
            <a class="btn btn-sm btn-outline-secondary" [href]="getDownloadUrl()">
 | 
					            <a class="btn btn-sm btn-outline-secondary" [href]="getDownloadUrl()">
 | 
				
			||||||
              <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
 | 
					              <svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
 | 
				
			||||||
                <path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
 | 
					                <path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
 | 
				
			||||||
                <path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
 | 
					                <path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
 | 
				
			||||||
              </svg> <span class="d-block d-md-inline" i18n>Download</span>
 | 
					              </svg> <span class="d-block d-md-inline" i18n>Download</span>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div *ngIf="searchScore" class="d-flex align-items-center ml-md-auto mt-2 mt-md-0">
 | 
					          <div *ngIf="searchScore" class="d-flex align-items-center ml-md-auto mt-2 mt-md-0">
 | 
				
			||||||
 | 
				
			|||||||
@ -37,3 +37,26 @@
 | 
				
			|||||||
.doc-img-background-selected {
 | 
					.doc-img-background-selected {
 | 
				
			||||||
  background-color: $primaryFaded;
 | 
					  background-color: $primaryFaded;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					::ng-deep .popover {
 | 
				
			||||||
 | 
					  max-width: 40rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .preview {
 | 
				
			||||||
 | 
					    min-width: 25rem;
 | 
				
			||||||
 | 
					    min-height: 15rem;
 | 
				
			||||||
 | 
					    max-height: 35rem;
 | 
				
			||||||
 | 
					    overflow-y: scroll;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .spinner-border {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    top: 4rem;
 | 
				
			||||||
 | 
					    left: calc(50% - 0.5rem);
 | 
				
			||||||
 | 
					    z-index: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.popover-hidden ::ng-deep .popover {
 | 
				
			||||||
 | 
					  opacity: 0;
 | 
				
			||||||
 | 
					  pointer-events: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 | 
					import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
 | 
				
			||||||
import { DomSanitizer } from '@angular/platform-browser';
 | 
					import { DomSanitizer } from '@angular/platform-browser';
 | 
				
			||||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
 | 
					import { PaperlessDocument } from 'src/app/data/paperless-document';
 | 
				
			||||||
 | 
					import { PaperlessDocumentMetadata } from 'src/app/data/paperless-document-metadata';
 | 
				
			||||||
import { DocumentService } from 'src/app/services/rest/document.service';
 | 
					import { DocumentService } from 'src/app/services/rest/document.service';
 | 
				
			||||||
 | 
					import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-document-card-large',
 | 
					  selector: 'app-document-card-large',
 | 
				
			||||||
@ -40,6 +42,13 @@ export class DocumentCardLargeComponent implements OnInit {
 | 
				
			|||||||
  @Input()
 | 
					  @Input()
 | 
				
			||||||
  searchScore: number
 | 
					  searchScore: number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @ViewChild('popover') popover: NgbPopover
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mouseOnPreview = false
 | 
				
			||||||
 | 
					  popoverHidden = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  metadata: PaperlessDocumentMetadata
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get searchScoreClass() {
 | 
					  get searchScoreClass() {
 | 
				
			||||||
    if (this.searchScore > 0.7) {
 | 
					    if (this.searchScore > 0.7) {
 | 
				
			||||||
      return "success"
 | 
					      return "success"
 | 
				
			||||||
@ -51,6 +60,9 @@ export class DocumentCardLargeComponent implements OnInit {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
 | 
					    this.documentService.getMetadata(this.document?.id).subscribe(result => {
 | 
				
			||||||
 | 
					      this.metadata = result
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getDetailsAsString() {
 | 
					  getDetailsAsString() {
 | 
				
			||||||
@ -74,7 +86,36 @@ export class DocumentCardLargeComponent implements OnInit {
 | 
				
			|||||||
    return this.documentService.getDownloadUrl(this.document.id)
 | 
					    return this.documentService.getDownloadUrl(this.document.id)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getPreviewUrl() {
 | 
					  get previewUrl() {
 | 
				
			||||||
    return this.documentService.getPreviewUrl(this.document.id)
 | 
					    return this.documentService.getPreviewUrl(this.document.id)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getContentType() {
 | 
				
			||||||
 | 
					    return this.metadata?.has_archive_version ? 'application/pdf' : this.metadata?.original_mime_type
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mouseEnterPreview() {
 | 
				
			||||||
 | 
					    this.mouseOnPreview = true
 | 
				
			||||||
 | 
					    if (!this.popover.isOpen()) {
 | 
				
			||||||
 | 
					      // we're going to open but hide to pre-load content during hover delay
 | 
				
			||||||
 | 
					      this.popover.open()
 | 
				
			||||||
 | 
					      this.popoverHidden = true
 | 
				
			||||||
 | 
					      setTimeout(() => {
 | 
				
			||||||
 | 
					        if (this.mouseOnPreview) {
 | 
				
			||||||
 | 
					          // show popover
 | 
				
			||||||
 | 
					          this.popoverHidden = false
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          this.popover.close()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }, 600);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mouseLeavePreview() {
 | 
				
			||||||
 | 
					    this.mouseOnPreview = false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mouseLeaveCard() {
 | 
				
			||||||
 | 
					    this.popover.close()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user