mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Support navigating directly to comments
This commit is contained in:
		| @@ -65,6 +65,17 @@ const routes: Routes = [ | |||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|  |       { | ||||||
|  |         path: 'documents/:id/:section', | ||||||
|  |         component: DocumentDetailComponent, | ||||||
|  |         canActivate: [PermissionsGuard], | ||||||
|  |         data: { | ||||||
|  |           requiredPermission: { | ||||||
|  |             action: PermissionAction.View, | ||||||
|  |             type: PermissionType.Document, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|       { |       { | ||||||
|         path: 'asn/:id', |         path: 'asn/:id', | ||||||
|         component: DocumentAsnComponent, |         component: DocumentAsnComponent, | ||||||
| @@ -143,17 +154,6 @@ const routes: Routes = [ | |||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|       { |  | ||||||
|         path: 'tasks', |  | ||||||
|         component: TasksComponent, |  | ||||||
|         canActivate: [PermissionsGuard], |  | ||||||
|         data: { |  | ||||||
|           requiredPermission: { |  | ||||||
|             action: PermissionAction.View, |  | ||||||
|             type: PermissionType.PaperlessTask, |  | ||||||
|           }, |  | ||||||
|         }, |  | ||||||
|       }, |  | ||||||
|       { |       { | ||||||
|         path: 'settings/:section', |         path: 'settings/:section', | ||||||
|         component: SettingsComponent, |         component: SettingsComponent, | ||||||
| @@ -171,6 +171,17 @@ const routes: Routes = [ | |||||||
|         component: SettingsComponent, |         component: SettingsComponent, | ||||||
|         canDeactivate: [DirtyFormGuard], |         canDeactivate: [DirtyFormGuard], | ||||||
|       }, |       }, | ||||||
|  |       { | ||||||
|  |         path: 'tasks', | ||||||
|  |         component: TasksComponent, | ||||||
|  |         canActivate: [PermissionsGuard], | ||||||
|  |         data: { | ||||||
|  |           requiredPermission: { | ||||||
|  |             action: PermissionAction.View, | ||||||
|  |             type: PermissionType.PaperlessTask, | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|       { path: 'tasks', component: TasksComponent }, |       { path: 'tasks', component: TasksComponent }, | ||||||
|     ], |     ], | ||||||
|   }, |   }, | ||||||
|   | |||||||
| @@ -67,8 +67,8 @@ | |||||||
|  |  | ||||||
|         <form [formGroup]='documentForm' (ngSubmit)="save()"> |         <form [formGroup]='documentForm' (ngSubmit)="save()"> | ||||||
|  |  | ||||||
|             <ul ngbNav #nav="ngbNav" class="nav-tabs"> |             <ul ngbNav #nav="ngbNav" class="nav-tabs" (navChange)="onNavChange($event)" [(activeId)]="activeNavID"> | ||||||
|                 <li [ngbNavItem]="1"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Details"> | ||||||
|                     <a ngbNavLink i18n>Details</a> |                     <a ngbNavLink i18n>Details</a> | ||||||
|                     <ng-template ngbNavContent> |                     <ng-template ngbNavContent> | ||||||
|  |  | ||||||
| @@ -87,7 +87,7 @@ | |||||||
|                     </ng-template> |                     </ng-template> | ||||||
|                 </li> |                 </li> | ||||||
|  |  | ||||||
|                 <li [ngbNavItem]="2"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Content"> | ||||||
|                     <a ngbNavLink i18n>Content</a> |                     <a ngbNavLink i18n>Content</a> | ||||||
|                     <ng-template ngbNavContent> |                     <ng-template ngbNavContent> | ||||||
|                         <div class="mb-3"> |                         <div class="mb-3"> | ||||||
| @@ -96,7 +96,7 @@ | |||||||
|                     </ng-template> |                     </ng-template> | ||||||
|                 </li> |                 </li> | ||||||
|  |  | ||||||
|                 <li [ngbNavItem]="3"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Metadata"> | ||||||
|                     <a ngbNavLink i18n>Metadata</a> |                     <a ngbNavLink i18n>Metadata</a> | ||||||
|                     <ng-template ngbNavContent> |                     <ng-template ngbNavContent> | ||||||
|  |  | ||||||
| @@ -147,7 +147,7 @@ | |||||||
|                     </ng-template> |                     </ng-template> | ||||||
|                 </li> |                 </li> | ||||||
|  |  | ||||||
|                 <li [ngbNavItem]="4" class="d-md-none"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Preview" class="d-md-none"> | ||||||
|                     <a ngbNavLink i18n>Preview</a> |                     <a ngbNavLink i18n>Preview</a> | ||||||
|                     <ng-template ngbNavContent *ngIf="!pdfPreview.offsetParent"> |                     <ng-template ngbNavContent *ngIf="!pdfPreview.offsetParent"> | ||||||
|                         <div class="position-relative"> |                         <div class="position-relative"> | ||||||
| @@ -171,14 +171,14 @@ | |||||||
|                     </ng-template> |                     </ng-template> | ||||||
|                 </li> |                 </li> | ||||||
|  |  | ||||||
|                 <li [ngbNavItem]="5" *ngIf="commentsEnabled"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Comments" *ngIf="commentsEnabled"> | ||||||
|                     <a ngbNavLink i18n>Comments <span *ngIf="document?.n_comments" class="badge text-bg-secondary ms-1">{{document.n_comments}}</span></a> |                     <a ngbNavLink i18n>Comments <span *ngIf="document?.n_comments" class="badge text-bg-secondary ms-1">{{document.n_comments}}</span></a> | ||||||
|                     <ng-template ngbNavContent> |                     <ng-template ngbNavContent> | ||||||
|                         <app-document-comments [documentId]="documentId" (updated)="commentsUpdated($event)"></app-document-comments> |                         <app-document-comments [documentId]="documentId" (updated)="commentsUpdated($event)"></app-document-comments> | ||||||
|                     </ng-template> |                     </ng-template> | ||||||
|                 </li> |                 </li> | ||||||
|  |  | ||||||
|                 <li [ngbNavItem]="6" *appIfOwner="document"> |                 <li [ngbNavItem]="DocumentDetailNavIDs.Permissions" *appIfOwner="document"> | ||||||
|                     <a ngbNavLink i18n>Permissions</a> |                     <a ngbNavLink i18n>Permissions</a> | ||||||
|                     <ng-template ngbNavContent> |                     <ng-template ngbNavContent> | ||||||
|                         <div class="mb-3"> |                         <div class="mb-3"> | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core' | import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core' | ||||||
| import { FormControl, FormGroup } from '@angular/forms' | import { FormControl, FormGroup } from '@angular/forms' | ||||||
| import { ActivatedRoute, Router } from '@angular/router' | import { ActivatedRoute, Router } from '@angular/router' | ||||||
| import { NgbModal, NgbNav } from '@ng-bootstrap/ng-bootstrap' | import { NgbModal, NgbNav, NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap' | ||||||
| import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent' | import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent' | ||||||
| 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 { PaperlessDocumentMetadata } from 'src/app/data/paperless-document-metadata' | ||||||
| @@ -43,6 +43,15 @@ import { | |||||||
| import { PaperlessUser } from 'src/app/data/paperless-user' | import { PaperlessUser } from 'src/app/data/paperless-user' | ||||||
| import { UserService } from 'src/app/services/rest/user.service' | import { UserService } from 'src/app/services/rest/user.service' | ||||||
|  |  | ||||||
|  | enum DocumentDetailNavIDs { | ||||||
|  |   Details = 1, | ||||||
|  |   Content = 2, | ||||||
|  |   Metadata = 3, | ||||||
|  |   Preview = 4, | ||||||
|  |   Comments = 5, | ||||||
|  |   Permissions = 6, | ||||||
|  | } | ||||||
|  |  | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'app-document-detail', |   selector: 'app-document-detail', | ||||||
|   templateUrl: './document-detail.component.html', |   templateUrl: './document-detail.component.html', | ||||||
| @@ -117,6 +126,8 @@ export class DocumentDetailComponent | |||||||
|  |  | ||||||
|   PermissionAction = PermissionAction |   PermissionAction = PermissionAction | ||||||
|   PermissionType = PermissionType |   PermissionType = PermissionType | ||||||
|  |   DocumentDetailNavIDs = DocumentDetailNavIDs | ||||||
|  |   activeNavID: number | ||||||
|  |  | ||||||
|   constructor( |   constructor( | ||||||
|     private documentsService: DocumentService, |     private documentsService: DocumentService, | ||||||
| @@ -282,6 +293,18 @@ export class DocumentDetailComponent | |||||||
|           this.router.navigate(['404']) |           this.router.navigate(['404']) | ||||||
|         }, |         }, | ||||||
|       }) |       }) | ||||||
|  |  | ||||||
|  |     this.route.paramMap.subscribe((paramMap) => { | ||||||
|  |       const section = paramMap.get('section') | ||||||
|  |       if (section) { | ||||||
|  |         const navIDKey: string = Object.keys(DocumentDetailNavIDs).find( | ||||||
|  |           (navID) => navID.toLowerCase() == section | ||||||
|  |         ) | ||||||
|  |         if (navIDKey) { | ||||||
|  |           this.activeNavID = DocumentDetailNavIDs[navIDKey] | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   ngOnDestroy(): void { |   ngOnDestroy(): void { | ||||||
| @@ -289,6 +312,18 @@ export class DocumentDetailComponent | |||||||
|     this.unsubscribeNotifier.complete() |     this.unsubscribeNotifier.complete() | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   onNavChange(navChangeEvent: NgbNavChangeEvent) { | ||||||
|  |     const [foundNavIDkey] = Object.entries(DocumentDetailNavIDs).find( | ||||||
|  |       ([, navIDValue]) => navIDValue == navChangeEvent.nextId | ||||||
|  |     ) | ||||||
|  |     if (foundNavIDkey) | ||||||
|  |       this.router.navigate([ | ||||||
|  |         'documents', | ||||||
|  |         this.documentId, | ||||||
|  |         foundNavIDkey.toLowerCase(), | ||||||
|  |       ]) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   updateComponent(doc: PaperlessDocument) { |   updateComponent(doc: PaperlessDocument) { | ||||||
|     this.document = doc |     this.document = doc | ||||||
|     this.requiresPassword = false |     this.requiresPassword = false | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
|           <div class="list-group list-group-horizontal border-0 card-info ms-md-auto mt-2 mt-md-0"> |           <div class="list-group list-group-horizontal border-0 card-info ms-md-auto mt-2 mt-md-0"> | ||||||
|             <button *ngIf="document.n_comments" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2" title="View comments" i18n-title> |             <button routerLink="/documents/{{document.id}}/comments" *ngIf="document.n_comments" class="list-group-item btn btn-sm bg-light text-dark p-1 border-0 me-2" title="View comments" i18n-title> | ||||||
|               <svg class="metadata-icon me-2 text-muted" fill="currentColor"> |               <svg class="metadata-icon me-2 text-muted" fill="currentColor"> | ||||||
|                 <use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/> |                 <use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/> | ||||||
|               </svg> |               </svg> | ||||||
|   | |||||||
| @@ -73,12 +73,6 @@ | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   .metadata-icon { |  | ||||||
|     width: 0.9rem; |  | ||||||
|     height: 0.9rem; |  | ||||||
|     padding: 0.05rem; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .search-score { |   .search-score { | ||||||
|     padding-top: 0.35rem !important; |     padding-top: 0.35rem !important; | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -18,13 +18,13 @@ | |||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <div *ngIf="document.n_comments" class="document-card-comments pe-none py-2 px-1"> |     <a routerLink="/documents/{{document.id}}/comments" *ngIf="document.n_comments" class="document-card-comments py-2 px-1"> | ||||||
|     <span class="badge rounded-pill bg-light border text-primary"> |       <span class="badge rounded-pill bg-light border text-primary"> | ||||||
|       <svg class="metadata-icon ms-1 me-1" fill="currentColor"> |       <svg class="metadata-icon ms-1 me-1" fill="currentColor"> | ||||||
|         <use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/> |         <use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/> | ||||||
|       </svg> |       </svg> | ||||||
|       {{document.n_comments}}</span> |       {{document.n_comments}}</span> | ||||||
|     </div> |     </a> | ||||||
|  |  | ||||||
|     <div class="card-body p-2"> |     <div class="card-body p-2"> | ||||||
|       <p class="card-text"> |       <p class="card-text"> | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| .doc-img { | .doc-img { | ||||||
|   object-fit: cover; |   object-fit: cover; | ||||||
|   object-position: top left; |   object-position: top left; | ||||||
|   height: 175px; |   height: 180px; | ||||||
|   mix-blend-mode: multiply; |   mix-blend-mode: multiply; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -66,12 +66,6 @@ | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| .metadata-icon { |  | ||||||
|   width: 0.9rem; |  | ||||||
|   height: 0.9rem; |  | ||||||
|   padding: 0.05rem; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .card-footer .btn { | .card-footer .btn { | ||||||
|   padding-top: .10rem; |   padding-top: .10rem; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -139,6 +139,12 @@ | |||||||
|         [currentSortReverse]="list.sortReverse" |         [currentSortReverse]="list.sortReverse" | ||||||
|         (sort)="onSort($event)" |         (sort)="onSort($event)" | ||||||
|         i18n>Title</th> |         i18n>Title</th> | ||||||
|  |       <th class="d-none d-xl-table-cell" | ||||||
|  |         appSortable="n_comments" | ||||||
|  |         [currentSortField]="list.sortField" | ||||||
|  |         [currentSortReverse]="list.sortReverse" | ||||||
|  |         (sort)="onSort($event)" | ||||||
|  |         i18n>Comments</th> | ||||||
|       <th class="d-none d-xl-table-cell" |       <th class="d-none d-xl-table-cell" | ||||||
|         appSortable="document_type__name" |         appSortable="document_type__name" | ||||||
|         [currentSortField]="list.sortField" |         [currentSortField]="list.sortField" | ||||||
| @@ -184,6 +190,15 @@ | |||||||
|           <a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a> |           <a routerLink="/documents/{{d.id}}" title="Edit document" i18n-title style="overflow-wrap: anywhere;">{{d.title | documentTitle}}</a> | ||||||
|           <app-tag [tag]="t" *ngFor="let t of d.tags$ | async" class="ms-1" clickable="true" linkTitle="Filter by tag" i18n-linkTitle (click)="clickTag(t.id);$event.stopPropagation()"></app-tag> |           <app-tag [tag]="t" *ngFor="let t of d.tags$ | async" class="ms-1" clickable="true" linkTitle="Filter by tag" i18n-linkTitle (click)="clickTag(t.id);$event.stopPropagation()"></app-tag> | ||||||
|         </td> |         </td> | ||||||
|  |         <td class="d-none d-xl-table-cell"> | ||||||
|  |           <a routerLink="/documents/{{d.id}}/comments" *ngIf="d.n_comments" class="btn btn-sm p-0"> | ||||||
|  |             <span class="badge rounded-pill bg-light border text-primary"> | ||||||
|  |             <svg class="metadata-icon ms-1 me-1" fill="currentColor"> | ||||||
|  |               <use xlink:href="assets/bootstrap-icons.svg#chat-left-text"/> | ||||||
|  |             </svg> | ||||||
|  |             {{d.n_comments}}</span> | ||||||
|  |           </a> | ||||||
|  |         </td> | ||||||
|         <td class="d-none d-xl-table-cell"> |         <td class="d-none d-xl-table-cell"> | ||||||
|           <ng-container *ngIf="d.document_type"> |           <ng-container *ngIf="d.document_type"> | ||||||
|             <a (click)="clickDocumentType(d.document_type);$event.stopPropagation()" title="Filter by document type" i18n-title>{{(d.document_type$ | async)?.name}}</a> |             <a (click)="clickDocumentType(d.document_type);$event.stopPropagation()" title="Filter by document type" i18n-title>{{(d.document_type$ | async)?.name}}</a> | ||||||
|   | |||||||
| @@ -436,6 +436,12 @@ textarea, | |||||||
|   height: 12px; |   height: 12px; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .metadata-icon { | ||||||
|  |   width: 0.9rem; | ||||||
|  |   height: 0.9rem; | ||||||
|  |   padding: 0.05rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| table.table { | table.table { | ||||||
|   color: var(--bs-body-color); |   color: var(--bs-body-color); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 shamoon
					shamoon