mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-19 10:19:27 -05:00
many changes to support server side saved views
This commit is contained in:
parent
13d934dc6e
commit
b7126030d1
@ -37,16 +37,16 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted" *ngIf='viewConfigService.getSideBarConfigs().length > 0'>
|
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted" *ngIf='savedViewService.sidebarViews.length > 0'>
|
||||||
<span>Saved views</span>
|
<span>Saved views</span>
|
||||||
</h6>
|
</h6>
|
||||||
<ul class="nav flex-column mb-2">
|
<ul class="nav flex-column mb-2">
|
||||||
<li class="nav-item w-100" *ngFor='let config of viewConfigService.getSideBarConfigs()'>
|
<li class="nav-item w-100" *ngFor="let view of savedViewService.sidebarViews">
|
||||||
<a class="nav-link text-truncate" routerLink="view/{{config.id}}" routerLinkActive="active" (click)="closeMenu()">
|
<a class="nav-link text-truncate" routerLink="view/{{view.id}}" routerLinkActive="active" (click)="closeMenu()">
|
||||||
<svg class="sidebaricon" fill="currentColor">
|
<svg class="sidebaricon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#funnel"/>
|
<use xlink:href="assets/bootstrap-icons.svg#funnel"/>
|
||||||
</svg>
|
</svg>
|
||||||
{{config.title}}
|
{{view.name}}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -5,8 +5,8 @@ import { from, Observable, Subscription } from 'rxjs';
|
|||||||
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
|
||||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
|
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
|
||||||
|
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
|
||||||
import { SearchService } from 'src/app/services/rest/search.service';
|
import { SearchService } from 'src/app/services/rest/search.service';
|
||||||
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
|
|
||||||
import { DocumentDetailComponent } from '../document-detail/document-detail.component';
|
import { DocumentDetailComponent } from '../document-detail/document-detail.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -21,7 +21,7 @@ export class AppFrameComponent implements OnInit, OnDestroy {
|
|||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private openDocumentsService: OpenDocumentsService,
|
private openDocumentsService: OpenDocumentsService,
|
||||||
private searchService: SearchService,
|
private searchService: SearchService,
|
||||||
public viewConfigService: SavedViewConfigService
|
public savedViewService: SavedViewService
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
|
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
|
||||||
|
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
|
|
||||||
@ -12,14 +13,16 @@ import { environment } from 'src/environments/environment';
|
|||||||
export class DashboardComponent implements OnInit {
|
export class DashboardComponent implements OnInit {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public savedViewConfigService: SavedViewConfigService,
|
private savedViewService: SavedViewService,
|
||||||
private titleService: Title) { }
|
private titleService: Title) { }
|
||||||
|
|
||||||
|
|
||||||
savedViews = []
|
savedViews: PaperlessSavedView[] = []
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.savedViews = this.savedViewConfigService.getDashboardConfigs()
|
this.savedViewService.listAll().subscribe(results => {
|
||||||
|
this.savedViews = results.results.filter(savedView => savedView.show_on_dashboard)
|
||||||
|
})
|
||||||
this.titleService.setTitle(`Dashboard - ${environment.appTitle}`)
|
this.titleService.setTitle(`Dashboard - ${environment.appTitle}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<app-widget-frame [title]="savedView.title">
|
<app-widget-frame [title]="savedView.name">
|
||||||
|
|
||||||
<a header-buttons [routerLink]="" (click)="showAll()">Show all</a>
|
<a header-buttons [routerLink]="" (click)="showAll()">Show all</a>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, Input, OnInit } from '@angular/core';
|
import { Component, Input, OnInit } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||||
import { SavedViewConfig } from 'src/app/data/saved-view-config';
|
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||||
|
|
||||||
@ -18,18 +18,18 @@ export class SavedViewWidgetComponent implements OnInit {
|
|||||||
private list: DocumentListViewService) { }
|
private list: DocumentListViewService) { }
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
savedView: SavedViewConfig
|
savedView: PaperlessSavedView
|
||||||
|
|
||||||
documents: PaperlessDocument[] = []
|
documents: PaperlessDocument[] = []
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.documentService.list(1,10,this.savedView.sortField,this.savedView.sortDirection,this.savedView.filterRules).subscribe(result => {
|
this.documentService.list(1,10,this.savedView.sort_field, this.savedView.sort_reverse, this.savedView.filter_rules).subscribe(result => {
|
||||||
this.documents = result.results
|
this.documents = result.results
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
showAll() {
|
showAll() {
|
||||||
if (this.savedView.showInSideBar) {
|
if (this.savedView.show_in_sidebar) {
|
||||||
this.router.navigate(['view', this.savedView.id])
|
this.router.navigate(['view', this.savedView.id])
|
||||||
} else {
|
} else {
|
||||||
this.list.load(this.savedView)
|
this.list.load(this.savedView)
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="btn-group btn-group-toggle ml-2" ngbRadioGroup [(ngModel)]="list.sortDirection">
|
<div class="btn-group btn-group-toggle ml-2" ngbRadioGroup [(ngModel)]="list.sortReverse">
|
||||||
<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" class="shadow">
|
<div ngbDropdownMenu aria-labelledby="dropdownBasic1" class="shadow">
|
||||||
@ -30,13 +30,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
||||||
<input ngbButton type="radio" class="btn btn-sm" value="asc">
|
<input ngbButton type="radio" class="btn btn-sm" [value]="false">
|
||||||
<svg class="toolbaricon" fill="currentColor">
|
<svg class="toolbaricon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-down" />
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-down" />
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
<label ngbButtonLabel class="btn-outline-primary btn-sm">
|
||||||
<input ngbButton type="radio" class="btn btn-sm" value="des">
|
<input ngbButton type="radio" class="btn btn-sm" [value]="true">
|
||||||
<svg class="toolbaricon" fill="currentColor">
|
<svg class="toolbaricon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-up-alt" />
|
<use xlink:href="assets/bootstrap-icons.svg#sort-alpha-up-alt" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -49,8 +49,8 @@
|
|||||||
<button class="btn btn-sm btn-outline-primary dropdown-toggle" ngbDropdownToggle>Views</button>
|
<button class="btn btn-sm btn-outline-primary dropdown-toggle" ngbDropdownToggle>Views</button>
|
||||||
<div class="dropdown-menu shadow" ngbDropdownMenu>
|
<div class="dropdown-menu shadow" ngbDropdownMenu>
|
||||||
<ng-container *ngIf="!list.savedViewId">
|
<ng-container *ngIf="!list.savedViewId">
|
||||||
<button ngbDropdownItem *ngFor="let config of savedViewConfigService.getConfigs()" (click)="loadViewConfig(config)">{{config.title}}</button>
|
<button ngbDropdownItem *ngFor="let view of savedViewService.allViews" (click)="loadViewConfig(view)">{{view.name}}</button>
|
||||||
<div class="dropdown-divider" *ngIf="savedViewConfigService.getConfigs().length > 0"></div>
|
<div class="dropdown-divider" *ngIf="savedViewService.allViews.length > 0"></div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.savedViewId">Save "{{list.savedViewTitle}}"</button>
|
<button ngbDropdownItem (click)="saveViewConfig()" *ngIf="list.savedViewId">Save "{{list.savedViewTitle}}"</button>
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { SavedViewConfig } from 'src/app/data/saved-view-config';
|
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
|
||||||
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 { SavedViewService } from 'src/app/services/rest/saved-view.service';
|
||||||
import { Toast, ToastService } from 'src/app/services/toast.service';
|
import { Toast, ToastService } from 'src/app/services/toast.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
import { FilterEditorComponent } from '../filter-editor/filter-editor.component';
|
import { FilterEditorComponent } from '../filter-editor/filter-editor.component';
|
||||||
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({
|
||||||
selector: 'app-document-list',
|
selector: 'app-document-list',
|
||||||
templateUrl: './document-list.component.html',
|
templateUrl: './document-list.component.html',
|
||||||
@ -19,8 +20,9 @@ export class DocumentListComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public list: DocumentListViewService,
|
public list: DocumentListViewService,
|
||||||
public savedViewConfigService: SavedViewConfigService,
|
public savedViewService: SavedViewService,
|
||||||
public route: ActivatedRoute,
|
public route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
private toastService: ToastService,
|
private toastService: ToastService,
|
||||||
public modalService: NgbModal,
|
public modalService: NgbModal,
|
||||||
private titleService: Title) { }
|
private titleService: Title) { }
|
||||||
@ -51,40 +53,51 @@ export class DocumentListComponent implements OnInit {
|
|||||||
this.displayMode = localStorage.getItem('document-list:displayMode')
|
this.displayMode = localStorage.getItem('document-list:displayMode')
|
||||||
}
|
}
|
||||||
this.route.paramMap.subscribe(params => {
|
this.route.paramMap.subscribe(params => {
|
||||||
|
this.list.clear()
|
||||||
if (params.has('id')) {
|
if (params.has('id')) {
|
||||||
this.list.savedView = this.savedViewConfigService.getConfig(params.get('id'))
|
this.savedViewService.getCached(+params.get('id')).subscribe(view => {
|
||||||
this.titleService.setTitle(`${this.list.savedView.title} - ${environment.appTitle}`)
|
if (!view) {
|
||||||
|
this.router.navigate(["404"])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.list.savedView = view
|
||||||
|
this.titleService.setTitle(`${this.list.savedView.name} - ${environment.appTitle}`)
|
||||||
|
this.list.reload()
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.list.savedView = null
|
this.list.savedView = null
|
||||||
this.titleService.setTitle(`Documents - ${environment.appTitle}`)
|
this.titleService.setTitle(`Documents - ${environment.appTitle}`)
|
||||||
|
this.list.reload()
|
||||||
}
|
}
|
||||||
this.list.clear()
|
|
||||||
this.list.reload()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loadViewConfig(config: SavedViewConfig) {
|
loadViewConfig(view: PaperlessSavedView) {
|
||||||
this.list.load(config)
|
this.list.load(view)
|
||||||
}
|
}
|
||||||
|
|
||||||
saveViewConfig() {
|
saveViewConfig() {
|
||||||
this.savedViewConfigService.updateConfig(this.list.savedView)
|
this.savedViewService.update(this.list.savedView).subscribe(result => {
|
||||||
this.toastService.showToast(Toast.make("Information", `View "${this.list.savedView.title}" saved successfully.`))
|
this.toastService.showToast(Toast.make("Information", `View "${this.list.savedView.name}" saved successfully.`))
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveViewConfigAs() {
|
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.newConfig({
|
this.savedViewService.create({
|
||||||
title: formValue.title,
|
name: formValue.name,
|
||||||
showInDashboard: formValue.showInDashboard,
|
show_on_dashboard: formValue.showOnDashboard,
|
||||||
showInSideBar: formValue.showInSideBar,
|
show_in_sidebar: formValue.showInSideBar,
|
||||||
filterRules: this.list.filterRules,
|
filter_rules: this.list.filterRules,
|
||||||
sortDirection: this.list.sortDirection,
|
sort_reverse: this.list.sortReverse,
|
||||||
sortField: this.list.sortField
|
sort_field: this.list.sortField
|
||||||
|
}).subscribe(() => {
|
||||||
|
modal.close()
|
||||||
})
|
})
|
||||||
modal.close()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<app-input-text title="Title" formControlName="title"></app-input-text>
|
<app-input-text title="Name" formControlName="name"></app-input-text>
|
||||||
<app-input-check title="Show in side bar" formControlName="showInSideBar"></app-input-check>
|
<app-input-check title="Show in side bar" formControlName="showInSideBar"></app-input-check>
|
||||||
<app-input-check title="Show in dashboard" formControlName="showInDashboard"></app-input-check>
|
<app-input-check title="Show on dashboard" formControlName="showOnDashboard"></app-input-check>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-outline-dark" (click)="cancel()">Cancel</button>
|
<button type="button" class="btn btn-outline-dark" (click)="cancel()">Cancel</button>
|
||||||
|
@ -15,9 +15,9 @@ export class SaveViewConfigDialogComponent implements OnInit {
|
|||||||
public saveClicked = new EventEmitter()
|
public saveClicked = new EventEmitter()
|
||||||
|
|
||||||
saveViewConfigForm = new FormGroup({
|
saveViewConfigForm = new FormGroup({
|
||||||
title: new FormControl(''),
|
name: new FormControl(''),
|
||||||
showInSideBar: new FormControl(false),
|
showInSideBar: new FormControl(false),
|
||||||
showInDashboard: new FormControl(false),
|
showOnDashboard: new FormControl(false),
|
||||||
})
|
})
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@ -39,22 +39,22 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get selectedTags(): PaperlessTag[] {
|
get selectedTags(): PaperlessTag[] {
|
||||||
let tagRules: FilterRule[] = this.filterRules.filter(fr => fr.type.id == FILTER_HAS_TAG)
|
let tagRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_HAS_TAG)
|
||||||
return this.tags?.filter(t => tagRules.find(tr => tr.value == t.id))
|
return this.tags?.filter(t => tagRules.find(tr => tr.value == t.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedCorrespondents(): PaperlessCorrespondent[] {
|
get selectedCorrespondents(): PaperlessCorrespondent[] {
|
||||||
let correspondentRules: FilterRule[] = this.filterRules.filter(fr => fr.type.id == FILTER_CORRESPONDENT)
|
let correspondentRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_CORRESPONDENT)
|
||||||
return this.correspondents?.filter(c => correspondentRules.find(cr => cr.value == c.id))
|
return this.correspondents?.filter(c => correspondentRules.find(cr => cr.value == c.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
get selectedDocumentTypes(): PaperlessDocumentType[] {
|
get selectedDocumentTypes(): PaperlessDocumentType[] {
|
||||||
let documentTypeRules: FilterRule[] = this.filterRules.filter(fr => fr.type.id == FILTER_DOCUMENT_TYPE)
|
let documentTypeRules: FilterRule[] = this.filterRules.filter(fr => fr.rule_type == FILTER_DOCUMENT_TYPE)
|
||||||
return this.documentTypes?.filter(dt => documentTypeRules.find(dtr => dtr.value == dt.id))
|
return this.documentTypes?.filter(dt => documentTypeRules.find(dtr => dtr.value == dt.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
get titleFilter() {
|
get titleFilter() {
|
||||||
let existingRule = this.filterRules.find(rule => rule.type.id == FILTER_TITLE)
|
let existingRule = this.filterRules.find(rule => rule.rule_type == FILTER_TITLE)
|
||||||
return existingRule ? existingRule.value : ''
|
return existingRule ? existingRule.value : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,15 +100,15 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
let filterRuleType = FILTER_RULE_TYPES.find(t => t.id == filterRuleTypeID)
|
let filterRuleType = FILTER_RULE_TYPES.find(t => t.id == filterRuleTypeID)
|
||||||
|
|
||||||
let existingRule = this.filterRules.find(rule => rule.type.id == filterRuleTypeID && rule.value == value)
|
let existingRule = this.filterRules.find(rule => rule.rule_type == filterRuleTypeID && rule.value == value)
|
||||||
let existingRuleOfSameType = this.filterRules.find(rule => rule.type.id == filterRuleTypeID)
|
let existingRuleOfSameType = this.filterRules.find(rule => rule.rule_type == filterRuleTypeID)
|
||||||
|
|
||||||
if (existingRule) {
|
if (existingRule) {
|
||||||
// if this exact rule already exists, remove it in all cases.
|
// if this exact rule already exists, remove it in all cases.
|
||||||
this.filterRules.splice(this.filterRules.indexOf(existingRule), 1)
|
this.filterRules.splice(this.filterRules.indexOf(existingRule), 1)
|
||||||
} else if (filterRuleType.multi || !existingRuleOfSameType) {
|
} else if (filterRuleType.multi || !existingRuleOfSameType) {
|
||||||
// if we allow multiple rules per type, or no rule of this type already exists, push a new rule.
|
// if we allow multiple rules per type, or no rule of this type already exists, push a new rule.
|
||||||
this.filterRules.push({type: filterRuleType, value: value})
|
this.filterRules.push({rule_type: filterRuleTypeID, value: value})
|
||||||
} else {
|
} else {
|
||||||
// otherwise (i.e., no multi support AND there's already a rule of this type), update the rule.
|
// otherwise (i.e., no multi support AND there's already a rule of this type), update the rule.
|
||||||
existingRuleOfSameType.value = value
|
existingRuleOfSameType.value = value
|
||||||
@ -117,12 +117,12 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setTitleRule(title: string) {
|
private setTitleRule(title: string) {
|
||||||
let existingRule = this.filterRules.find(rule => rule.type.id == FILTER_TITLE)
|
let existingRule = this.filterRules.find(rule => rule.rule_type == FILTER_TITLE)
|
||||||
|
|
||||||
if (!existingRule && title) {
|
if (!existingRule && title) {
|
||||||
this.filterRules.push({type: FILTER_RULE_TYPES.find(t => t.id == FILTER_TITLE), value: title})
|
this.filterRules.push({rule_type: FILTER_TITLE, value: title})
|
||||||
} else if (existingRule && !title) {
|
} else if (existingRule && !title) {
|
||||||
this.filterRules.splice(this.filterRules.findIndex(rule => rule.type.id == FILTER_TITLE), 1)
|
this.filterRules.splice(this.filterRules.findIndex(rule => rule.rule_type == FILTER_TITLE), 1)
|
||||||
} else if (existingRule && title) {
|
} else if (existingRule && title) {
|
||||||
existingRule.value = title
|
existingRule.value = title
|
||||||
}
|
}
|
||||||
@ -167,7 +167,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dateCreatedBefore(): NgbDateStruct {
|
get dateCreatedBefore(): NgbDateStruct {
|
||||||
let createdBeforeRule: FilterRule = this.filterRules.find(fr => fr.type.id == FILTER_CREATED_BEFORE)
|
let createdBeforeRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_CREATED_BEFORE)
|
||||||
return createdBeforeRule ? {
|
return createdBeforeRule ? {
|
||||||
year: createdBeforeRule.value.substring(0,4),
|
year: createdBeforeRule.value.substring(0,4),
|
||||||
month: createdBeforeRule.value.substring(5,7),
|
month: createdBeforeRule.value.substring(5,7),
|
||||||
@ -176,7 +176,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dateCreatedAfter(): NgbDateStruct {
|
get dateCreatedAfter(): NgbDateStruct {
|
||||||
let createdAfterRule: FilterRule = this.filterRules.find(fr => fr.type.id == FILTER_CREATED_AFTER)
|
let createdAfterRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_CREATED_AFTER)
|
||||||
return createdAfterRule ? {
|
return createdAfterRule ? {
|
||||||
year: createdAfterRule.value.substring(0,4),
|
year: createdAfterRule.value.substring(0,4),
|
||||||
month: createdAfterRule.value.substring(5,7),
|
month: createdAfterRule.value.substring(5,7),
|
||||||
@ -185,7 +185,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dateAddedBefore(): NgbDateStruct {
|
get dateAddedBefore(): NgbDateStruct {
|
||||||
let addedBeforeRule: FilterRule = this.filterRules.find(fr => fr.type.id == FILTER_ADDED_BEFORE)
|
let addedBeforeRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_ADDED_BEFORE)
|
||||||
return addedBeforeRule ? {
|
return addedBeforeRule ? {
|
||||||
year: addedBeforeRule.value.substring(0,4),
|
year: addedBeforeRule.value.substring(0,4),
|
||||||
month: addedBeforeRule.value.substring(5,7),
|
month: addedBeforeRule.value.substring(5,7),
|
||||||
@ -194,7 +194,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get dateAddedAfter(): NgbDateStruct {
|
get dateAddedAfter(): NgbDateStruct {
|
||||||
let addedAfterRule: FilterRule = this.filterRules.find(fr => fr.type.id == FILTER_ADDED_AFTER)
|
let addedAfterRule: FilterRule = this.filterRules.find(fr => fr.rule_type == FILTER_ADDED_AFTER)
|
||||||
return addedAfterRule ? {
|
return addedAfterRule ? {
|
||||||
year: addedAfterRule.value.substring(0,4),
|
year: addedAfterRule.value.substring(0,4),
|
||||||
month: addedAfterRule.value.substring(5,7),
|
month: addedAfterRule.value.substring(5,7),
|
||||||
@ -224,13 +224,13 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
setDateFilter(date: NgbDateStruct, dateRuleTypeID: number) {
|
setDateFilter(date: NgbDateStruct, dateRuleTypeID: number) {
|
||||||
let filterRules = this.filterRules
|
let filterRules = this.filterRules
|
||||||
let existingRule = filterRules.find(rule => rule.type.id == dateRuleTypeID)
|
let existingRule = filterRules.find(rule => rule.rule_type == dateRuleTypeID)
|
||||||
let newValue = `${date.year}-${date.month.toString().padStart(2,'0')}-${date.day.toString().padStart(2,'0')}` // YYYY-MM-DD
|
let newValue = `${date.year}-${date.month.toString().padStart(2,'0')}-${date.day.toString().padStart(2,'0')}` // YYYY-MM-DD
|
||||||
|
|
||||||
if (existingRule) {
|
if (existingRule) {
|
||||||
existingRule.value = newValue
|
existingRule.value = newValue
|
||||||
} else {
|
} else {
|
||||||
filterRules.push({type: FILTER_RULE_TYPES.find(t => t.id == dateRuleTypeID), value: newValue})
|
filterRules.push({rule_type: dateRuleTypeID, value: newValue})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.filterRules = filterRules
|
this.filterRules = filterRules
|
||||||
@ -238,7 +238,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
clearDateFilter(dateRuleTypeID: number) {
|
clearDateFilter(dateRuleTypeID: number) {
|
||||||
let filterRules = this.filterRules
|
let filterRules = this.filterRules
|
||||||
let existingRule = filterRules.find(rule => rule.type.id == dateRuleTypeID)
|
let existingRule = filterRules.find(rule => rule.rule_type == dateRuleTypeID)
|
||||||
filterRules.splice(filterRules.indexOf(existingRule), 1)
|
filterRules.splice(filterRules.indexOf(existingRule), 1)
|
||||||
this.filterRules = filterRules
|
this.filterRules = filterRules
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,8 @@ export abstract class GenericListComponent<T extends ObjectWithId> implements On
|
|||||||
}
|
}
|
||||||
|
|
||||||
reloadData() {
|
reloadData() {
|
||||||
this.service.list(this.page, null, this.sortField, this.sortDirection).subscribe(c => {
|
// TODO: this is a hack
|
||||||
|
this.service.list(this.page, null, this.sortField, this.sortDirection == 'des').subscribe(c => {
|
||||||
this.data = c.results
|
this.data = c.results
|
||||||
this.collectionSize = c.count
|
this.collectionSize = c.count
|
||||||
});
|
});
|
||||||
|
@ -22,7 +22,7 @@ export class LogsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload() {
|
||||||
this.logService.list(1, 50, 'created', 'des', {'level__gte': this.level}).subscribe(result => this.logs = result.results)
|
this.logService.list(1, 50, 'created', true, {'level__gte': this.level}).subscribe(result => this.logs = result.results)
|
||||||
}
|
}
|
||||||
|
|
||||||
getLevelText(level: number) {
|
getLevelText(level: number) {
|
||||||
@ -34,7 +34,7 @@ export class LogsComponent implements OnInit {
|
|||||||
if (this.logs.length > 0) {
|
if (this.logs.length > 0) {
|
||||||
lastCreated = new Date(this.logs[this.logs.length-1].created).toISOString()
|
lastCreated = new Date(this.logs[this.logs.length-1].created).toISOString()
|
||||||
}
|
}
|
||||||
this.logService.list(1, 25, 'created', 'des', {'created__lt': lastCreated, 'level__gte': this.level}).subscribe(result => {
|
this.logService.list(1, 25, 'created', true, {'created__lt': lastCreated, 'level__gte': this.level}).subscribe(result => {
|
||||||
this.logs.push(...result.results)
|
this.logs.push(...result.results)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let config of savedViewConfigService.getConfigs()">
|
<tr *ngFor="let view of savedViewService.allViews">
|
||||||
<td>{{ config.title }}</td>
|
<td>{{ view.name }}</td>
|
||||||
<td>{{ config.showInDashboard | yesno }}</td>
|
<td>{{ view.show_on_dashboard | yesno }}</td>
|
||||||
<td>{{ config.showInSideBar | yesno }}</td>
|
<td>{{ view.show_in_sidebar | yesno }}</td>
|
||||||
<td><button type="button" class="btn btn-sm btn-outline-danger" (click)="deleteViewConfig(config)">Delete</button></td>
|
<td><button type="button" class="btn btn-sm btn-outline-danger" (click)="deleteSavedView(view)">Delete</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
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 { Title } from '@angular/platform-browser';
|
import { Title } from '@angular/platform-browser';
|
||||||
import { SavedViewConfig } from 'src/app/data/saved-view-config';
|
import { map, tap } from 'rxjs/operators';
|
||||||
|
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
|
||||||
import { GENERAL_SETTINGS } from 'src/app/data/storage-keys';
|
import { GENERAL_SETTINGS } from 'src/app/data/storage-keys';
|
||||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||||
import { SavedViewConfigService } from 'src/app/services/saved-view-config.service';
|
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -19,7 +20,7 @@ export class SettingsComponent implements OnInit {
|
|||||||
})
|
})
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private savedViewConfigService: SavedViewConfigService,
|
public savedViewService: SavedViewService,
|
||||||
private documentListViewService: DocumentListViewService,
|
private documentListViewService: DocumentListViewService,
|
||||||
private titleService: Title
|
private titleService: Title
|
||||||
) { }
|
) { }
|
||||||
@ -28,8 +29,8 @@ export class SettingsComponent implements OnInit {
|
|||||||
this.titleService.setTitle(`Settings - ${environment.appTitle}`)
|
this.titleService.setTitle(`Settings - ${environment.appTitle}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteViewConfig(config: SavedViewConfig) {
|
deleteSavedView(savedView: PaperlessSavedView) {
|
||||||
this.savedViewConfigService.deleteConfig(config)
|
this.savedViewService.delete(savedView).subscribe(() => {})
|
||||||
}
|
}
|
||||||
|
|
||||||
saveSettings() {
|
saveSettings() {
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { cloneFilterRules, FilterRule } from '../data/filter-rule';
|
import { cloneFilterRules, FilterRule } from '../data/filter-rule';
|
||||||
import { PaperlessDocument } from '../data/paperless-document';
|
import { PaperlessDocument } from '../data/paperless-document';
|
||||||
import { SavedViewConfig } from '../data/saved-view-config';
|
import { PaperlessSavedView } from '../data/paperless-saved-view';
|
||||||
import { DOCUMENT_LIST_SERVICE, GENERAL_SETTINGS } from '../data/storage-keys';
|
import { DOCUMENT_LIST_SERVICE, GENERAL_SETTINGS } from '../data/storage-keys';
|
||||||
import { DocumentService } from './rest/document.service';
|
import { DocumentService } from './rest/document.service';
|
||||||
|
|
||||||
@ -29,17 +29,17 @@ export class DocumentListViewService {
|
|||||||
/**
|
/**
|
||||||
* This is the current config for the document list. The service will always remember the last settings used for the document list.
|
* This is the current config for the document list. The service will always remember the last settings used for the document list.
|
||||||
*/
|
*/
|
||||||
private _documentListViewConfig: SavedViewConfig
|
private _documentListViewConfig: PaperlessSavedView
|
||||||
/**
|
/**
|
||||||
* Optionally, this is the currently selected saved view, which might be null.
|
* Optionally, this is the currently selected saved view, which might be null.
|
||||||
*/
|
*/
|
||||||
private _savedViewConfig: SavedViewConfig
|
private _savedViewConfig: PaperlessSavedView
|
||||||
|
|
||||||
get savedView() {
|
get savedView(): PaperlessSavedView {
|
||||||
return this._savedViewConfig
|
return this._savedViewConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
set savedView(value) {
|
set savedView(value: PaperlessSavedView) {
|
||||||
if (value) {
|
if (value) {
|
||||||
//this is here so that we don't modify value, which might be the actual instance of the saved view.
|
//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)
|
this._savedViewConfig = Object.assign({}, value)
|
||||||
@ -53,7 +53,7 @@ export class DocumentListViewService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get savedViewTitle() {
|
get savedViewTitle() {
|
||||||
return this.savedView?.title
|
return this.savedView?.name
|
||||||
}
|
}
|
||||||
|
|
||||||
get documentListView() {
|
get documentListView() {
|
||||||
@ -75,10 +75,11 @@ export class DocumentListViewService {
|
|||||||
return this.savedView || this.documentListView
|
return this.savedView || this.documentListView
|
||||||
}
|
}
|
||||||
|
|
||||||
load(config: SavedViewConfig) {
|
load(view: PaperlessSavedView) {
|
||||||
this.view.filterRules = cloneFilterRules(config.filterRules)
|
this.view.filter_rules = cloneFilterRules(view.filter_rules)
|
||||||
this.view.sortDirection = config.sortDirection
|
this.view.sort_reverse = view.sort_reverse
|
||||||
this.view.sortField = config.sortField
|
this.view.sort_field = view.sort_field
|
||||||
|
this.saveDocumentListView()
|
||||||
this.reload()
|
this.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,9 +94,9 @@ export class DocumentListViewService {
|
|||||||
this.documentService.list(
|
this.documentService.list(
|
||||||
this.currentPage,
|
this.currentPage,
|
||||||
this.currentPageSize,
|
this.currentPageSize,
|
||||||
this.view.sortField,
|
this.view.sort_field,
|
||||||
this.view.sortDirection,
|
this.view.sort_reverse,
|
||||||
this.view.filterRules).subscribe(
|
this.view.filter_rules).subscribe(
|
||||||
result => {
|
result => {
|
||||||
this.collectionSize = result.count
|
this.collectionSize = result.count
|
||||||
this.documents = result.results
|
this.documents = result.results
|
||||||
@ -116,33 +117,33 @@ export class DocumentListViewService {
|
|||||||
set filterRules(filterRules: FilterRule[]) {
|
set filterRules(filterRules: FilterRule[]) {
|
||||||
//we're going to clone the filterRules object, since we don't
|
//we're going to clone the filterRules object, since we don't
|
||||||
//want changes in the filter editor to propagate into here right away.
|
//want changes in the filter editor to propagate into here right away.
|
||||||
this.view.filterRules = cloneFilterRules(filterRules)
|
this.view.filter_rules = cloneFilterRules(filterRules)
|
||||||
this.reload()
|
this.reload()
|
||||||
this.saveDocumentListView()
|
this.saveDocumentListView()
|
||||||
}
|
}
|
||||||
|
|
||||||
get filterRules(): FilterRule[] {
|
get filterRules(): FilterRule[] {
|
||||||
return cloneFilterRules(this.view.filterRules)
|
return cloneFilterRules(this.view.filter_rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
set sortField(field: string) {
|
set sortField(field: string) {
|
||||||
this.view.sortField = field
|
this.view.sort_field = field
|
||||||
this.saveDocumentListView()
|
this.saveDocumentListView()
|
||||||
this.reload()
|
this.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
get sortField(): string {
|
get sortField(): string {
|
||||||
return this.view.sortField
|
return this.view.sort_field
|
||||||
}
|
}
|
||||||
|
|
||||||
set sortDirection(direction: string) {
|
set sortReverse(reverse: boolean) {
|
||||||
this.view.sortDirection = direction
|
this.view.sort_reverse = reverse
|
||||||
this.saveDocumentListView()
|
this.saveDocumentListView()
|
||||||
this.reload()
|
this.reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
get sortDirection(): string {
|
get sortReverse(): boolean {
|
||||||
return this.view.sortDirection
|
return this.view.sort_reverse
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveDocumentListView() {
|
private saveDocumentListView() {
|
||||||
@ -204,9 +205,9 @@ export class DocumentListViewService {
|
|||||||
}
|
}
|
||||||
if (!this.documentListView) {
|
if (!this.documentListView) {
|
||||||
this.documentListView = {
|
this.documentListView = {
|
||||||
filterRules: [],
|
filter_rules: [],
|
||||||
sortDirection: 'des',
|
sort_reverse: true,
|
||||||
sortField: 'created'
|
sort_field: 'created'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,17 +22,15 @@ export abstract class AbstractPaperlessService<T extends ObjectWithId> {
|
|||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
private getOrderingQueryParam(sortField: string, sortDirection: string) {
|
private getOrderingQueryParam(sortField: string, sortReverse: boolean) {
|
||||||
if (sortField && sortDirection) {
|
if (sortField) {
|
||||||
return (sortDirection == 'des' ? '-' : '') + sortField
|
return (sortReverse ? '-' : '') + sortField
|
||||||
} else if (sortField) {
|
|
||||||
return sortField
|
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
list(page?: number, pageSize?: number, sortField?: string, sortDirection?: string, extraParams?): Observable<Results<T>> {
|
list(page?: number, pageSize?: number, sortField?: string, sortReverse?: boolean, extraParams?): Observable<Results<T>> {
|
||||||
let httpParams = new HttpParams()
|
let httpParams = new HttpParams()
|
||||||
if (page) {
|
if (page) {
|
||||||
httpParams = httpParams.set('page', page.toString())
|
httpParams = httpParams.set('page', page.toString())
|
||||||
@ -40,7 +38,7 @@ export abstract class AbstractPaperlessService<T extends ObjectWithId> {
|
|||||||
if (pageSize) {
|
if (pageSize) {
|
||||||
httpParams = httpParams.set('page_size', pageSize.toString())
|
httpParams = httpParams.set('page_size', pageSize.toString())
|
||||||
}
|
}
|
||||||
let ordering = this.getOrderingQueryParam(sortField, sortDirection)
|
let ordering = this.getOrderingQueryParam(sortField, sortReverse)
|
||||||
if (ordering) {
|
if (ordering) {
|
||||||
httpParams = httpParams.set('ordering', ordering)
|
httpParams = httpParams.set('ordering', ordering)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { map } from 'rxjs/operators';
|
|||||||
import { CorrespondentService } from './correspondent.service';
|
import { CorrespondentService } from './correspondent.service';
|
||||||
import { DocumentTypeService } from './document-type.service';
|
import { DocumentTypeService } from './document-type.service';
|
||||||
import { TagService } from './tag.service';
|
import { TagService } from './tag.service';
|
||||||
|
import { FILTER_RULE_TYPES } from 'src/app/data/filter-rule-type';
|
||||||
|
|
||||||
export const DOCUMENT_SORT_FIELDS = [
|
export const DOCUMENT_SORT_FIELDS = [
|
||||||
{ field: "correspondent__name", name: "Correspondent" },
|
{ field: "correspondent__name", name: "Correspondent" },
|
||||||
@ -22,10 +22,6 @@ export const DOCUMENT_SORT_FIELDS = [
|
|||||||
{ field: 'modified', name: 'Modified' }
|
{ field: 'modified', name: 'Modified' }
|
||||||
]
|
]
|
||||||
|
|
||||||
export const SORT_DIRECTION_ASCENDING = "asc"
|
|
||||||
export const SORT_DIRECTION_DESCENDING = "des"
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
@ -39,10 +35,11 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
|
|||||||
if (filterRules) {
|
if (filterRules) {
|
||||||
let params = {}
|
let params = {}
|
||||||
for (let rule of filterRules) {
|
for (let rule of filterRules) {
|
||||||
if (rule.type.multi) {
|
let ruleType = FILTER_RULE_TYPES.find(t => t.id == rule.rule_type)
|
||||||
params[rule.type.filtervar] = params[rule.type.filtervar] ? params[rule.type.filtervar] + "," + rule.value : rule.value
|
if (ruleType.multi) {
|
||||||
|
params[ruleType.filtervar] = params[ruleType.filtervar] ? params[ruleType.filtervar] + "," + rule.value : rule.value
|
||||||
} else {
|
} else {
|
||||||
params[rule.type.filtervar] = rule.value
|
params[ruleType.filtervar] = rule.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
@ -64,8 +61,8 @@ export class DocumentService extends AbstractPaperlessService<PaperlessDocument>
|
|||||||
return doc
|
return doc
|
||||||
}
|
}
|
||||||
|
|
||||||
list(page?: number, pageSize?: number, sortField?: string, sortDirection?: string, filterRules?: FilterRule[]): Observable<Results<PaperlessDocument>> {
|
list(page?: number, pageSize?: number, sortField?: string, sortReverse?: boolean, filterRules?: FilterRule[]): Observable<Results<PaperlessDocument>> {
|
||||||
return super.list(page, pageSize, sortField, sortDirection, this.filterRulesToQueryParams(filterRules)).pipe(
|
return super.list(page, pageSize, sortField, sortReverse, this.filterRulesToQueryParams(filterRules)).pipe(
|
||||||
map(results => {
|
map(results => {
|
||||||
results.results.forEach(doc => this.addObservablesToDocument(doc))
|
results.results.forEach(doc => this.addObservablesToDocument(doc))
|
||||||
return results
|
return results
|
||||||
|
Loading…
x
Reference in New Issue
Block a user