mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	Refactored the list view logic, editable saved views fixes #58
This commit is contained in:
		@@ -1,4 +1,3 @@
 | 
				
			|||||||
import { DatePipe, formatDate } from '@angular/common';
 | 
					 | 
				
			||||||
import { Component, OnInit } from '@angular/core';
 | 
					import { Component, OnInit } 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';
 | 
				
			||||||
@@ -6,17 +5,14 @@ import { NgbModal } 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 { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
 | 
					import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
 | 
				
			||||||
import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag';
 | 
					 | 
				
			||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
					import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
				
			||||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
 | 
					import { OpenDocumentsService } from 'src/app/services/open-documents.service';
 | 
				
			||||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
 | 
					import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
 | 
				
			||||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
 | 
					import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
 | 
				
			||||||
import { DocumentService } from 'src/app/services/rest/document.service';
 | 
					import { DocumentService } from 'src/app/services/rest/document.service';
 | 
				
			||||||
import { TagService } from 'src/app/services/rest/tag.service';
 | 
					 | 
				
			||||||
import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.component';
 | 
					import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.component';
 | 
				
			||||||
import { CorrespondentEditDialogComponent } from '../manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component';
 | 
					import { CorrespondentEditDialogComponent } from '../manage/correspondent-list/correspondent-edit-dialog/correspondent-edit-dialog.component';
 | 
				
			||||||
import { DocumentTypeEditDialogComponent } from '../manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component';
 | 
					import { DocumentTypeEditDialogComponent } from '../manage/document-type-list/document-type-edit-dialog/document-type-edit-dialog.component';
 | 
				
			||||||
import { TagEditDialogComponent } from '../manage/tag-list/tag-edit-dialog/tag-edit-dialog.component';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
  selector: 'app-document-detail',
 | 
					  selector: 'app-document-detail',
 | 
				
			||||||
@@ -133,8 +129,8 @@ export class DocumentDetailComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  close() {
 | 
					  close() {
 | 
				
			||||||
    this.openDocumentService.closeDocument(this.document)
 | 
					    this.openDocumentService.closeDocument(this.document)
 | 
				
			||||||
    if (this.documentListViewService.viewId) {
 | 
					    if (this.documentListViewService.savedViewId) {
 | 
				
			||||||
      this.router.navigate(['view', this.documentListViewService.viewId])
 | 
					      this.router.navigate(['view', this.documentListViewService.savedViewId])
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.router.navigate(['documents'])
 | 
					      this.router.navigate(['documents'])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,13 +21,12 @@
 | 
				
			|||||||
      </svg>
 | 
					      </svg>
 | 
				
			||||||
    </label>
 | 
					    </label>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div class="btn-group btn-group-toggle ml-2" ngbRadioGroup [(ngModel)]="docs.sortDirection"
 | 
					  <div class="btn-group btn-group-toggle ml-2" ngbRadioGroup [(ngModel)]="list.sortDirection">
 | 
				
			||||||
    *ngIf="!docs.viewId">
 | 
					 | 
				
			||||||
    <div ngbDropdown class="btn-group">
 | 
					    <div ngbDropdown class="btn-group">
 | 
				
			||||||
      <button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>Sort by</button>
 | 
					      <button class="btn btn-outline-primary btn-sm" id="dropdownBasic1" ngbDropdownToggle>Sort by</button>
 | 
				
			||||||
      <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
 | 
					      <div ngbDropdownMenu aria-labelledby="dropdownBasic1">
 | 
				
			||||||
        <button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="setSort(f.field)"
 | 
					        <button *ngFor="let f of getSortFields()" ngbDropdownItem (click)="list.sortField = f.field"
 | 
				
			||||||
          [class.active]="docs.sortField == f.field">{{f.name}}</button>
 | 
					          [class.active]="list.sortField == f.field">{{f.name}}</button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <label ngbButtonLabel class="btn-outline-primary btn-sm">
 | 
					    <label ngbButtonLabel class="btn-outline-primary btn-sm">
 | 
				
			||||||
@@ -43,7 +42,7 @@
 | 
				
			|||||||
      </svg>
 | 
					      </svg>
 | 
				
			||||||
    </label>
 | 
					    </label>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  <div class="btn-group ml-2" *ngIf="!docs.viewId">
 | 
					  <div class="btn-group ml-2">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <button type="button" class="btn btn-sm btn-outline-primary" (click)="showFilter=!showFilter">
 | 
					    <button type="button" class="btn btn-sm btn-outline-primary" (click)="showFilter=!showFilter">
 | 
				
			||||||
      <svg class="toolbaricon" fill="currentColor">
 | 
					      <svg class="toolbaricon" fill="currentColor">
 | 
				
			||||||
@@ -55,9 +54,13 @@
 | 
				
			|||||||
    <div class="btn-group" ngbDropdown role="group">
 | 
					    <div class="btn-group" ngbDropdown role="group">
 | 
				
			||||||
      <button class="btn btn-sm btn-outline-primary dropdown-toggle-split" ngbDropdownToggle></button>
 | 
					      <button class="btn btn-sm btn-outline-primary dropdown-toggle-split" ngbDropdownToggle></button>
 | 
				
			||||||
      <div class="dropdown-menu" ngbDropdownMenu>
 | 
					      <div class="dropdown-menu" ngbDropdownMenu>
 | 
				
			||||||
        <button ngbDropdownItem *ngFor="let config of savedViewConfigService.getConfigs()" (click)="loadViewConfig(config)">{{config.title}}</button>
 | 
					        <ng-container *ngIf="!list.savedViewId" >
 | 
				
			||||||
        <div class="dropdown-divider" *ngIf="savedViewConfigService.getConfigs().length > 0"></div>
 | 
					          <button ngbDropdownItem *ngFor="let config of savedViewConfigService.getConfigs()" (click)="loadViewConfig(config)">{{config.title}}</button>
 | 
				
			||||||
        <button ngbDropdownItem (click)="saveViewConfig()">Save current view</button>
 | 
					          <div class="dropdown-divider" *ngIf="savedViewConfigService.getConfigs().length > 0"></div>
 | 
				
			||||||
 | 
					        </ng-container>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.savedViewId">Save "{{list.savedViewTitle}}"</button>
 | 
				
			||||||
 | 
					        <button ngbDropdownItem (click)="saveViewConfigAs()">Save as...</button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -72,12 +75,12 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="row m-0 justify-content-end">
 | 
					<div class="row m-0 justify-content-end">
 | 
				
			||||||
  <ngb-pagination [pageSize]="docs.currentPageSize" [collectionSize]="docs.collectionSize" [(page)]="docs.currentPage" [maxSize]="5"
 | 
					  <ngb-pagination [pageSize]="list.currentPageSize" [collectionSize]="list.collectionSize" [(page)]="list.currentPage" [maxSize]="5"
 | 
				
			||||||
  [rotate]="true" (pageChange)="reload()" aria-label="Default pagination"></ngb-pagination>
 | 
					  [rotate]="true" (pageChange)="list.reload()" aria-label="Default pagination"></ngb-pagination>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div *ngIf="displayMode == 'largeCards'">
 | 
					<div *ngIf="displayMode == 'largeCards'">
 | 
				
			||||||
  <app-document-card-large *ngFor="let d of docs.documents" [document]="d" [details]="d.content">
 | 
					  <app-document-card-large *ngFor="let d of list.documents" [document]="d" [details]="d.content" (clickTag)="filterByTag($event)" (clickCorrespondent)="filterByCorrespondent($event)">
 | 
				
			||||||
  </app-document-card-large>
 | 
					  </app-document-card-large>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,7 +94,7 @@
 | 
				
			|||||||
    <th class="d-none d-xl-table-cell">Added</th>
 | 
					    <th class="d-none d-xl-table-cell">Added</th>
 | 
				
			||||||
  </thead>
 | 
					  </thead>
 | 
				
			||||||
  <tbody>
 | 
					  <tbody>
 | 
				
			||||||
    <tr *ngFor="let d of docs.documents" routerLink="/documents/{{d.id}}">
 | 
					    <tr *ngFor="let d of list.documents" routerLink="/documents/{{d.id}}">
 | 
				
			||||||
      <td class="d-none d-lg-table-cell">{{d.archive_serial_number}}</td>
 | 
					      <td class="d-none d-lg-table-cell">{{d.archive_serial_number}}</td>
 | 
				
			||||||
      <td class="d-none d-md-table-cell">{{d.correspondent ? d.correspondent.name : ''}}</td>
 | 
					      <td class="d-none d-md-table-cell">{{d.correspondent ? d.correspondent.name : ''}}</td>
 | 
				
			||||||
      <td>{{d.title}}<app-tag [tag]="t" *ngFor="let t of d.tags" class="ml-1"></app-tag></td>
 | 
					      <td>{{d.title}}<app-tag [tag]="t" *ngFor="let t of d.tags" class="ml-1"></app-tag></td>
 | 
				
			||||||
@@ -104,7 +107,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class=" m-n2 row" *ngIf="displayMode == 'smallCards'">
 | 
					<div class=" m-n2 row" *ngIf="displayMode == 'smallCards'">
 | 
				
			||||||
  <app-document-card-small [document]="d" *ngFor="let d of docs.documents"></app-document-card-small>    
 | 
					  <app-document-card-small [document]="d" *ngFor="let d of list.documents" (clickTag)="filterByTag($event)" (clickCorrespondent)="filterByCorrespondent($event)"></app-document-card-small>    
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<p *ngIf="docs.documents.length == 0" class="mx-auto">No results</p>
 | 
					<p *ngIf="list.documents.length == 0" class="mx-auto">No results</p>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,12 @@
 | 
				
			|||||||
import { Component, OnInit } from '@angular/core';
 | 
					import { Component, OnInit } from '@angular/core';
 | 
				
			||||||
import { ActivatedRoute, Router } from '@angular/router';
 | 
					import { ActivatedRoute } from '@angular/router';
 | 
				
			||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 | 
					import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 | 
				
			||||||
import { cloneFilterRules, FilterRule } from 'src/app/data/filter-rule';
 | 
					import { cloneFilterRules, FilterRule } from 'src/app/data/filter-rule';
 | 
				
			||||||
import { SavedViewConfig } from 'src/app/data/saved-view-config';
 | 
					import { SavedViewConfig } from 'src/app/data/saved-view-config';
 | 
				
			||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
					import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
				
			||||||
import { DOCUMENT_SORT_FIELDS } from 'src/app/services/rest/document.service';
 | 
					import { DOCUMENT_SORT_FIELDS } from 'src/app/services/rest/document.service';
 | 
				
			||||||
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
 | 
					import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
 | 
				
			||||||
 | 
					import { Toast, ToastService } from 'src/app/services/toast.service';
 | 
				
			||||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component';
 | 
					import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@@ -16,9 +17,10 @@ import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-vi
 | 
				
			|||||||
export class DocumentListComponent implements OnInit {
 | 
					export class DocumentListComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    public docs: DocumentListViewService,
 | 
					    public list: DocumentListViewService,
 | 
				
			||||||
    public savedViewConfigService: SavedViewConfigService,
 | 
					    public savedViewConfigService: SavedViewConfigService,
 | 
				
			||||||
    public route: ActivatedRoute,
 | 
					    public route: ActivatedRoute,
 | 
				
			||||||
 | 
					    private toastService: ToastService,
 | 
				
			||||||
    public modalService: NgbModal) { }
 | 
					    public modalService: NgbModal) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  displayMode = 'smallCards' // largeCards, smallCards, details
 | 
					  displayMode = 'smallCards' // largeCards, smallCards, details
 | 
				
			||||||
@@ -27,17 +29,13 @@ export class DocumentListComponent implements OnInit {
 | 
				
			|||||||
  showFilter = false
 | 
					  showFilter = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getTitle() {
 | 
					  getTitle() {
 | 
				
			||||||
    return this.docs.viewConfigOverride ? this.docs.viewConfigOverride.title : "Documents"
 | 
					    return this.list.savedViewTitle || "Documents"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getSortFields() {
 | 
					  getSortFields() {
 | 
				
			||||||
    return DOCUMENT_SORT_FIELDS
 | 
					    return DOCUMENT_SORT_FIELDS
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setSort(field: string) {
 | 
					 | 
				
			||||||
    this.docs.sortField = field
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  saveDisplayMode() {
 | 
					  saveDisplayMode() {
 | 
				
			||||||
    localStorage.setItem('document-list:displayMode', this.displayMode)
 | 
					    localStorage.setItem('document-list:displayMode', this.displayMode)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -48,39 +46,42 @@ export class DocumentListComponent implements OnInit {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    this.route.paramMap.subscribe(params => {
 | 
					    this.route.paramMap.subscribe(params => {
 | 
				
			||||||
      if (params.has('id')) {
 | 
					      if (params.has('id')) {
 | 
				
			||||||
        this.docs.viewConfigOverride = this.savedViewConfigService.getConfig(params.get('id'))
 | 
					        this.list.savedView = this.savedViewConfigService.getConfig(params.get('id'))
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        this.filterRules = this.docs.filterRules
 | 
					        this.list.savedView = null
 | 
				
			||||||
        this.showFilter = this.filterRules.length > 0
 | 
					 | 
				
			||||||
        this.docs.viewConfigOverride = null
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.reload()
 | 
					      this.filterRules = this.list.filterRules
 | 
				
			||||||
 | 
					      //this.showFilter = this.filterRules.length > 0
 | 
				
			||||||
 | 
					      // prevents temporarily visible results from previous views
 | 
				
			||||||
 | 
					      this.list.documents = []
 | 
				
			||||||
 | 
					      this.list.reload()
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  reload() {
 | 
					 | 
				
			||||||
    this.docs.reload()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  applyFilterRules() {
 | 
					  applyFilterRules() {
 | 
				
			||||||
    this.docs.filterRules = this.filterRules
 | 
					    this.list.filterRules = this.filterRules
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadViewConfig(config: SavedViewConfig) {
 | 
					  loadViewConfig(config: SavedViewConfig) {
 | 
				
			||||||
    this.filterRules = cloneFilterRules(config.filterRules)
 | 
					    this.filterRules = cloneFilterRules(config.filterRules)
 | 
				
			||||||
    this.docs.loadViewConfig(config)
 | 
					    this.list.load(config)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  saveViewConfig() {
 | 
					  saveViewConfig() {
 | 
				
			||||||
 | 
					    this.savedViewConfigService.updateConfig(this.list.savedView)
 | 
				
			||||||
 | 
					    this.toastService.showToast(Toast.make("Information", `View "${this.list.savedView.title}" saved successfully.`))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  saveViewConfigAs() {
 | 
				
			||||||
    let modal = this.modalService.open(SaveViewConfigDialogComponent, {backdrop: 'static'})
 | 
					    let modal = this.modalService.open(SaveViewConfigDialogComponent, {backdrop: 'static'})
 | 
				
			||||||
    modal.componentInstance.saveClicked.subscribe(formValue => {
 | 
					    modal.componentInstance.saveClicked.subscribe(formValue => {
 | 
				
			||||||
      this.savedViewConfigService.saveConfig({
 | 
					      this.savedViewConfigService.newConfig({
 | 
				
			||||||
        title: formValue.title,
 | 
					        title: formValue.title,
 | 
				
			||||||
        showInDashboard: formValue.showInDashboard,
 | 
					        showInDashboard: formValue.showInDashboard,
 | 
				
			||||||
        showInSideBar: formValue.showInSideBar,
 | 
					        showInSideBar: formValue.showInSideBar,
 | 
				
			||||||
        filterRules: this.docs.filterRules,
 | 
					        filterRules: this.list.filterRules,
 | 
				
			||||||
        sortDirection: this.docs.sortDirection,
 | 
					        sortDirection: this.list.sortDirection,
 | 
				
			||||||
        sortField: this.docs.sortField
 | 
					        sortField: this.list.sortField
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      modal.close()
 | 
					      modal.close()
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,12 @@ import { DOCUMENT_LIST_SERVICE, GENERAL_SETTINGS } from '../data/storage-keys';
 | 
				
			|||||||
import { DocumentService } from './rest/document.service';
 | 
					import { DocumentService } from './rest/document.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * This service manages the document list which is displayed using the document list view.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * This service also serves saved views by transparently switching between the document list
 | 
				
			||||||
 | 
					 * and saved views on request. See below.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
@Injectable({
 | 
					@Injectable({
 | 
				
			||||||
  providedIn: 'root'
 | 
					  providedIn: 'root'
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@@ -14,80 +20,127 @@ export class DocumentListViewService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  static DEFAULT_SORT_FIELD = 'created'
 | 
					  static DEFAULT_SORT_FIELD = 'created'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  isReloading: boolean = false
 | 
				
			||||||
  documents: PaperlessDocument[] = []
 | 
					  documents: PaperlessDocument[] = []
 | 
				
			||||||
  currentPage = 1
 | 
					  currentPage = 1
 | 
				
			||||||
  currentPageSize: number = +localStorage.getItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE) || GENERAL_SETTINGS.DOCUMENT_LIST_SIZE_DEFAULT
 | 
					  currentPageSize: number = +localStorage.getItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE) || GENERAL_SETTINGS.DOCUMENT_LIST_SIZE_DEFAULT
 | 
				
			||||||
  collectionSize: number
 | 
					  collectionSize: number
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  private currentViewConfig: SavedViewConfig
 | 
					  /**
 | 
				
			||||||
  //TODO: make private
 | 
					   * This is the current config for the document list. The service will always remember the last settings used for the document list.
 | 
				
			||||||
  viewConfigOverride: SavedViewConfig
 | 
					   */
 | 
				
			||||||
 | 
					  private _documentListViewConfig: SavedViewConfig
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * Optionally, this is the currently selected saved view, which might be null.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  private _savedViewConfig: SavedViewConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get viewId() {
 | 
					  get savedView() {
 | 
				
			||||||
    return this.viewConfigOverride?.id
 | 
					    return this._savedViewConfig
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  set savedView(value) {
 | 
				
			||||||
 | 
					    if (value) {
 | 
				
			||||||
 | 
					      //this is here so that we don't modify value, which might be the actual instance of the saved view.
 | 
				
			||||||
 | 
					      this._savedViewConfig = Object.assign({}, value)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this._savedViewConfig = null
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get savedViewId() {
 | 
				
			||||||
 | 
					    return this.savedView?.id
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get savedViewTitle() {
 | 
				
			||||||
 | 
					    return this.savedView?.title
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get documentListView() {
 | 
				
			||||||
 | 
					    return this._documentListViewConfig
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  set documentListView(value) {
 | 
				
			||||||
 | 
					    if (value) {
 | 
				
			||||||
 | 
					      this._documentListViewConfig = Object.assign({}, value)
 | 
				
			||||||
 | 
					      this.saveDocumentListView()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * This is what switches between the saved views and the document list view. Everything on the document list uses
 | 
				
			||||||
 | 
					   * this property to determine the settings for the currently displayed document list.
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  get view() {
 | 
				
			||||||
 | 
					    return this.savedView || this.documentListView
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  load(config: SavedViewConfig) {
 | 
				
			||||||
 | 
					    this.view.filterRules = cloneFilterRules(config.filterRules)
 | 
				
			||||||
 | 
					    this.view.sortDirection = config.sortDirection
 | 
				
			||||||
 | 
					    this.view.sortField = config.sortField
 | 
				
			||||||
 | 
					    this.reload()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  reload(onFinish?) {
 | 
					  reload(onFinish?) {
 | 
				
			||||||
    let viewConfig = this.viewConfigOverride || this.currentViewConfig
 | 
					    this.isReloading = true
 | 
				
			||||||
 | 
					 | 
				
			||||||
    this.documentService.list(
 | 
					    this.documentService.list(
 | 
				
			||||||
      this.currentPage,
 | 
					      this.currentPage,
 | 
				
			||||||
      this.currentPageSize,
 | 
					      this.currentPageSize,
 | 
				
			||||||
      viewConfig.sortField,
 | 
					      this.view.sortField,
 | 
				
			||||||
      viewConfig.sortDirection,
 | 
					      this.view.sortDirection,
 | 
				
			||||||
      viewConfig.filterRules).subscribe(
 | 
					      this.view.filterRules).subscribe(
 | 
				
			||||||
        result => {
 | 
					        result => {
 | 
				
			||||||
          this.collectionSize = result.count
 | 
					          this.collectionSize = result.count
 | 
				
			||||||
          this.documents = result.results
 | 
					          this.documents = result.results
 | 
				
			||||||
          if (onFinish) {
 | 
					          if (onFinish) {
 | 
				
			||||||
            onFinish()
 | 
					            onFinish()
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          this.isReloading = false
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        error => {
 | 
					        error => {
 | 
				
			||||||
          if (error.error['detail'] == 'Invalid page.') {
 | 
					          if (error.error['detail'] == 'Invalid page.') {
 | 
				
			||||||
            this.currentPage = 1
 | 
					            this.currentPage = 1
 | 
				
			||||||
            this.reload()
 | 
					            this.reload()
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          this.isReloading = false
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  set filterRules(filterRules: FilterRule[]) {
 | 
					  set filterRules(filterRules: FilterRule[]) {
 | 
				
			||||||
    this.currentViewConfig.filterRules = cloneFilterRules(filterRules)
 | 
					    //we're going to clone the filterRules object, since we don't
 | 
				
			||||||
    this.saveCurrentViewConfig()
 | 
					    //want changes in the filter editor to propagate into here right away.
 | 
				
			||||||
 | 
					    this.view.filterRules = cloneFilterRules(filterRules)
 | 
				
			||||||
    this.reload()
 | 
					    this.reload()
 | 
				
			||||||
 | 
					    this.saveDocumentListView()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get filterRules(): FilterRule[] {
 | 
					  get filterRules(): FilterRule[] {
 | 
				
			||||||
    return cloneFilterRules(this.currentViewConfig.filterRules)
 | 
					    return cloneFilterRules(this.view.filterRules)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  set sortField(field: string) {
 | 
					  set sortField(field: string) {
 | 
				
			||||||
    this.currentViewConfig.sortField = field
 | 
					    this.view.sortField = field
 | 
				
			||||||
    this.saveCurrentViewConfig()
 | 
					    this.saveDocumentListView()
 | 
				
			||||||
    this.reload()
 | 
					    this.reload()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get sortField(): string {
 | 
					  get sortField(): string {
 | 
				
			||||||
    return this.currentViewConfig.sortField
 | 
					    return this.view.sortField
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  set sortDirection(direction: string) {
 | 
					  set sortDirection(direction: string) {
 | 
				
			||||||
    this.currentViewConfig.sortDirection = direction
 | 
					    this.view.sortDirection = direction
 | 
				
			||||||
    this.saveCurrentViewConfig()
 | 
					    this.saveDocumentListView()
 | 
				
			||||||
    this.reload()
 | 
					    this.reload()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get sortDirection(): string {
 | 
					  get sortDirection(): string {
 | 
				
			||||||
    return this.currentViewConfig.sortDirection
 | 
					    return this.view.sortDirection
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  loadViewConfig(config: SavedViewConfig) {
 | 
					  private saveDocumentListView() {
 | 
				
			||||||
    Object.assign(this.currentViewConfig, config)
 | 
					    sessionStorage.setItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG, JSON.stringify(this.documentListView))
 | 
				
			||||||
    this.reload()
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private saveCurrentViewConfig() {
 | 
					 | 
				
			||||||
    sessionStorage.setItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG, JSON.stringify(this.currentViewConfig))
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getLastPage(): number {
 | 
					  getLastPage(): number {
 | 
				
			||||||
@@ -134,21 +187,21 @@ export class DocumentListViewService {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(private documentService: DocumentService) { 
 | 
					  constructor(private documentService: DocumentService) { 
 | 
				
			||||||
    let currentViewConfigJson = sessionStorage.getItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG)
 | 
					    let documentListViewConfigJson = sessionStorage.getItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG)
 | 
				
			||||||
    if (currentViewConfigJson) {
 | 
					    if (documentListViewConfigJson) {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        this.currentViewConfig = JSON.parse(currentViewConfigJson)
 | 
					        this.documentListView = JSON.parse(documentListViewConfigJson)
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
        sessionStorage.removeItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG)
 | 
					        sessionStorage.removeItem(DOCUMENT_LIST_SERVICE.CURRENT_VIEW_CONFIG)
 | 
				
			||||||
        this.currentViewConfig = null
 | 
					        this.documentListView = null
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!this.currentViewConfig) {
 | 
					    if (!this.documentListView) {
 | 
				
			||||||
      this.currentViewConfig = {
 | 
					      this.documentListView = {
 | 
				
			||||||
        filterRules: [],
 | 
					        filterRules: [],
 | 
				
			||||||
        sortDirection: 'des',
 | 
					        sortDirection: 'des',
 | 
				
			||||||
        sortField: 'created'
 | 
					        sortField: 'created'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,13 +36,21 @@ export class SavedViewConfigService {
 | 
				
			|||||||
    return this.configs.find(sf => sf.id == id)
 | 
					    return this.configs.find(sf => sf.id == id)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  saveConfig(config: SavedViewConfig) {
 | 
					  newConfig(config: SavedViewConfig) {
 | 
				
			||||||
    config.id = uuidv4()
 | 
					    config.id = uuidv4()
 | 
				
			||||||
    this.configs.push(config)
 | 
					    this.configs.push(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.save()
 | 
					    this.save()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  updateConfig(config: SavedViewConfig) {
 | 
				
			||||||
 | 
					    let savedConfig = this.configs.find(c => c.id == config.id)
 | 
				
			||||||
 | 
					    if (savedConfig) {
 | 
				
			||||||
 | 
					      Object.assign(savedConfig, config)
 | 
				
			||||||
 | 
					      this.save()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private save() {
 | 
					  private save() {
 | 
				
			||||||
    localStorage.setItem('saved-view-config-service:savedConfigs', JSON.stringify(this.configs))
 | 
					    localStorage.setItem('saved-view-config-service:savedConfigs', JSON.stringify(this.configs))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user