From d1e10754a515183ae01fe70aef19c819eefbf60d Mon Sep 17 00:00:00 2001 From: Jonas Winkler Date: Fri, 30 Oct 2020 22:46:43 +0100 Subject: [PATCH] Saved views, some refactoring --- src-ui/src/app/app-routing.module.ts | 2 +- src-ui/src/app/app.module.ts | 4 +- .../app-frame/app-frame.component.html | 14 ++++ .../app-frame/app-frame.component.ts | 9 ++- .../edit-dialog/edit-dialog.component.ts | 6 +- .../common/input/select/select.component.ts | 3 +- .../components/common/tag/tag.component.ts | 4 +- .../document-detail.component.ts | 5 +- .../document-list.component.html | 65 ++++++++------- .../document-list/document-list.component.ts | 53 ++++++++++-- .../save-view-config-dialog.component.css | 0 .../save-view-config-dialog.component.html | 17 ++++ .../save-view-config-dialog.component.spec.ts | 25 ++++++ .../save-view-config-dialog.component.ts | 33 ++++++++ .../filter-editor.component.html | 2 +- .../filter-editor/filter-editor.component.ts | 80 +++---------------- .../generic-list/generic-list.component.ts | 6 +- .../manage/settings/settings.component.html | 35 +++++++- .../manage/settings/settings.component.ts | 12 ++- .../tag-edit-dialog.component.ts | 6 +- .../manage/tag-list/tag-list.component.ts | 4 +- src-ui/src/app/data/filter-rule-type.ts | 31 +++++++ src-ui/src/app/data/filter-rule.ts | 23 ++++++ src-ui/src/app/data/matching-model.spec.ts | 7 -- src-ui/src/app/data/matching-model.ts | 31 +++---- src-ui/src/app/data/object-with-id.spec.ts | 7 -- src-ui/src/app/data/object-with-id.ts | 2 +- .../app/data/paperless-correspondent.spec.ts | 7 -- .../src/app/data/paperless-correspondent.ts | 2 +- .../app/data/paperless-document-type.spec.ts | 7 -- .../src/app/data/paperless-document-type.ts | 2 +- .../src/app/data/paperless-document.spec.ts | 7 -- src-ui/src/app/data/paperless-document.ts | 2 +- src-ui/src/app/data/paperless-log.spec.ts | 7 -- src-ui/src/app/data/paperless-log.ts | 2 +- src-ui/src/app/data/paperless-tag.spec.ts | 7 -- src-ui/src/app/data/paperless-tag.ts | 33 ++++---- src-ui/src/app/data/results.spec.ts | 7 -- src-ui/src/app/data/results.ts | 2 +- src-ui/src/app/data/saved-view-config.ts | 19 +++++ .../services/document-list-view.service.ts | 33 +++++--- .../saved-view-config.service.spec.ts | 16 ++++ .../app/services/saved-view-config.service.ts | 54 +++++++++++++ 43 files changed, 461 insertions(+), 232 deletions(-) create mode 100644 src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.css create mode 100644 src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html create mode 100644 src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.spec.ts create mode 100644 src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts create mode 100644 src-ui/src/app/data/filter-rule-type.ts create mode 100644 src-ui/src/app/data/filter-rule.ts delete mode 100644 src-ui/src/app/data/matching-model.spec.ts delete mode 100644 src-ui/src/app/data/object-with-id.spec.ts delete mode 100644 src-ui/src/app/data/paperless-correspondent.spec.ts delete mode 100644 src-ui/src/app/data/paperless-document-type.spec.ts delete mode 100644 src-ui/src/app/data/paperless-document.spec.ts delete mode 100644 src-ui/src/app/data/paperless-log.spec.ts delete mode 100644 src-ui/src/app/data/paperless-tag.spec.ts delete mode 100644 src-ui/src/app/data/results.spec.ts create mode 100644 src-ui/src/app/data/saved-view-config.ts create mode 100644 src-ui/src/app/services/saved-view-config.service.spec.ts create mode 100644 src-ui/src/app/services/saved-view-config.service.ts diff --git a/src-ui/src/app/app-routing.module.ts b/src-ui/src/app/app-routing.module.ts index f1398e8f1..fde8fd31f 100644 --- a/src-ui/src/app/app-routing.module.ts +++ b/src-ui/src/app/app-routing.module.ts @@ -19,7 +19,7 @@ const routes: Routes = [ {path: '', component: AppFrameComponent, children: [ {path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuardService] }, {path: 'documents', component: DocumentListComponent, canActivate: [AuthGuardService] }, - {path: 'view/:name', component: DocumentListComponent, canActivate: [AuthGuardService] }, + {path: 'view/:id', component: DocumentListComponent, canActivate: [AuthGuardService] }, {path: 'search', component: SearchComponent, canActivate: [AuthGuardService] }, {path: 'documents/:id', component: DocumentDetailComponent, canActivate: [AuthGuardService] }, diff --git a/src-ui/src/app/app.module.ts b/src-ui/src/app/app.module.ts index 73c3244e3..3c79fae30 100644 --- a/src-ui/src/app/app.module.ts +++ b/src-ui/src/app/app.module.ts @@ -36,6 +36,7 @@ import { NgxFileDropModule } from 'ngx-file-drop'; import { TextComponent } from './components/common/input/text/text.component'; import { SelectComponent } from './components/common/input/select/select.component'; import { CheckComponent } from './components/common/input/check/check.component'; +import { SaveViewConfigDialogComponent } from './components/document-list/save-view-config-dialog/save-view-config-dialog.component'; @NgModule({ declarations: [ @@ -66,7 +67,8 @@ import { CheckComponent } from './components/common/input/check/check.component' DocumentCardSmallComponent, TextComponent, SelectComponent, - CheckComponent + CheckComponent, + SaveViewConfigDialogComponent ], imports: [ BrowserModule, diff --git a/src-ui/src/app/components/app-frame/app-frame.component.html b/src-ui/src/app/components/app-frame/app-frame.component.html index c4158bf9c..fb13b90ff 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.html +++ b/src-ui/src/app/components/app-frame/app-frame.component.html @@ -43,6 +43,20 @@ + + + diff --git a/src-ui/src/app/components/app-frame/app-frame.component.ts b/src-ui/src/app/components/app-frame/app-frame.component.ts index 33a13b384..595da5b1d 100644 --- a/src-ui/src/app/components/app-frame/app-frame.component.ts +++ b/src-ui/src/app/components/app-frame/app-frame.component.ts @@ -7,6 +7,7 @@ import { PaperlessDocument } from 'src/app/data/paperless-document'; import { AuthService } from 'src/app/services/auth.service'; import { OpenDocumentsService } from 'src/app/services/open-documents.service'; import { SearchService } from 'src/app/services/rest/search.service'; +import { SavedViewConfigService } from 'src/app/services/saved-view-config.service'; @Component({ selector: 'app-app-frame', @@ -15,7 +16,13 @@ import { SearchService } from 'src/app/services/rest/search.service'; }) export class AppFrameComponent implements OnInit, OnDestroy { - constructor (public router: Router, private openDocumentsService: OpenDocumentsService, private authService: AuthService, private searchService: SearchService) { + constructor ( + public router: Router, + private openDocumentsService: OpenDocumentsService, + private authService: AuthService, + private searchService: SearchService, + public viewConfigService: SavedViewConfigService + ) { } searchField = new FormControl('') diff --git a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts index 153f588a3..ba0d90847 100644 --- a/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts +++ b/src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts @@ -1,8 +1,8 @@ import { Directive, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { Form, FormGroup } from '@angular/forms'; +import { FormGroup } from '@angular/forms'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { Observable } from 'rxjs'; -import { MatchingModel } from 'src/app/data/matching-model'; +import { MATCHING_ALGORITHMS } from 'src/app/data/matching-model'; import { ObjectWithId } from 'src/app/data/object-with-id'; import { AbstractPaperlessService } from 'src/app/services/rest/abstract-paperless-service'; import { Toast, ToastService } from 'src/app/services/toast.service'; @@ -47,7 +47,7 @@ export abstract class EditDialogComponent implements OnI } getMatchingAlgorithms() { - return MatchingModel.MATCHING_ALGORITHMS + return MATCHING_ALGORITHMS } save() { diff --git a/src-ui/src/app/components/common/input/select/select.component.ts b/src-ui/src/app/components/common/input/select/select.component.ts index a53566dab..c8e213722 100644 --- a/src-ui/src/app/components/common/input/select/select.component.ts +++ b/src-ui/src/app/components/common/input/select/select.component.ts @@ -1,6 +1,5 @@ import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'; -import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { v4 as uuidv4 } from 'uuid'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { AbstractInputComponent } from '../abstract-input'; @Component({ diff --git a/src-ui/src/app/components/common/tag/tag.component.ts b/src-ui/src/app/components/common/tag/tag.component.ts index bb4c2a15c..a7f81fa0a 100644 --- a/src-ui/src/app/components/common/tag/tag.component.ts +++ b/src-ui/src/app/components/common/tag/tag.component.ts @@ -1,5 +1,5 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { PaperlessTag } from 'src/app/data/paperless-tag'; +import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag'; @Component({ selector: 'app-tag', @@ -23,7 +23,7 @@ export class TagComponent implements OnInit { } getColour() { - return PaperlessTag.COLOURS.find(c => c.id == this.tag.colour) + return TAG_COLOURS.find(c => c.id == this.tag.colour) } } diff --git a/src-ui/src/app/components/document-detail/document-detail.component.ts b/src-ui/src/app/components/document-detail/document-detail.component.ts index 8ae46b9c8..6e0e51300 100644 --- a/src-ui/src/app/components/document-detail/document-detail.component.ts +++ b/src-ui/src/app/components/document-detail/document-detail.component.ts @@ -6,7 +6,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'; import { PaperlessDocument } from 'src/app/data/paperless-document'; import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'; -import { PaperlessTag } from 'src/app/data/paperless-tag'; +import { TAG_COLOURS, PaperlessTag } from 'src/app/data/paperless-tag'; import { DocumentListViewService } from 'src/app/services/document-list-view.service'; import { OpenDocumentsService } from 'src/app/services/open-documents.service'; import { CorrespondentService } from 'src/app/services/rest/correspondent.service'; @@ -17,6 +17,7 @@ import { DeleteDialogComponent } from '../common/delete-dialog/delete-dialog.com 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 { TagEditDialogComponent } from '../manage/tag-list/tag-edit-dialog/tag-edit-dialog.component'; + @Component({ selector: 'app-document-detail', templateUrl: './document-detail.component.html', @@ -116,7 +117,7 @@ export class DocumentDetailComponent implements OnInit { } getColour(id: number) { - return PaperlessTag.COLOURS.find(c => c.id == this.getTag(id).colour) + return TAG_COLOURS.find(c => c.id == this.getTag(id).colour) } addTag(id: number) { diff --git a/src-ui/src/app/components/document-list/document-list.component.html b/src-ui/src/app/components/document-list/document-list.component.html index f7558be49..b66cfbfa0 100644 --- a/src-ui/src/app/components/document-list/document-list.component.html +++ b/src-ui/src/app/components/document-list/document-list.component.html @@ -1,74 +1,83 @@ - + -
+
-
+
- +
- +
+ + + +
+ + +
+ + +
Filter
- +
- +
- +
diff --git a/src-ui/src/app/components/document-list/document-list.component.ts b/src-ui/src/app/components/document-list/document-list.component.ts index 927b9aa43..21537d224 100644 --- a/src-ui/src/app/components/document-list/document-list.component.ts +++ b/src-ui/src/app/components/document-list/document-list.component.ts @@ -1,6 +1,11 @@ import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { cloneFilterRules, FilterRule } from 'src/app/data/filter-rule'; +import { SavedViewConfig } from 'src/app/data/saved-view-config'; import { DocumentListViewService } from 'src/app/services/document-list-view.service'; -import { FilterRuleSet } from '../filter-editor/filter-editor.component'; +import { SavedViewConfigService } from 'src/app/services/saved-view-config.service'; +import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component'; @Component({ selector: 'app-document-list', @@ -10,11 +15,14 @@ import { FilterRuleSet } from '../filter-editor/filter-editor.component'; export class DocumentListComponent implements OnInit { constructor( - public docs: DocumentListViewService) { } + public docs: DocumentListViewService, + public savedViewConfigService: SavedViewConfigService, + public route: ActivatedRoute, + public modalService: NgbModal) { } displayMode = 'smallCards' // largeCards, smallCards, details - filter = new FilterRuleSet() + filterRules: FilterRule[] = [] showFilter = false getSortFields() { @@ -34,18 +42,47 @@ export class DocumentListComponent implements OnInit { if (localStorage.getItem('document-list:displayMode') != null) { this.displayMode = localStorage.getItem('document-list:displayMode') } - this.filter = this.docs.currentFilter.clone() - this.showFilter = this.filter.rules.length > 0 - this.reload() + this.route.paramMap.subscribe(params => { + if (params.has('id')) { + this.docs.viewConfig = this.savedViewConfigService.getConfig(params.get('id')) + } else { + this.filterRules = cloneFilterRules(this.docs.currentFilterRules) + this.showFilter = this.filterRules.length > 0 + this.docs.viewConfig = null + } + this.reload() + }) } reload() { this.docs.reload() } - applyFilter() { - this.docs.setFilter(this.filter.clone()) + applyFilterRules() { + this.docs.setFilterRules(this.filterRules) this.reload() } + loadViewConfig(config: SavedViewConfig) { + this.filterRules = config.filterRules + this.docs.setFilterRules(config.filterRules) + this.docs.currentSortField = config.sortField + this.docs.currentSortDirection = config.sortDirection + this.reload() + } + + saveViewConfig() { + let modal = this.modalService.open(SaveViewConfigDialogComponent, {backdrop: 'static'}) + modal.componentInstance.saveClicked.subscribe(formValue => { + this.savedViewConfigService.saveConfig({ + filterRules: cloneFilterRules(this.filterRules), + title: formValue.title, + showInDashboard: formValue.showInDashboard, + showInSideBar: formValue.showInSideBar, + sortDirection: this.docs.currentSortDirection, + sortField: this.docs.currentSortField + }) + modal.close() + }) + } } diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.css b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html new file mode 100644 index 000000000..870431096 --- /dev/null +++ b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.html @@ -0,0 +1,17 @@ +
+ + + +
diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.spec.ts b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.spec.ts new file mode 100644 index 000000000..11ac77c0b --- /dev/null +++ b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SaveViewConfigDialogComponent } from './save-view-config-dialog.component'; + +describe('SaveViewConfigDialogComponent', () => { + let component: SaveViewConfigDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SaveViewConfigDialogComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SaveViewConfigDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts new file mode 100644 index 000000000..6fcdbd2c8 --- /dev/null +++ b/src-ui/src/app/components/document-list/save-view-config-dialog/save-view-config-dialog.component.ts @@ -0,0 +1,33 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { FormControl, FormGroup } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'app-save-view-config-dialog', + templateUrl: './save-view-config-dialog.component.html', + styleUrls: ['./save-view-config-dialog.component.css'] +}) +export class SaveViewConfigDialogComponent implements OnInit { + + constructor(private modal: NgbActiveModal) { } + + @Output() + public saveClicked = new EventEmitter() + + saveViewConfigForm = new FormGroup({ + title: new FormControl(''), + showInSideBar: new FormControl(false), + showInDashboard: new FormControl(false), + }) + + ngOnInit(): void { + } + + save() { + this.saveClicked.emit(this.saveViewConfigForm.value) + } + + cancel() { + this.modal.close() + } +} diff --git a/src-ui/src/app/components/filter-editor/filter-editor.component.html b/src-ui/src/app/components/filter-editor/filter-editor.component.html index de65b1150..ee8ee67bb 100644 --- a/src-ui/src/app/components/filter-editor/filter-editor.component.html +++ b/src-ui/src/app/components/filter-editor/filter-editor.component.html @@ -1,4 +1,4 @@ -
+