mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	editable saved views
This commit is contained in:
		@@ -34,24 +34,35 @@
 | 
				
			|||||||
      <a ngbNavLink>Saved views</a>
 | 
					      <a ngbNavLink>Saved views</a>
 | 
				
			||||||
      <ng-template ngbNavContent>
 | 
					      <ng-template ngbNavContent>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <table class="table table-borderless table-sm">
 | 
					        <div formGroupName="savedViews">
 | 
				
			||||||
          <thead>
 | 
					          
 | 
				
			||||||
            <tr>
 | 
					            <div *ngFor="let view of savedViews" [formGroupName]="view.id" class="form-row">
 | 
				
			||||||
              <th scope="col">Title</th>
 | 
					              <div class="form-group col-4 mr-3">
 | 
				
			||||||
              <th scope="col">Show in dashboard</th>
 | 
					                <label for="name_{{view.id}}">Name</label>
 | 
				
			||||||
              <th scope="col">Show in sidebar</th>
 | 
					                <input type="text" class="form-control" formControlName="name" id="name_{{view.id}}">
 | 
				
			||||||
              <th scope="col">Actions</th>
 | 
					              </div>
 | 
				
			||||||
            </tr>
 | 
					
 | 
				
			||||||
          </thead>
 | 
					              <div class="form-group col-auto mr-3">
 | 
				
			||||||
          <tbody>
 | 
					                <label for="show_on_dashboard_{{view.id}}">Appears on</label>
 | 
				
			||||||
            <tr *ngFor="let view of savedViewService.allViews">
 | 
					                <div class="custom-control custom-switch">
 | 
				
			||||||
              <td>{{ view.name }}</td>
 | 
					                  <input type="checkbox" class="custom-control-input" id="show_on_dashboard_{{view.id}}" formControlName="show_on_dashboard">
 | 
				
			||||||
              <td>{{ view.show_on_dashboard | yesno }}</td>
 | 
					                  <label class="custom-control-label" for="show_on_dashboard_{{view.id}}">Show on dashboard</label>
 | 
				
			||||||
              <td>{{ view.show_in_sidebar | yesno }}</td>
 | 
					                </div>
 | 
				
			||||||
              <td><button type="button" class="btn btn-sm btn-outline-danger" (click)="deleteSavedView(view)">Delete</button></td>
 | 
					                <div class="custom-control custom-switch">
 | 
				
			||||||
            </tr>
 | 
					                  <input type="checkbox" class="custom-control-input" id="show_in_sidebar_{{view.id}}" formControlName="show_in_sidebar">
 | 
				
			||||||
          </tbody>
 | 
					                  <label class="custom-control-label" for="show_in_sidebar_{{view.id}}">Show in sidebar</label>
 | 
				
			||||||
        </table>
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              <div class="form-group col-auto">
 | 
				
			||||||
 | 
					                <label for="name_{{view.id}}">Actions</label>
 | 
				
			||||||
 | 
					                <button type="button" class="btn btn-sm btn-outline-danger form-control" (click)="deleteSavedView(view)">Delete</button>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div *ngIf="savedViews.length == 0">No saved views defined.</div>
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
    </li>
 | 
					    </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,10 +11,13 @@ import { Toast, ToastService } from 'src/app/services/toast.service';
 | 
				
			|||||||
  templateUrl: './settings.component.html',
 | 
					  templateUrl: './settings.component.html',
 | 
				
			||||||
  styleUrls: ['./settings.component.scss']
 | 
					  styleUrls: ['./settings.component.scss']
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class SettingsComponent {
 | 
					export class SettingsComponent implements OnInit {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  savedViewGroup = new FormGroup({})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  settingsForm = new FormGroup({
 | 
					  settingsForm = new FormGroup({
 | 
				
			||||||
    'documentListItemPerPage': new FormControl(+localStorage.getItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE) || GENERAL_SETTINGS.DOCUMENT_LIST_SIZE_DEFAULT)
 | 
					    'documentListItemPerPage': new FormControl(+localStorage.getItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE) || GENERAL_SETTINGS.DOCUMENT_LIST_SIZE_DEFAULT),
 | 
				
			||||||
 | 
					    'savedViews': this.savedViewGroup
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
@@ -23,14 +26,40 @@ export class SettingsComponent {
 | 
				
			|||||||
    private toastService: ToastService
 | 
					    private toastService: ToastService
 | 
				
			||||||
  ) { }
 | 
					  ) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  savedViews: PaperlessSavedView[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnInit() {
 | 
				
			||||||
 | 
					    this.savedViewService.listAll().subscribe(r => {
 | 
				
			||||||
 | 
					      this.savedViews = r.results
 | 
				
			||||||
 | 
					      for (let view of this.savedViews) {
 | 
				
			||||||
 | 
					        this.savedViewGroup.addControl(view.id.toString(), new FormGroup({
 | 
				
			||||||
 | 
					          "id": new FormControl(view.id),
 | 
				
			||||||
 | 
					          "name": new FormControl(view.name),
 | 
				
			||||||
 | 
					          "show_on_dashboard": new FormControl(view.show_on_dashboard),
 | 
				
			||||||
 | 
					          "show_in_sidebar": new FormControl(view.show_in_sidebar)
 | 
				
			||||||
 | 
					        }))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  deleteSavedView(savedView: PaperlessSavedView) {
 | 
					  deleteSavedView(savedView: PaperlessSavedView) {
 | 
				
			||||||
    this.savedViewService.delete(savedView).subscribe(() => {
 | 
					    this.savedViewService.delete(savedView).subscribe(() => {
 | 
				
			||||||
 | 
					      this.savedViewGroup.removeControl(savedView.id.toString())
 | 
				
			||||||
 | 
					      this.savedViews.splice(this.savedViews.indexOf(savedView), 1)
 | 
				
			||||||
      this.toastService.showToast(Toast.make("Information", `Saved view "${savedView.name} deleted.`))
 | 
					      this.toastService.showToast(Toast.make("Information", `Saved view "${savedView.name} deleted.`))
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  saveSettings() {
 | 
					  saveSettings() {
 | 
				
			||||||
 | 
					    let x = []
 | 
				
			||||||
 | 
					    for (let id in this.savedViewGroup.value) {
 | 
				
			||||||
 | 
					      x.push(this.savedViewGroup.value[id])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.savedViewService.patchMany(x).subscribe(s => {
 | 
				
			||||||
 | 
					      this.toastService.showToast(Toast.make("Information", "Settings saved successfully."))
 | 
				
			||||||
      localStorage.setItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE, this.settingsForm.value.documentListItemPerPage)
 | 
					      localStorage.setItem(GENERAL_SETTINGS.DOCUMENT_LIST_SIZE, this.settingsForm.value.documentListItemPerPage)
 | 
				
			||||||
      this.documentListViewService.updatePageSize()
 | 
					      this.documentListViewService.updatePageSize()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,4 +92,10 @@ export abstract class AbstractPaperlessService<T extends ObjectWithId> {
 | 
				
			|||||||
    this._listAll = null
 | 
					    this._listAll = null
 | 
				
			||||||
    return this.http.put<T>(this.getResourceUrl(o.id), o)
 | 
					    return this.http.put<T>(this.getResourceUrl(o.id), o)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  patch(o: T): Observable<T> {
 | 
				
			||||||
 | 
					    this._listAll = null
 | 
				
			||||||
 | 
					    return this.http.patch<T>(this.getResourceUrl(o.id), o)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import { HttpClient } from '@angular/common/http';
 | 
					import { HttpClient } from '@angular/common/http';
 | 
				
			||||||
import { Injectable } from '@angular/core';
 | 
					import { Injectable } from '@angular/core';
 | 
				
			||||||
 | 
					import { combineLatest, Observable } from 'rxjs';
 | 
				
			||||||
import { tap } from 'rxjs/operators';
 | 
					import { tap } from 'rxjs/operators';
 | 
				
			||||||
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
 | 
					import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
 | 
				
			||||||
import { AbstractPaperlessService } from './abstract-paperless-service';
 | 
					import { AbstractPaperlessService } from './abstract-paperless-service';
 | 
				
			||||||
@@ -44,6 +45,12 @@ export class SavedViewService extends AbstractPaperlessService<PaperlessSavedVie
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  patchMany(objects: PaperlessSavedView[]): Observable<PaperlessSavedView[]> {
 | 
				
			||||||
 | 
					    return combineLatest(objects.map(o => super.patch(o))).pipe(
 | 
				
			||||||
 | 
					      tap(() => this.reload())
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  delete(o: PaperlessSavedView) {
 | 
					  delete(o: PaperlessSavedView) {
 | 
				
			||||||
    return super.delete(o).pipe(
 | 
					    return super.delete(o).pipe(
 | 
				
			||||||
      tap(() => this.reload())
 | 
					      tap(() => this.reload())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -159,8 +159,12 @@ class SavedViewSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
                  "sort_field", "sort_reverse", "filter_rules"]
 | 
					                  "sort_field", "sort_reverse", "filter_rules"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def update(self, instance, validated_data):
 | 
					    def update(self, instance, validated_data):
 | 
				
			||||||
 | 
					        if 'filter_rules' in validated_data:
 | 
				
			||||||
            rules_data = validated_data.pop('filter_rules')
 | 
					            rules_data = validated_data.pop('filter_rules')
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            rules_data = None
 | 
				
			||||||
        super(SavedViewSerializer, self).update(instance, validated_data)
 | 
					        super(SavedViewSerializer, self).update(instance, validated_data)
 | 
				
			||||||
 | 
					        if rules_data:
 | 
				
			||||||
            SavedViewFilterRule.objects.filter(saved_view=instance).delete()
 | 
					            SavedViewFilterRule.objects.filter(saved_view=instance).delete()
 | 
				
			||||||
            for rule_data in rules_data:
 | 
					            for rule_data in rules_data:
 | 
				
			||||||
                SavedViewFilterRule.objects.create(saved_view=instance, **rule_data)
 | 
					                SavedViewFilterRule.objects.create(saved_view=instance, **rule_data)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user