mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { BulkEditorComponent } from './bulk-editor.component';
|
||||
import { BulkEditorComponent } from './bulk-editor.component'
|
||||
|
||||
describe('BulkEditorComponent', () => {
|
||||
let component: BulkEditorComponent;
|
||||
let fixture: ComponentFixture<BulkEditorComponent>;
|
||||
let component: BulkEditorComponent
|
||||
let fixture: ComponentFixture<BulkEditorComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ BulkEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [BulkEditorComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(BulkEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(BulkEditorComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,29 +1,37 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag';
|
||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent';
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { DocumentService, SelectionDataItem } from 'src/app/services/rest/document.service';
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
|
||||
import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component';
|
||||
import { ChangedItems, FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||
import { MatchingModel } from 'src/app/data/matching-model';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { Component } from '@angular/core'
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag'
|
||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'
|
||||
import { TagService } from 'src/app/services/rest/tag.service'
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import {
|
||||
DocumentService,
|
||||
SelectionDataItem,
|
||||
} from 'src/app/services/rest/document.service'
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||
import { ConfirmDialogComponent } from 'src/app/components/common/confirm-dialog/confirm-dialog.component'
|
||||
import {
|
||||
ChangedItems,
|
||||
FilterableDropdownSelectionModel,
|
||||
} from '../../common/filterable-dropdown/filterable-dropdown.component'
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
|
||||
import { MatchingModel } from 'src/app/data/matching-model'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
@Component({
|
||||
selector: 'app-bulk-editor',
|
||||
templateUrl: './bulk-editor.component.html',
|
||||
styleUrls: ['./bulk-editor.component.scss']
|
||||
styleUrls: ['./bulk-editor.component.scss'],
|
||||
})
|
||||
export class BulkEditorComponent {
|
||||
|
||||
tags: PaperlessTag[]
|
||||
correspondents: PaperlessCorrespondent[]
|
||||
documentTypes: PaperlessDocumentType[]
|
||||
@@ -42,43 +50,63 @@ export class BulkEditorComponent {
|
||||
private openDocumentService: OpenDocumentsService,
|
||||
private settings: SettingsService,
|
||||
private toastService: ToastService
|
||||
) { }
|
||||
) {}
|
||||
|
||||
applyOnClose: boolean = this.settings.get(SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE)
|
||||
showConfirmationDialogs: boolean = this.settings.get(SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS)
|
||||
applyOnClose: boolean = this.settings.get(
|
||||
SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
|
||||
)
|
||||
showConfirmationDialogs: boolean = this.settings.get(
|
||||
SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS
|
||||
)
|
||||
|
||||
ngOnInit() {
|
||||
this.tagService.listAll().subscribe(result => this.tags = result.results)
|
||||
this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
|
||||
this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
|
||||
this.tagService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.tags = result.results))
|
||||
this.correspondentService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.correspondents = result.results))
|
||||
this.documentTypeService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.documentTypes = result.results))
|
||||
}
|
||||
|
||||
private executeBulkOperation(modal, method: string, args) {
|
||||
if (modal) {
|
||||
modal.componentInstance.buttonsEnabled = false
|
||||
}
|
||||
this.documentService.bulkEdit(Array.from(this.list.selected), method, args).subscribe(
|
||||
response => {
|
||||
this.list.reload()
|
||||
this.list.reduceSelectionToFilter()
|
||||
this.list.selected.forEach(id => {
|
||||
this.openDocumentService.refreshDocument(id)
|
||||
})
|
||||
if (modal) {
|
||||
modal.close()
|
||||
this.documentService
|
||||
.bulkEdit(Array.from(this.list.selected), method, args)
|
||||
.subscribe(
|
||||
(response) => {
|
||||
this.list.reload()
|
||||
this.list.reduceSelectionToFilter()
|
||||
this.list.selected.forEach((id) => {
|
||||
this.openDocumentService.refreshDocument(id)
|
||||
})
|
||||
if (modal) {
|
||||
modal.close()
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
if (modal) {
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
}
|
||||
this.toastService.showError(
|
||||
$localize`Error executing bulk operation: ${JSON.stringify(
|
||||
error.error
|
||||
)}`
|
||||
)
|
||||
}
|
||||
}, error => {
|
||||
if (modal) {
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
}
|
||||
this.toastService.showError($localize`Error executing bulk operation: ${JSON.stringify(error.error)}`)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private applySelectionData(items: SelectionDataItem[], selectionModel: FilterableDropdownSelectionModel) {
|
||||
private applySelectionData(
|
||||
items: SelectionDataItem[],
|
||||
selectionModel: FilterableDropdownSelectionModel
|
||||
) {
|
||||
let selectionData = new Map<number, ToggleableItemState>()
|
||||
items.forEach(i => {
|
||||
items.forEach((i) => {
|
||||
if (i.document_count == this.list.selected.size) {
|
||||
selectionData.set(i.id, ToggleableItemState.Selected)
|
||||
} else if (i.document_count > 0) {
|
||||
@@ -89,129 +117,210 @@ export class BulkEditorComponent {
|
||||
}
|
||||
|
||||
openTagsDropdown() {
|
||||
this.documentService.getSelectionData(Array.from(this.list.selected)).subscribe(s => {
|
||||
this.applySelectionData(s.selected_tags, this.tagSelectionModel)
|
||||
})
|
||||
this.documentService
|
||||
.getSelectionData(Array.from(this.list.selected))
|
||||
.subscribe((s) => {
|
||||
this.applySelectionData(s.selected_tags, this.tagSelectionModel)
|
||||
})
|
||||
}
|
||||
|
||||
openDocumentTypeDropdown() {
|
||||
this.documentService.getSelectionData(Array.from(this.list.selected)).subscribe(s => {
|
||||
this.applySelectionData(s.selected_document_types, this.documentTypeSelectionModel)
|
||||
})
|
||||
this.documentService
|
||||
.getSelectionData(Array.from(this.list.selected))
|
||||
.subscribe((s) => {
|
||||
this.applySelectionData(
|
||||
s.selected_document_types,
|
||||
this.documentTypeSelectionModel
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
openCorrespondentDropdown() {
|
||||
this.documentService.getSelectionData(Array.from(this.list.selected)).subscribe(s => {
|
||||
this.applySelectionData(s.selected_correspondents, this.correspondentSelectionModel)
|
||||
})
|
||||
this.documentService
|
||||
.getSelectionData(Array.from(this.list.selected))
|
||||
.subscribe((s) => {
|
||||
this.applySelectionData(
|
||||
s.selected_correspondents,
|
||||
this.correspondentSelectionModel
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
private _localizeList(items: MatchingModel[]) {
|
||||
if (items.length == 0) {
|
||||
return ""
|
||||
return ''
|
||||
} else if (items.length == 1) {
|
||||
return $localize`"${items[0].name}"`
|
||||
} else if (items.length == 2) {
|
||||
return $localize`:This is for messages like 'modify "tag1" and "tag2"':"${items[0].name}" and "${items[1].name}"`
|
||||
} else {
|
||||
let list = items.slice(0, items.length - 1).map(i => $localize`"${i.name}"`).join($localize`:this is used to separate enumerations and should probably be a comma and a whitespace in most languages:, `)
|
||||
return $localize`:this is for messages like 'modify "tag1", "tag2" and "tag3"':${list} and "${items[items.length - 1].name}"`
|
||||
let list = items
|
||||
.slice(0, items.length - 1)
|
||||
.map((i) => $localize`"${i.name}"`)
|
||||
.join(
|
||||
$localize`:this is used to separate enumerations and should probably be a comma and a whitespace in most languages:, `
|
||||
)
|
||||
return $localize`:this is for messages like 'modify "tag1", "tag2" and "tag3"':${list} and "${
|
||||
items[items.length - 1].name
|
||||
}"`
|
||||
}
|
||||
}
|
||||
|
||||
setTags(changedTags: ChangedItems) {
|
||||
if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 0) return
|
||||
if (
|
||||
changedTags.itemsToAdd.length == 0 &&
|
||||
changedTags.itemsToRemove.length == 0
|
||||
)
|
||||
return
|
||||
|
||||
if (this.showConfirmationDialogs) {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Confirm tags assignment`
|
||||
if (changedTags.itemsToAdd.length == 1 && changedTags.itemsToRemove.length == 0) {
|
||||
if (
|
||||
changedTags.itemsToAdd.length == 1 &&
|
||||
changedTags.itemsToRemove.length == 0
|
||||
) {
|
||||
let tag = changedTags.itemsToAdd[0]
|
||||
modal.componentInstance.message = $localize`This operation will add the tag "${tag.name}" to ${this.list.selected.size} selected document(s).`
|
||||
} else if (changedTags.itemsToAdd.length > 1 && changedTags.itemsToRemove.length == 0) {
|
||||
modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} to ${this.list.selected.size} selected document(s).`
|
||||
} else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length == 1) {
|
||||
} else if (
|
||||
changedTags.itemsToAdd.length > 1 &&
|
||||
changedTags.itemsToRemove.length == 0
|
||||
) {
|
||||
modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(
|
||||
changedTags.itemsToAdd
|
||||
)} to ${this.list.selected.size} selected document(s).`
|
||||
} else if (
|
||||
changedTags.itemsToAdd.length == 0 &&
|
||||
changedTags.itemsToRemove.length == 1
|
||||
) {
|
||||
let tag = changedTags.itemsToRemove[0]
|
||||
modal.componentInstance.message = $localize`This operation will remove the tag "${tag.name}" from ${this.list.selected.size} selected document(s).`
|
||||
} else if (changedTags.itemsToAdd.length == 0 && changedTags.itemsToRemove.length > 1) {
|
||||
modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(changedTags.itemsToRemove)} from ${this.list.selected.size} selected document(s).`
|
||||
} else if (
|
||||
changedTags.itemsToAdd.length == 0 &&
|
||||
changedTags.itemsToRemove.length > 1
|
||||
) {
|
||||
modal.componentInstance.message = $localize`This operation will remove the tags ${this._localizeList(
|
||||
changedTags.itemsToRemove
|
||||
)} from ${this.list.selected.size} selected document(s).`
|
||||
} else {
|
||||
modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(changedTags.itemsToAdd)} and remove the tags ${this._localizeList(changedTags.itemsToRemove)} on ${this.list.selected.size} selected document(s).`
|
||||
modal.componentInstance.message = $localize`This operation will add the tags ${this._localizeList(
|
||||
changedTags.itemsToAdd
|
||||
)} and remove the tags ${this._localizeList(
|
||||
changedTags.itemsToRemove
|
||||
)} on ${this.list.selected.size} selected document(s).`
|
||||
}
|
||||
|
||||
modal.componentInstance.btnClass = "btn-warning"
|
||||
modal.componentInstance.btnClass = 'btn-warning'
|
||||
modal.componentInstance.btnCaption = $localize`Confirm`
|
||||
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||
this.executeBulkOperation(modal, 'modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)})
|
||||
this.executeBulkOperation(modal, 'modify_tags', {
|
||||
add_tags: changedTags.itemsToAdd.map((t) => t.id),
|
||||
remove_tags: changedTags.itemsToRemove.map((t) => t.id),
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.executeBulkOperation(null, 'modify_tags', {"add_tags": changedTags.itemsToAdd.map(t => t.id), "remove_tags": changedTags.itemsToRemove.map(t => t.id)})
|
||||
this.executeBulkOperation(null, 'modify_tags', {
|
||||
add_tags: changedTags.itemsToAdd.map((t) => t.id),
|
||||
remove_tags: changedTags.itemsToRemove.map((t) => t.id),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setCorrespondents(changedCorrespondents: ChangedItems) {
|
||||
if (changedCorrespondents.itemsToAdd.length == 0 && changedCorrespondents.itemsToRemove.length == 0) return
|
||||
if (
|
||||
changedCorrespondents.itemsToAdd.length == 0 &&
|
||||
changedCorrespondents.itemsToRemove.length == 0
|
||||
)
|
||||
return
|
||||
|
||||
let correspondent = changedCorrespondents.itemsToAdd.length > 0 ? changedCorrespondents.itemsToAdd[0] : null
|
||||
let correspondent =
|
||||
changedCorrespondents.itemsToAdd.length > 0
|
||||
? changedCorrespondents.itemsToAdd[0]
|
||||
: null
|
||||
|
||||
if (this.showConfirmationDialogs) {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Confirm correspondent assignment`
|
||||
if (correspondent) {
|
||||
modal.componentInstance.message = $localize`This operation will assign the correspondent "${correspondent.name}" to ${this.list.selected.size} selected document(s).`
|
||||
} else {
|
||||
modal.componentInstance.message = $localize`This operation will remove the correspondent from ${this.list.selected.size} selected document(s).`
|
||||
}
|
||||
modal.componentInstance.btnClass = "btn-warning"
|
||||
modal.componentInstance.btnClass = 'btn-warning'
|
||||
modal.componentInstance.btnCaption = $localize`Confirm`
|
||||
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||
this.executeBulkOperation(modal, 'set_correspondent', {"correspondent": correspondent ? correspondent.id : null})
|
||||
this.executeBulkOperation(modal, 'set_correspondent', {
|
||||
correspondent: correspondent ? correspondent.id : null,
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.executeBulkOperation(null, 'set_correspondent', {"correspondent": correspondent ? correspondent.id : null})
|
||||
this.executeBulkOperation(null, 'set_correspondent', {
|
||||
correspondent: correspondent ? correspondent.id : null,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setDocumentTypes(changedDocumentTypes: ChangedItems) {
|
||||
if (changedDocumentTypes.itemsToAdd.length == 0 && changedDocumentTypes.itemsToRemove.length == 0) return
|
||||
if (
|
||||
changedDocumentTypes.itemsToAdd.length == 0 &&
|
||||
changedDocumentTypes.itemsToRemove.length == 0
|
||||
)
|
||||
return
|
||||
|
||||
let documentType = changedDocumentTypes.itemsToAdd.length > 0 ? changedDocumentTypes.itemsToAdd[0] : null
|
||||
let documentType =
|
||||
changedDocumentTypes.itemsToAdd.length > 0
|
||||
? changedDocumentTypes.itemsToAdd[0]
|
||||
: null
|
||||
|
||||
if (this.showConfirmationDialogs) {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Confirm document type assignment`
|
||||
if (documentType) {
|
||||
modal.componentInstance.message = $localize`This operation will assign the document type "${documentType.name}" to ${this.list.selected.size} selected document(s).`
|
||||
} else {
|
||||
modal.componentInstance.message = $localize`This operation will remove the document type from ${this.list.selected.size} selected document(s).`
|
||||
}
|
||||
modal.componentInstance.btnClass = "btn-warning"
|
||||
modal.componentInstance.btnClass = 'btn-warning'
|
||||
modal.componentInstance.btnCaption = $localize`Confirm`
|
||||
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||
this.executeBulkOperation(modal, 'set_document_type', {"document_type": documentType ? documentType.id : null})
|
||||
this.executeBulkOperation(modal, 'set_document_type', {
|
||||
document_type: documentType ? documentType.id : null,
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.executeBulkOperation(null, 'set_document_type', {"document_type": documentType ? documentType.id : null})
|
||||
this.executeBulkOperation(null, 'set_document_type', {
|
||||
document_type: documentType ? documentType.id : null,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
applyDelete() {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {backdrop: 'static'})
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.delayConfirm(5)
|
||||
modal.componentInstance.title = $localize`Delete confirm`
|
||||
modal.componentInstance.messageBold = $localize`This operation will permanently delete ${this.list.selected.size} selected document(s).`
|
||||
modal.componentInstance.message = $localize`This operation cannot be undone.`
|
||||
modal.componentInstance.btnClass = "btn-danger"
|
||||
modal.componentInstance.btnClass = 'btn-danger'
|
||||
modal.componentInstance.btnCaption = $localize`Delete document(s)`
|
||||
modal.componentInstance.confirmClicked.subscribe(() => {
|
||||
modal.componentInstance.buttonsEnabled = false
|
||||
this.executeBulkOperation(modal, "delete", {})
|
||||
this.executeBulkOperation(modal, 'delete', {})
|
||||
})
|
||||
}
|
||||
|
||||
downloadSelected(content = "archive") {
|
||||
this.documentService.bulkDownload(Array.from(this.list.selected), content).subscribe((result: any) => {
|
||||
saveAs(result, 'documents.zip');
|
||||
})
|
||||
downloadSelected(content = 'archive') {
|
||||
this.documentService
|
||||
.bulkDownload(Array.from(this.list.selected), content)
|
||||
.subscribe((result: any) => {
|
||||
saveAs(result, 'documents.zip')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { DocumentCardLargeComponent } from './document-card-large.component';
|
||||
import { DocumentCardLargeComponent } from './document-card-large.component'
|
||||
|
||||
describe('DocumentCardLargeComponent', () => {
|
||||
let component: DocumentCardLargeComponent;
|
||||
let fixture: ComponentFixture<DocumentCardLargeComponent>;
|
||||
let component: DocumentCardLargeComponent
|
||||
let fixture: ComponentFixture<DocumentCardLargeComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DocumentCardLargeComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [DocumentCardLargeComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocumentCardLargeComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(DocumentCardLargeComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,20 +1,36 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core'
|
||||
import { DomSanitizer } from '@angular/platform-browser'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-large',
|
||||
templateUrl: './document-card-large.component.html',
|
||||
styleUrls: ['./document-card-large.component.scss', '../popover-preview/popover-preview.scss']
|
||||
styleUrls: [
|
||||
'./document-card-large.component.scss',
|
||||
'../popover-preview/popover-preview.scss',
|
||||
],
|
||||
})
|
||||
export class DocumentCardLargeComponent implements OnInit {
|
||||
|
||||
constructor(private documentService: DocumentService, private sanitizer: DomSanitizer, private settingsService: SettingsService) { }
|
||||
constructor(
|
||||
private documentService: DocumentService,
|
||||
private sanitizer: DomSanitizer,
|
||||
private settingsService: SettingsService
|
||||
) {}
|
||||
|
||||
@Input()
|
||||
selected = false
|
||||
@@ -39,7 +55,7 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
clickDocumentType = new EventEmitter<number>()
|
||||
|
||||
@Output()
|
||||
clickMoreLike= new EventEmitter()
|
||||
clickMoreLike = new EventEmitter()
|
||||
|
||||
@ViewChild('popover') popover: NgbPopover
|
||||
|
||||
@@ -49,17 +65,16 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
get searchScoreClass() {
|
||||
if (this.document.__search_hit__) {
|
||||
if (this.document.__search_hit__.score > 0.7) {
|
||||
return "success"
|
||||
return 'success'
|
||||
} else if (this.document.__search_hit__.score > 0.3) {
|
||||
return "warning"
|
||||
return 'warning'
|
||||
} else {
|
||||
return "danger"
|
||||
return 'danger'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
ngOnInit(): void {}
|
||||
|
||||
getIsThumbInverted() {
|
||||
return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)
|
||||
@@ -90,7 +105,7 @@ export class DocumentCardLargeComponent implements OnInit {
|
||||
} else {
|
||||
this.popover.close()
|
||||
}
|
||||
}, 600);
|
||||
}, 600)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { DocumentCardSmallComponent } from './document-card-small.component';
|
||||
import { DocumentCardSmallComponent } from './document-card-small.component'
|
||||
|
||||
describe('DocumentCardSmallComponent', () => {
|
||||
let component: DocumentCardSmallComponent;
|
||||
let fixture: ComponentFixture<DocumentCardSmallComponent>;
|
||||
let component: DocumentCardSmallComponent
|
||||
let fixture: ComponentFixture<DocumentCardSmallComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DocumentCardSmallComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [DocumentCardSmallComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocumentCardSmallComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(DocumentCardSmallComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,18 +1,33 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { SettingsService, SETTINGS_KEYS } from 'src/app/services/settings.service';
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild,
|
||||
} from '@angular/core'
|
||||
import { map } from 'rxjs/operators'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-small',
|
||||
templateUrl: './document-card-small.component.html',
|
||||
styleUrls: ['./document-card-small.component.scss', '../popover-preview/popover-preview.scss']
|
||||
styleUrls: [
|
||||
'./document-card-small.component.scss',
|
||||
'../popover-preview/popover-preview.scss',
|
||||
],
|
||||
})
|
||||
export class DocumentCardSmallComponent implements OnInit {
|
||||
|
||||
constructor(private documentService: DocumentService, private settingsService: SettingsService) { }
|
||||
constructor(
|
||||
private documentService: DocumentService,
|
||||
private settingsService: SettingsService
|
||||
) {}
|
||||
|
||||
@Input()
|
||||
selected = false
|
||||
@@ -39,8 +54,7 @@ export class DocumentCardSmallComponent implements OnInit {
|
||||
mouseOnPreview = false
|
||||
popoverHidden = true
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
ngOnInit(): void {}
|
||||
|
||||
getIsThumbInverted() {
|
||||
return this.settingsService.get(SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED)
|
||||
@@ -60,7 +74,7 @@ export class DocumentCardSmallComponent implements OnInit {
|
||||
|
||||
getTagsLimited$() {
|
||||
return this.document.tags$.pipe(
|
||||
map(tags => {
|
||||
map((tags) => {
|
||||
if (tags.length > 7) {
|
||||
this.moreTags = tags.length - 6
|
||||
return tags.slice(0, 6)
|
||||
@@ -84,7 +98,7 @@ export class DocumentCardSmallComponent implements OnInit {
|
||||
} else {
|
||||
this.popover.close()
|
||||
}
|
||||
}, 600);
|
||||
}, 600)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { DocumentListComponent } from './document-list.component';
|
||||
import { DocumentListComponent } from './document-list.component'
|
||||
|
||||
describe('DocumentListComponent', () => {
|
||||
let component: DocumentListComponent;
|
||||
let fixture: ComponentFixture<DocumentListComponent>;
|
||||
let component: DocumentListComponent
|
||||
let fixture: ComponentFixture<DocumentListComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ DocumentListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [DocumentListComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(DocumentListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(DocumentListComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,27 +1,39 @@
|
||||
import { Component, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule';
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view';
|
||||
import { SortableDirective, SortEvent } from 'src/app/directives/sortable.directive';
|
||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service';
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
|
||||
import { DOCUMENT_SORT_FIELDS, DOCUMENT_SORT_FIELDS_FULLTEXT } from 'src/app/services/rest/document.service';
|
||||
import { SavedViewService } from 'src/app/services/rest/saved-view.service';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { FilterEditorComponent } from './filter-editor/filter-editor.component';
|
||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component';
|
||||
import {
|
||||
Component,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
QueryList,
|
||||
ViewChild,
|
||||
ViewChildren,
|
||||
} from '@angular/core'
|
||||
import { ActivatedRoute, Router } from '@angular/router'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { FilterRule, isFullTextFilterRule } from 'src/app/data/filter-rule'
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'
|
||||
import {
|
||||
SortableDirective,
|
||||
SortEvent,
|
||||
} from 'src/app/directives/sortable.directive'
|
||||
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import {
|
||||
DOCUMENT_SORT_FIELDS,
|
||||
DOCUMENT_SORT_FIELDS_FULLTEXT,
|
||||
} from 'src/app/services/rest/document.service'
|
||||
import { SavedViewService } from 'src/app/services/rest/saved-view.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { FilterEditorComponent } from './filter-editor/filter-editor.component'
|
||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog/save-view-config-dialog.component'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-list',
|
||||
templateUrl: './document-list.component.html',
|
||||
styleUrls: ['./document-list.component.scss']
|
||||
styleUrls: ['./document-list.component.scss'],
|
||||
})
|
||||
export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
public list: DocumentListViewService,
|
||||
public savedViewService: SavedViewService,
|
||||
@@ -30,12 +42,12 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
private toastService: ToastService,
|
||||
private modalService: NgbModal,
|
||||
private consumerStatusService: ConsumerStatusService
|
||||
) { }
|
||||
) {}
|
||||
|
||||
@ViewChild("filterEditor")
|
||||
@ViewChild('filterEditor')
|
||||
private filterEditor: FilterEditorComponent
|
||||
|
||||
@ViewChildren(SortableDirective) headers: QueryList<SortableDirective>;
|
||||
@ViewChildren(SortableDirective) headers: QueryList<SortableDirective>
|
||||
|
||||
displayMode = 'smallCards' // largeCards, smallCards, details
|
||||
|
||||
@@ -52,7 +64,9 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getSortFields() {
|
||||
return isFullTextFilterRule(this.list.filterRules) ? DOCUMENT_SORT_FIELDS_FULLTEXT : DOCUMENT_SORT_FIELDS
|
||||
return isFullTextFilterRule(this.list.filterRules)
|
||||
? DOCUMENT_SORT_FIELDS_FULLTEXT
|
||||
: DOCUMENT_SORT_FIELDS
|
||||
}
|
||||
|
||||
onSort(event: SortEvent) {
|
||||
@@ -71,14 +85,16 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
if (localStorage.getItem('document-list:displayMode') != null) {
|
||||
this.displayMode = localStorage.getItem('document-list:displayMode')
|
||||
}
|
||||
this.consumptionFinishedSubscription = this.consumerStatusService.onDocumentConsumptionFinished().subscribe(() => {
|
||||
this.list.reload()
|
||||
})
|
||||
this.route.paramMap.subscribe(params => {
|
||||
this.consumptionFinishedSubscription = this.consumerStatusService
|
||||
.onDocumentConsumptionFinished()
|
||||
.subscribe(() => {
|
||||
this.list.reload()
|
||||
})
|
||||
this.route.paramMap.subscribe((params) => {
|
||||
if (params.has('id')) {
|
||||
this.savedViewService.getCached(+params.get('id')).subscribe(view => {
|
||||
this.savedViewService.getCached(+params.get('id')).subscribe((view) => {
|
||||
if (!view) {
|
||||
this.router.navigate(["404"])
|
||||
this.router.navigate(['404'])
|
||||
return
|
||||
}
|
||||
this.list.activateSavedView(view)
|
||||
@@ -110,19 +126,23 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
id: this.list.activeSavedViewId,
|
||||
filter_rules: this.list.filterRules,
|
||||
sort_field: this.list.sortField,
|
||||
sort_reverse: this.list.sortReverse
|
||||
sort_reverse: this.list.sortReverse,
|
||||
}
|
||||
this.savedViewService.patch(savedView).subscribe(result => {
|
||||
this.toastService.showInfo($localize`View "${this.list.activeSavedViewTitle}" saved successfully.`)
|
||||
this.savedViewService.patch(savedView).subscribe((result) => {
|
||||
this.toastService.showInfo(
|
||||
$localize`View "${this.list.activeSavedViewTitle}" saved successfully.`
|
||||
)
|
||||
this.unmodifiedFilterRules = this.list.filterRules
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
saveViewConfigAs() {
|
||||
let modal = this.modalService.open(SaveViewConfigDialogComponent, {backdrop: 'static'})
|
||||
let modal = this.modalService.open(SaveViewConfigDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.defaultName = this.filterEditor.generateFilterName()
|
||||
modal.componentInstance.saveClicked.subscribe(formValue => {
|
||||
modal.componentInstance.saveClicked.subscribe((formValue) => {
|
||||
modal.componentInstance.buttonsEnabled = false
|
||||
let savedView: PaperlessSavedView = {
|
||||
name: formValue.name,
|
||||
@@ -130,16 +150,21 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
show_in_sidebar: formValue.showInSideBar,
|
||||
filter_rules: this.list.filterRules,
|
||||
sort_reverse: this.list.sortReverse,
|
||||
sort_field: this.list.sortField
|
||||
sort_field: this.list.sortField,
|
||||
}
|
||||
|
||||
this.savedViewService.create(savedView).subscribe(() => {
|
||||
modal.close()
|
||||
this.toastService.showInfo($localize`View "${savedView.name}" created successfully.`)
|
||||
}, error => {
|
||||
modal.componentInstance.error = error.error
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
})
|
||||
this.savedViewService.create(savedView).subscribe(
|
||||
() => {
|
||||
modal.close()
|
||||
this.toastService.showInfo(
|
||||
$localize`View "${savedView.name}" created successfully.`
|
||||
)
|
||||
},
|
||||
(error) => {
|
||||
modal.componentInstance.error = error.error
|
||||
modal.componentInstance.buttonsEnabled = true
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -170,7 +195,9 @@ export class DocumentListComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
clickMoreLike(documentID: number) {
|
||||
this.list.quickFilter([{rule_type: FILTER_FULLTEXT_MORELIKE, value: documentID.toString()}])
|
||||
this.list.quickFilter([
|
||||
{ rule_type: FILTER_FULLTEXT_MORELIKE, value: documentID.toString() },
|
||||
])
|
||||
}
|
||||
|
||||
trackByDocumentId(index, item: PaperlessDocument) {
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { FilterEditorComponent } from './filter-editor.component';
|
||||
import { FilterEditorComponent } from './filter-editor.component'
|
||||
|
||||
describe('FilterEditorComponent', () => {
|
||||
let component: FilterEditorComponent;
|
||||
let fixture: ComponentFixture<FilterEditorComponent>;
|
||||
let component: FilterEditorComponent
|
||||
let fixture: ComponentFixture<FilterEditorComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ FilterEditorComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [FilterEditorComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(FilterEditorComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(FilterEditorComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,56 +1,85 @@
|
||||
import { Component, EventEmitter, Input, Output, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag';
|
||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent';
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type';
|
||||
import { Subject, Subscription } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service';
|
||||
import { TagService } from 'src/app/services/rest/tag.service';
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service';
|
||||
import { FilterRule } from 'src/app/data/filter-rule';
|
||||
import { FILTER_ADDED_AFTER, FILTER_ADDED_BEFORE, FILTER_ASN, FILTER_CORRESPONDENT, FILTER_CREATED_AFTER, FILTER_CREATED_BEFORE, FILTER_DOCUMENT_TYPE, FILTER_FULLTEXT_MORELIKE, FILTER_FULLTEXT_QUERY, FILTER_HAS_ANY_TAG, FILTER_HAS_TAGS_ALL, FILTER_HAS_TAGS_ANY, FILTER_DOES_NOT_HAVE_TAG, FILTER_TITLE, FILTER_TITLE_CONTENT } from 'src/app/data/filter-rule-type';
|
||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component';
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component';
|
||||
import { DocumentService } from 'src/app/services/rest/document.service';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
Output,
|
||||
OnInit,
|
||||
OnDestroy,
|
||||
ViewChild,
|
||||
ElementRef,
|
||||
} from '@angular/core'
|
||||
import { PaperlessTag } from 'src/app/data/paperless-tag'
|
||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent'
|
||||
import { PaperlessDocumentType } from 'src/app/data/paperless-document-type'
|
||||
import { Subject, Subscription } from 'rxjs'
|
||||
import { debounceTime, distinctUntilChanged } from 'rxjs/operators'
|
||||
import { DocumentTypeService } from 'src/app/services/rest/document-type.service'
|
||||
import { TagService } from 'src/app/services/rest/tag.service'
|
||||
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
|
||||
import { FilterRule } from 'src/app/data/filter-rule'
|
||||
import {
|
||||
FILTER_ADDED_AFTER,
|
||||
FILTER_ADDED_BEFORE,
|
||||
FILTER_ASN,
|
||||
FILTER_CORRESPONDENT,
|
||||
FILTER_CREATED_AFTER,
|
||||
FILTER_CREATED_BEFORE,
|
||||
FILTER_DOCUMENT_TYPE,
|
||||
FILTER_FULLTEXT_MORELIKE,
|
||||
FILTER_FULLTEXT_QUERY,
|
||||
FILTER_HAS_ANY_TAG,
|
||||
FILTER_HAS_TAGS_ALL,
|
||||
FILTER_HAS_TAGS_ANY,
|
||||
FILTER_DOES_NOT_HAVE_TAG,
|
||||
FILTER_TITLE,
|
||||
FILTER_TITLE_CONTENT,
|
||||
} from 'src/app/data/filter-rule-type'
|
||||
import { FilterableDropdownSelectionModel } from '../../common/filterable-dropdown/filterable-dropdown.component'
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
|
||||
const TEXT_FILTER_TARGET_TITLE = "title"
|
||||
const TEXT_FILTER_TARGET_TITLE_CONTENT = "title-content"
|
||||
const TEXT_FILTER_TARGET_ASN = "asn"
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = "fulltext-query"
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = "fulltext-morelike"
|
||||
const TEXT_FILTER_TARGET_TITLE = 'title'
|
||||
const TEXT_FILTER_TARGET_TITLE_CONTENT = 'title-content'
|
||||
const TEXT_FILTER_TARGET_ASN = 'asn'
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_QUERY = 'fulltext-query'
|
||||
const TEXT_FILTER_TARGET_FULLTEXT_MORELIKE = 'fulltext-morelike'
|
||||
|
||||
@Component({
|
||||
selector: 'app-filter-editor',
|
||||
templateUrl: './filter-editor.component.html',
|
||||
styleUrls: ['./filter-editor.component.scss']
|
||||
styleUrls: ['./filter-editor.component.scss'],
|
||||
})
|
||||
export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
generateFilterName() {
|
||||
if (this.filterRules.length == 1) {
|
||||
let rule = this.filterRules[0]
|
||||
switch(this.filterRules[0].rule_type) {
|
||||
|
||||
switch (this.filterRules[0].rule_type) {
|
||||
case FILTER_CORRESPONDENT:
|
||||
if (rule.value) {
|
||||
return $localize`Correspondent: ${this.correspondents.find(c => c.id == +rule.value)?.name}`
|
||||
return $localize`Correspondent: ${
|
||||
this.correspondents.find((c) => c.id == +rule.value)?.name
|
||||
}`
|
||||
} else {
|
||||
return $localize`Without correspondent`
|
||||
}
|
||||
|
||||
case FILTER_DOCUMENT_TYPE:
|
||||
if (rule.value) {
|
||||
return $localize`Type: ${this.documentTypes.find(dt => dt.id == +rule.value)?.name}`
|
||||
return $localize`Type: ${
|
||||
this.documentTypes.find((dt) => dt.id == +rule.value)?.name
|
||||
}`
|
||||
} else {
|
||||
return $localize`Without document type`
|
||||
}
|
||||
|
||||
case FILTER_HAS_TAGS_ALL:
|
||||
return $localize`Tag: ${this.tags.find(t => t.id == +rule.value)?.name}`
|
||||
return $localize`Tag: ${
|
||||
this.tags.find((t) => t.id == +rule.value)?.name
|
||||
}`
|
||||
|
||||
case FILTER_HAS_ANY_TAG:
|
||||
if (rule.value == "false") {
|
||||
if (rule.value == 'false') {
|
||||
return $localize`Without any tag`
|
||||
}
|
||||
|
||||
@@ -62,7 +91,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
return ''
|
||||
}
|
||||
|
||||
constructor(
|
||||
@@ -70,28 +99,37 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
private tagService: TagService,
|
||||
private correspondentService: CorrespondentService,
|
||||
private documentService: DocumentService
|
||||
) { }
|
||||
) {}
|
||||
|
||||
@ViewChild("textFilterInput")
|
||||
@ViewChild('textFilterInput')
|
||||
textFilterInput: ElementRef
|
||||
|
||||
tags: PaperlessTag[] = []
|
||||
correspondents: PaperlessCorrespondent[] = []
|
||||
documentTypes: PaperlessDocumentType[] = []
|
||||
|
||||
_textFilter = ""
|
||||
_textFilter = ''
|
||||
_moreLikeId: number
|
||||
_moreLikeDoc: PaperlessDocument
|
||||
|
||||
get textFilterTargets() {
|
||||
let targets = [
|
||||
{id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title`},
|
||||
{id: TEXT_FILTER_TARGET_TITLE_CONTENT, name: $localize`Title & content`},
|
||||
{id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN`},
|
||||
{id: TEXT_FILTER_TARGET_FULLTEXT_QUERY, name: $localize`Advanced search`}
|
||||
{ id: TEXT_FILTER_TARGET_TITLE, name: $localize`Title` },
|
||||
{
|
||||
id: TEXT_FILTER_TARGET_TITLE_CONTENT,
|
||||
name: $localize`Title & content`,
|
||||
},
|
||||
{ id: TEXT_FILTER_TARGET_ASN, name: $localize`ASN` },
|
||||
{
|
||||
id: TEXT_FILTER_TARGET_FULLTEXT_QUERY,
|
||||
name: $localize`Advanced search`,
|
||||
},
|
||||
]
|
||||
if (this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
|
||||
targets.push({id: TEXT_FILTER_TARGET_FULLTEXT_MORELIKE, name: $localize`More like`})
|
||||
targets.push({
|
||||
id: TEXT_FILTER_TARGET_FULLTEXT_MORELIKE,
|
||||
name: $localize`More like`,
|
||||
})
|
||||
}
|
||||
return targets
|
||||
}
|
||||
@@ -99,10 +137,10 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||
|
||||
get textFilterTargetName() {
|
||||
return this.textFilterTargets.find(t => t.id == this.textFilterTarget)?.name
|
||||
return this.textFilterTargets.find((t) => t.id == this.textFilterTarget)
|
||||
?.name
|
||||
}
|
||||
|
||||
|
||||
tagSelectionModel = new FilterableDropdownSelectionModel()
|
||||
correspondentSelectionModel = new FilterableDropdownSelectionModel()
|
||||
documentTypeSelectionModel = new FilterableDropdownSelectionModel()
|
||||
@@ -126,7 +164,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
@Input()
|
||||
set filterRules (value: FilterRule[]) {
|
||||
set filterRules(value: FilterRule[]) {
|
||||
this._filterRules = value
|
||||
|
||||
this.documentTypeSelectionModel.clear(false)
|
||||
@@ -139,7 +177,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
this.dateCreatedBefore = null
|
||||
this.dateCreatedAfter = null
|
||||
|
||||
value.forEach(rule => {
|
||||
value.forEach((rule) => {
|
||||
switch (rule.rule_type) {
|
||||
case FILTER_TITLE:
|
||||
this._textFilter = rule.value
|
||||
@@ -160,7 +198,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
case FILTER_FULLTEXT_MORELIKE:
|
||||
this._moreLikeId = +rule.value
|
||||
this.textFilterTarget = TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
|
||||
this.documentService.get(this._moreLikeId).subscribe(result => {
|
||||
this.documentService.get(this._moreLikeId).subscribe((result) => {
|
||||
this._moreLikeDoc = result
|
||||
this._textFilter = result.title
|
||||
})
|
||||
@@ -178,23 +216,43 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
this.dateAddedBefore = rule.value
|
||||
break
|
||||
case FILTER_HAS_TAGS_ALL:
|
||||
this.tagSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
this.tagSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_HAS_TAGS_ANY:
|
||||
this.tagSelectionModel.logicalOperator = 'or'
|
||||
this.tagSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
this.tagSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_HAS_ANY_TAG:
|
||||
this.tagSelectionModel.set(null, ToggleableItemState.Selected, false)
|
||||
break
|
||||
case FILTER_DOES_NOT_HAVE_TAG:
|
||||
this.tagSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Excluded, false)
|
||||
this.tagSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Excluded,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_CORRESPONDENT:
|
||||
this.correspondentSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
this.correspondentSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
case FILTER_DOCUMENT_TYPE:
|
||||
this.documentTypeSelectionModel.set(rule.value ? +rule.value : null, ToggleableItemState.Selected, false)
|
||||
this.documentTypeSelectionModel.set(
|
||||
rule.value ? +rule.value : null,
|
||||
ToggleableItemState.Selected,
|
||||
false
|
||||
)
|
||||
break
|
||||
}
|
||||
})
|
||||
@@ -203,49 +261,104 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
|
||||
get filterRules(): FilterRule[] {
|
||||
let filterRules: FilterRule[] = []
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE_CONTENT) {
|
||||
filterRules.push({rule_type: FILTER_TITLE_CONTENT, value: this._textFilter})
|
||||
if (
|
||||
this._textFilter &&
|
||||
this.textFilterTarget == TEXT_FILTER_TARGET_TITLE_CONTENT
|
||||
) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_TITLE_CONTENT,
|
||||
value: this._textFilter,
|
||||
})
|
||||
}
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_TITLE) {
|
||||
filterRules.push({rule_type: FILTER_TITLE, value: this._textFilter})
|
||||
filterRules.push({ rule_type: FILTER_TITLE, value: this._textFilter })
|
||||
}
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_ASN) {
|
||||
filterRules.push({rule_type: FILTER_ASN, value: this._textFilter})
|
||||
filterRules.push({ rule_type: FILTER_ASN, value: this._textFilter })
|
||||
}
|
||||
if (this._textFilter && this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY) {
|
||||
filterRules.push({rule_type: FILTER_FULLTEXT_QUERY, value: this._textFilter})
|
||||
if (
|
||||
this._textFilter &&
|
||||
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_QUERY
|
||||
) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_FULLTEXT_QUERY,
|
||||
value: this._textFilter,
|
||||
})
|
||||
}
|
||||
if (this._moreLikeId && this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
|
||||
filterRules.push({rule_type: FILTER_FULLTEXT_MORELIKE, value: this._moreLikeId?.toString()})
|
||||
if (
|
||||
this._moreLikeId &&
|
||||
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
|
||||
) {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_FULLTEXT_MORELIKE,
|
||||
value: this._moreLikeId?.toString(),
|
||||
})
|
||||
}
|
||||
if (this.tagSelectionModel.isNoneSelected()) {
|
||||
filterRules.push({rule_type: FILTER_HAS_ANY_TAG, value: "false"})
|
||||
filterRules.push({ rule_type: FILTER_HAS_ANY_TAG, value: 'false' })
|
||||
} else {
|
||||
const tagFilterType = this.tagSelectionModel.logicalOperator == 'and' ? FILTER_HAS_TAGS_ALL : FILTER_HAS_TAGS_ANY
|
||||
this.tagSelectionModel.getSelectedItems().filter(tag => tag.id).forEach(tag => {
|
||||
filterRules.push({rule_type: tagFilterType, value: tag.id?.toString()})
|
||||
})
|
||||
this.tagSelectionModel.getExcludedItems().filter(tag => tag.id).forEach(tag => {
|
||||
filterRules.push({rule_type: FILTER_DOES_NOT_HAVE_TAG, value: tag.id?.toString()})
|
||||
})
|
||||
const tagFilterType =
|
||||
this.tagSelectionModel.logicalOperator == 'and'
|
||||
? FILTER_HAS_TAGS_ALL
|
||||
: FILTER_HAS_TAGS_ANY
|
||||
this.tagSelectionModel
|
||||
.getSelectedItems()
|
||||
.filter((tag) => tag.id)
|
||||
.forEach((tag) => {
|
||||
filterRules.push({
|
||||
rule_type: tagFilterType,
|
||||
value: tag.id?.toString(),
|
||||
})
|
||||
})
|
||||
this.tagSelectionModel
|
||||
.getExcludedItems()
|
||||
.filter((tag) => tag.id)
|
||||
.forEach((tag) => {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_DOES_NOT_HAVE_TAG,
|
||||
value: tag.id?.toString(),
|
||||
})
|
||||
})
|
||||
}
|
||||
this.correspondentSelectionModel.getSelectedItems().forEach(correspondent => {
|
||||
filterRules.push({rule_type: FILTER_CORRESPONDENT, value: correspondent.id?.toString()})
|
||||
})
|
||||
this.documentTypeSelectionModel.getSelectedItems().forEach(documentType => {
|
||||
filterRules.push({rule_type: FILTER_DOCUMENT_TYPE, value: documentType.id?.toString()})
|
||||
})
|
||||
this.correspondentSelectionModel
|
||||
.getSelectedItems()
|
||||
.forEach((correspondent) => {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_CORRESPONDENT,
|
||||
value: correspondent.id?.toString(),
|
||||
})
|
||||
})
|
||||
this.documentTypeSelectionModel
|
||||
.getSelectedItems()
|
||||
.forEach((documentType) => {
|
||||
filterRules.push({
|
||||
rule_type: FILTER_DOCUMENT_TYPE,
|
||||
value: documentType.id?.toString(),
|
||||
})
|
||||
})
|
||||
if (this.dateCreatedBefore) {
|
||||
filterRules.push({rule_type: FILTER_CREATED_BEFORE, value: this.dateCreatedBefore})
|
||||
filterRules.push({
|
||||
rule_type: FILTER_CREATED_BEFORE,
|
||||
value: this.dateCreatedBefore,
|
||||
})
|
||||
}
|
||||
if (this.dateCreatedAfter) {
|
||||
filterRules.push({rule_type: FILTER_CREATED_AFTER, value: this.dateCreatedAfter})
|
||||
filterRules.push({
|
||||
rule_type: FILTER_CREATED_AFTER,
|
||||
value: this.dateCreatedAfter,
|
||||
})
|
||||
}
|
||||
if (this.dateAddedBefore) {
|
||||
filterRules.push({rule_type: FILTER_ADDED_BEFORE, value: this.dateAddedBefore})
|
||||
filterRules.push({
|
||||
rule_type: FILTER_ADDED_BEFORE,
|
||||
value: this.dateAddedBefore,
|
||||
})
|
||||
}
|
||||
if (this.dateAddedAfter) {
|
||||
filterRules.push({rule_type: FILTER_ADDED_AFTER, value: this.dateAddedAfter})
|
||||
filterRules.push({
|
||||
rule_type: FILTER_ADDED_AFTER,
|
||||
value: this.dateAddedAfter,
|
||||
})
|
||||
}
|
||||
return filterRules
|
||||
}
|
||||
@@ -260,14 +373,20 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
if (this._unmodifiedFilterRules.length != this._filterRules.length) {
|
||||
modified = true
|
||||
} else {
|
||||
modified = this._unmodifiedFilterRules.some(rule => {
|
||||
return (this._filterRules.find(fri => fri.rule_type == rule.rule_type && fri.value == rule.value) == undefined)
|
||||
modified = this._unmodifiedFilterRules.some((rule) => {
|
||||
return (
|
||||
this._filterRules.find(
|
||||
(fri) => fri.rule_type == rule.rule_type && fri.value == rule.value
|
||||
) == undefined
|
||||
)
|
||||
})
|
||||
|
||||
if (!modified) {
|
||||
// only check other direction if we havent already determined is modified
|
||||
modified = this._filterRules.some(rule => {
|
||||
this._unmodifiedFilterRules.find(fr => fr.rule_type == rule.rule_type && fr.value == rule.value) == undefined
|
||||
modified = this._filterRules.some((rule) => {
|
||||
this._unmodifiedFilterRules.find(
|
||||
(fr) => fr.rule_type == rule.rule_type && fr.value == rule.value
|
||||
) == undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -290,23 +409,27 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
subscription: Subscription
|
||||
|
||||
ngOnInit() {
|
||||
this.tagService.listAll().subscribe(result => this.tags = result.results)
|
||||
this.correspondentService.listAll().subscribe(result => this.correspondents = result.results)
|
||||
this.documentTypeService.listAll().subscribe(result => this.documentTypes = result.results)
|
||||
this.tagService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.tags = result.results))
|
||||
this.correspondentService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.correspondents = result.results))
|
||||
this.documentTypeService
|
||||
.listAll()
|
||||
.subscribe((result) => (this.documentTypes = result.results))
|
||||
|
||||
this.textFilterDebounce = new Subject<string>()
|
||||
|
||||
this.subscription = this.textFilterDebounce.pipe(
|
||||
debounceTime(400),
|
||||
distinctUntilChanged()
|
||||
).subscribe(text => {
|
||||
this._textFilter = text
|
||||
this.documentService.searchQuery = text
|
||||
this.updateRules()
|
||||
})
|
||||
this.subscription = this.textFilterDebounce
|
||||
.pipe(debounceTime(400), distinctUntilChanged())
|
||||
.subscribe((text) => {
|
||||
this._textFilter = text
|
||||
this.documentService.searchQuery = text
|
||||
this.updateRules()
|
||||
})
|
||||
|
||||
if (this._textFilter) this.documentService.searchQuery = this._textFilter
|
||||
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -324,11 +447,17 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
addCorrespondent(correspondentId: number) {
|
||||
this.correspondentSelectionModel.set(correspondentId, ToggleableItemState.Selected)
|
||||
this.correspondentSelectionModel.set(
|
||||
correspondentId,
|
||||
ToggleableItemState.Selected
|
||||
)
|
||||
}
|
||||
|
||||
addDocumentType(documentTypeId: number) {
|
||||
this.documentTypeSelectionModel.set(documentTypeId, ToggleableItemState.Selected)
|
||||
this.documentTypeSelectionModel.set(
|
||||
documentTypeId,
|
||||
ToggleableItemState.Selected
|
||||
)
|
||||
}
|
||||
|
||||
onTagsDropdownOpen() {
|
||||
@@ -344,8 +473,11 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
changeTextFilterTarget(target) {
|
||||
if (this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE && target != TEXT_FILTER_TARGET_FULLTEXT_MORELIKE) {
|
||||
this._textFilter = ""
|
||||
if (
|
||||
this.textFilterTarget == TEXT_FILTER_TARGET_FULLTEXT_MORELIKE &&
|
||||
target != TEXT_FILTER_TARGET_FULLTEXT_MORELIKE
|
||||
) {
|
||||
this._textFilter = ''
|
||||
}
|
||||
this.textFilterTarget = target
|
||||
this.textFilterInput.nativeElement.focus()
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing'
|
||||
|
||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog.component';
|
||||
import { SaveViewConfigDialogComponent } from './save-view-config-dialog.component'
|
||||
|
||||
describe('SaveViewConfigDialogComponent', () => {
|
||||
let component: SaveViewConfigDialogComponent;
|
||||
let fixture: ComponentFixture<SaveViewConfigDialogComponent>;
|
||||
let component: SaveViewConfigDialogComponent
|
||||
let fixture: ComponentFixture<SaveViewConfigDialogComponent>
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ SaveViewConfigDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
declarations: [SaveViewConfigDialogComponent],
|
||||
}).compileComponents()
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SaveViewConfigDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
fixture = TestBed.createComponent(SaveViewConfigDialogComponent)
|
||||
component = fixture.componentInstance
|
||||
fixture.detectChanges()
|
||||
})
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
expect(component).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -1,15 +1,14 @@
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { FormControl, FormGroup } from '@angular/forms';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { Component, EventEmitter, Input, 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.scss']
|
||||
styleUrls: ['./save-view-config-dialog.component.scss'],
|
||||
})
|
||||
export class SaveViewConfigDialogComponent implements OnInit {
|
||||
|
||||
constructor(private modal: NgbActiveModal) { }
|
||||
constructor(private modal: NgbActiveModal) {}
|
||||
|
||||
@Output()
|
||||
public saveClicked = new EventEmitter()
|
||||
@@ -22,7 +21,7 @@ export class SaveViewConfigDialogComponent implements OnInit {
|
||||
|
||||
closeEnabled = false
|
||||
|
||||
_defaultName = ""
|
||||
_defaultName = ''
|
||||
|
||||
get defaultName() {
|
||||
return this._defaultName
|
||||
@@ -31,7 +30,7 @@ export class SaveViewConfigDialogComponent implements OnInit {
|
||||
@Input()
|
||||
set defaultName(value: string) {
|
||||
this._defaultName = value
|
||||
this.saveViewConfigForm.patchValue({name: value})
|
||||
this.saveViewConfigForm.patchValue({ name: value })
|
||||
}
|
||||
|
||||
saveViewConfigForm = new FormGroup({
|
||||
@@ -44,7 +43,7 @@ export class SaveViewConfigDialogComponent implements OnInit {
|
||||
// wait to enable close button so it doesnt steal focus from input since its the first clickable element in the DOM
|
||||
setTimeout(() => {
|
||||
this.closeEnabled = true
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
save() {
|
||||
|
Reference in New Issue
Block a user