shamoon 06def8c11e frontend unit tests
toasts component testing

conditional import of angular setup-jest for vscode-jest support

Update jest.config.js

Create open-documents.service.spec.ts

Add unit tests for all REST services

settings service test

Remove component from settings service test

Create permissions.service.spec.ts

upload documents service tests

Update package.json

Create toast.service.spec.ts

Tasks service test

Statistics widget component tests

Update permissions.service.ts

Create app.component.spec.ts

settings component testing

tasks component unit testing

Management list component generic tests

Some management component tests

document notes component unit tests

Create document-list.component.spec.ts

Create save-view-config-dialog.component.spec.ts

Create filter-editor.component.spec.ts

small and large document cards unit testing

Create bulk-editor.component.spec.ts

document detail unit tests

saving work on documentdetail component spec

Create document-asn.component.spec.ts

dashboard & widgets unit testing

Fix ResizeObserver mock

common component unit tests

fix some merge errors

Update app-frame.component.spec.ts

Create page-header.component.spec.ts

input component unit tests

FilterableDropdownComponent unit testing

and found minor errors

update taskservice unit tests

Edit dialogs unit tests

Create date-dropdown.component.spec.ts

Remove selectors from guard tests

confirm dialog component tests

app frame component test

Miscellaneous component tests

Update document-list-view.service.spec.ts

directives unit tests

Remove unused resizeobserver mock

guard unit tests

Update query-params.spec.ts

try to fix flaky playwright

filter rules utils & testing

Interceptor unit tests

Pipes unit testing

Utils unit tests

Update upload-documents.service.spec.ts

consumer status service tests

Update setup-jest.ts

Create document-list-view.service.spec.ts

Update app-routing.module.ts
2023-06-15 23:53:04 -07:00

910 lines
30 KiB
TypeScript

import {
Component,
Inject,
LOCALE_ID,
OnInit,
OnDestroy,
AfterViewInit,
} from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { SavedViewService } from 'src/app/services/rest/saved-view.service'
import {
LanguageOption,
SettingsService,
} from 'src/app/services/settings.service'
import { Toast, ToastService } from 'src/app/services/toast.service'
import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms'
import {
Observable,
Subscription,
BehaviorSubject,
first,
tap,
takeUntil,
Subject,
} from 'rxjs'
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
import { ActivatedRoute, Router } from '@angular/router'
import { ViewportScroller } from '@angular/common'
import { TourService } from 'ngx-ui-tour-ng-bootstrap'
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
import { NgbModal, NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap'
import { UserService } from 'src/app/services/rest/user.service'
import { GroupService } from 'src/app/services/rest/group.service'
import { PaperlessUser } from 'src/app/data/paperless-user'
import { PaperlessGroup } from 'src/app/data/paperless-group'
import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component'
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component'
import { PaperlessMailAccount } from 'src/app/data/paperless-mail-account'
import { PaperlessMailRule } from 'src/app/data/paperless-mail-rule'
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
import { MailRuleService } from 'src/app/services/rest/mail-rule.service'
import { MailAccountEditDialogComponent } from '../../common/edit-dialog/mail-account-edit-dialog/mail-account-edit-dialog.component'
import { MailRuleEditDialogComponent } from '../../common/edit-dialog/mail-rule-edit-dialog/mail-rule-edit-dialog.component'
import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
enum SettingsNavIDs {
General = 1,
Notifications = 2,
SavedViews = 3,
Mail = 4,
UsersGroups = 5,
}
@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.scss'],
})
export class SettingsComponent
extends ComponentWithPermissions
implements OnInit, AfterViewInit, OnDestroy, DirtyComponent
{
SettingsNavIDs = SettingsNavIDs
activeNavID: number
savedViewGroup = new FormGroup({})
usersGroup = new FormGroup({})
groupsGroup = new FormGroup({})
mailAccountGroup = new FormGroup({})
mailRuleGroup = new FormGroup({})
settingsForm = new FormGroup({
bulkEditConfirmationDialogs: new FormControl(null),
bulkEditApplyOnClose: new FormControl(null),
documentListItemPerPage: new FormControl(null),
slimSidebarEnabled: new FormControl(null),
darkModeUseSystem: new FormControl(null),
darkModeEnabled: new FormControl(null),
darkModeInvertThumbs: new FormControl(null),
themeColor: new FormControl(null),
useNativePdfViewer: new FormControl(null),
displayLanguage: new FormControl(null),
dateLocale: new FormControl(null),
dateFormat: new FormControl(null),
notesEnabled: new FormControl(null),
updateCheckingEnabled: new FormControl(null),
notificationsConsumerNewDocument: new FormControl(null),
notificationsConsumerSuccess: new FormControl(null),
notificationsConsumerFailed: new FormControl(null),
notificationsConsumerSuppressOnDashboard: new FormControl(null),
usersGroup: this.usersGroup,
groupsGroup: this.groupsGroup,
savedViewsWarnOnUnsavedChange: new FormControl(null),
savedViews: this.savedViewGroup,
mailAccounts: this.mailAccountGroup,
mailRules: this.mailRuleGroup,
})
savedViews: PaperlessSavedView[]
mailAccounts: PaperlessMailAccount[]
mailRules: PaperlessMailRule[]
store: BehaviorSubject<any>
storeSub: Subscription
isDirty$: Observable<boolean>
isDirty: boolean = false
unsubscribeNotifier: Subject<any> = new Subject()
savePending: boolean = false
users: PaperlessUser[]
groups: PaperlessGroup[]
get computedDateLocale(): string {
return (
this.settingsForm.value.dateLocale ||
this.settingsForm.value.displayLanguage ||
this.currentLocale
)
}
constructor(
public savedViewService: SavedViewService,
public mailAccountService: MailAccountService,
public mailRuleService: MailRuleService,
private documentListViewService: DocumentListViewService,
private toastService: ToastService,
private settings: SettingsService,
@Inject(LOCALE_ID) public currentLocale: string,
private viewportScroller: ViewportScroller,
private activatedRoute: ActivatedRoute,
public readonly tourService: TourService,
private usersService: UserService,
private groupsService: GroupService,
private router: Router,
private modalService: NgbModal
) {
super()
this.settings.settingsSaved.subscribe(() => {
if (!this.savePending) this.initialize()
})
}
ngOnInit() {
this.initialize()
this.activatedRoute.paramMap.subscribe((paramMap) => {
const section = paramMap.get('section')
if (section) {
const navIDKey: string = Object.keys(SettingsNavIDs).find(
(navID) => navID.toLowerCase() == section
)
if (navIDKey) {
this.activeNavID = SettingsNavIDs[navIDKey]
this.maybeInitializeTab(this.activeNavID)
}
}
})
}
ngAfterViewInit(): void {
if (this.activatedRoute.snapshot.fragment) {
this.viewportScroller.scrollToAnchor(
this.activatedRoute.snapshot.fragment
)
}
}
private getCurrentSettings() {
return {
bulkEditConfirmationDialogs: this.settings.get(
SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS
),
bulkEditApplyOnClose: this.settings.get(
SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE
),
documentListItemPerPage: this.settings.get(
SETTINGS_KEYS.DOCUMENT_LIST_SIZE
),
slimSidebarEnabled: this.settings.get(SETTINGS_KEYS.SLIM_SIDEBAR),
darkModeUseSystem: this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM),
darkModeEnabled: this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED),
darkModeInvertThumbs: this.settings.get(
SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED
),
themeColor: this.settings.get(SETTINGS_KEYS.THEME_COLOR),
useNativePdfViewer: this.settings.get(
SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER
),
displayLanguage: this.settings.getLanguage(),
dateLocale: this.settings.get(SETTINGS_KEYS.DATE_LOCALE),
dateFormat: this.settings.get(SETTINGS_KEYS.DATE_FORMAT),
notesEnabled: this.settings.get(SETTINGS_KEYS.NOTES_ENABLED),
updateCheckingEnabled: this.settings.get(
SETTINGS_KEYS.UPDATE_CHECKING_ENABLED
),
notificationsConsumerNewDocument: this.settings.get(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT
),
notificationsConsumerSuccess: this.settings.get(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS
),
notificationsConsumerFailed: this.settings.get(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED
),
notificationsConsumerSuppressOnDashboard: this.settings.get(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD
),
savedViewsWarnOnUnsavedChange: this.settings.get(
SETTINGS_KEYS.SAVED_VIEWS_WARN_ON_UNSAVED_CHANGE
),
usersGroup: {},
groupsGroup: {},
savedViews: {},
mailAccounts: {},
mailRules: {},
}
}
onNavChange(navChangeEvent: NgbNavChangeEvent) {
this.maybeInitializeTab(navChangeEvent.nextId)
const [foundNavIDkey] = Object.entries(SettingsNavIDs).find(
([, navIDValue]) => navIDValue == navChangeEvent.nextId
)
if (foundNavIDkey)
// if its dirty we need to wait for confirmation
this.router
.navigate(['settings', foundNavIDkey.toLowerCase()])
.then((navigated) => {
if (!navigated && this.isDirty) {
this.activeNavID = navChangeEvent.activeId
} else if (navigated && this.isDirty) {
this.initialize()
}
})
}
// Load tab contents 'on demand', either on mouseover or focusin (i.e. before click) or called from nav change event
maybeInitializeTab(navID: number): void {
if (navID == SettingsNavIDs.SavedViews && !this.savedViews) {
this.savedViewService.listAll().subscribe((r) => {
this.savedViews = r.results
this.initialize(false)
})
} else if (
navID == SettingsNavIDs.UsersGroups &&
(!this.users || !this.groups)
) {
this.usersService.listAll().subscribe((r) => {
this.users = r.results
this.groupsService.listAll().subscribe((r) => {
this.groups = r.results
this.initialize(false)
})
})
} else if (
navID == SettingsNavIDs.Mail &&
(!this.mailAccounts || !this.mailRules)
) {
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.initialize(false)
})
})
}
}
initialize(resetSettings: boolean = true) {
this.unsubscribeNotifier.next(true)
const currentFormValue = this.settingsForm.value
let storeData = this.getCurrentSettings()
if (this.savedViews) {
this.emptyGroup(this.savedViewGroup)
for (let view of this.savedViews) {
storeData.savedViews[view.id.toString()] = {
id: view.id,
name: view.name,
show_on_dashboard: view.show_on_dashboard,
show_in_sidebar: view.show_in_sidebar,
}
this.savedViewGroup.addControl(
view.id.toString(),
new FormGroup({
id: new FormControl(null),
name: new FormControl(null),
show_on_dashboard: new FormControl(null),
show_in_sidebar: new FormControl(null),
})
)
}
}
if (this.users && this.groups) {
this.emptyGroup(this.usersGroup)
this.emptyGroup(this.groupsGroup)
for (let user of this.users) {
storeData.usersGroup[user.id.toString()] = {
id: user.id,
username: user.username,
first_name: user.first_name,
last_name: user.last_name,
is_active: user.is_active,
is_superuser: user.is_superuser,
groups: user.groups,
user_permissions: user.user_permissions,
}
this.usersGroup.addControl(
user.id.toString(),
new FormGroup({
id: new FormControl(null),
username: new FormControl(null),
first_name: new FormControl(null),
last_name: new FormControl(null),
is_active: new FormControl(null),
is_superuser: new FormControl(null),
groups: new FormControl(null),
user_permissions: new FormControl(null),
})
)
}
for (let group of this.groups) {
storeData.groupsGroup[group.id.toString()] = {
id: group.id,
name: group.name,
permissions: group.permissions,
}
this.groupsGroup.addControl(
group.id.toString(),
new FormGroup({
id: new FormControl(null),
name: new FormControl(null),
permissions: new FormControl(null),
})
)
}
}
if (this.mailAccounts && this.mailRules) {
this.emptyGroup(this.mailAccountGroup)
this.emptyGroup(this.mailRuleGroup)
for (let account of this.mailAccounts) {
storeData.mailAccounts[account.id.toString()] = {
id: account.id,
name: account.name,
imap_server: account.imap_server,
imap_port: account.imap_port,
imap_security: account.imap_security,
username: account.username,
password: account.password,
character_set: account.character_set,
}
this.mailAccountGroup.addControl(
account.id.toString(),
new FormGroup({
id: new FormControl(null),
name: new FormControl(null),
imap_server: new FormControl(null),
imap_port: new FormControl(null),
imap_security: new FormControl(null),
username: new FormControl(null),
password: new FormControl(null),
character_set: new FormControl(null),
})
)
}
for (let rule of this.mailRules) {
storeData.mailRules[rule.id.toString()] = {
name: rule.name,
account: rule.account,
folder: rule.folder,
filter_from: rule.filter_from,
filter_to: rule.filter_to,
filter_subject: rule.filter_subject,
filter_body: rule.filter_body,
filter_attachment_filename: rule.filter_attachment_filename,
maximum_age: rule.maximum_age,
attachment_type: rule.attachment_type,
action: rule.action,
action_parameter: rule.action_parameter,
assign_title_from: rule.assign_title_from,
assign_tags: rule.assign_tags,
assign_document_type: rule.assign_document_type,
assign_correspondent_from: rule.assign_correspondent_from,
assign_correspondent: rule.assign_correspondent,
}
this.mailRuleGroup.addControl(
rule.id.toString(),
new FormGroup({
name: new FormControl(null),
account: new FormControl(null),
folder: new FormControl(null),
filter_from: new FormControl(null),
filter_to: new FormControl(null),
filter_subject: new FormControl(null),
filter_body: new FormControl(null),
filter_attachment_filename: new FormControl(null),
maximum_age: new FormControl(null),
attachment_type: new FormControl(null),
action: new FormControl(null),
action_parameter: new FormControl(null),
assign_title_from: new FormControl(null),
assign_tags: new FormControl(null),
assign_document_type: new FormControl(null),
assign_correspondent_from: new FormControl(null),
assign_correspondent: new FormControl(null),
})
)
}
}
this.store = new BehaviorSubject(storeData)
this.storeSub = this.store.asObservable().subscribe((state) => {
this.settingsForm.patchValue(state, { emitEvent: false })
})
// Initialize dirtyCheck
this.isDirty$ = dirtyCheck(this.settingsForm, this.store.asObservable())
// Record dirty in case we need to 'undo' appearance settings if not saved on close
this.isDirty$
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((dirty) => {
this.isDirty = dirty
})
// "Live" visual changes prior to save
this.settingsForm.valueChanges
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {
this.settings.updateAppearanceSettings(
this.settingsForm.get('darkModeUseSystem').value,
this.settingsForm.get('darkModeEnabled').value,
this.settingsForm.get('themeColor').value
)
})
if (!resetSettings && currentFormValue) {
// prevents loss of unsaved changes
this.settingsForm.patchValue(currentFormValue)
}
}
private emptyGroup(group: FormGroup) {
Object.keys(group.controls).forEach((key) => group.removeControl(key))
}
ngOnDestroy() {
if (this.isDirty) this.settings.updateAppearanceSettings() // in case user changed appearance but didnt save
this.storeSub && this.storeSub.unsubscribe()
}
deleteSavedView(savedView: PaperlessSavedView) {
this.savedViewService.delete(savedView).subscribe(() => {
this.savedViewGroup.removeControl(savedView.id.toString())
this.savedViews.splice(this.savedViews.indexOf(savedView), 1)
this.toastService.showInfo(
$localize`Saved view "${savedView.name}" deleted.`
)
this.savedViewService.clearCache()
this.savedViewService.listAll().subscribe((r) => {
this.savedViews = r.results
this.initialize(true)
})
})
}
private saveLocalSettings() {
this.savePending = true
const reloadRequired =
this.settingsForm.value.displayLanguage !=
this.store?.getValue()['displayLanguage'] || // displayLanguage is dirty
(this.settingsForm.value.updateCheckingEnabled !=
this.store?.getValue()['updateCheckingEnabled'] &&
this.settingsForm.value.updateCheckingEnabled) // update checking was turned on
this.settings.set(
SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE,
this.settingsForm.value.bulkEditApplyOnClose
)
this.settings.set(
SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS,
this.settingsForm.value.bulkEditConfirmationDialogs
)
this.settings.set(
SETTINGS_KEYS.DOCUMENT_LIST_SIZE,
this.settingsForm.value.documentListItemPerPage
)
this.settings.set(
SETTINGS_KEYS.SLIM_SIDEBAR,
this.settingsForm.value.slimSidebarEnabled
)
this.settings.set(
SETTINGS_KEYS.DARK_MODE_USE_SYSTEM,
this.settingsForm.value.darkModeUseSystem
)
this.settings.set(
SETTINGS_KEYS.DARK_MODE_ENABLED,
(this.settingsForm.value.darkModeEnabled == true).toString()
)
this.settings.set(
SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED,
(this.settingsForm.value.darkModeInvertThumbs == true).toString()
)
this.settings.set(
SETTINGS_KEYS.THEME_COLOR,
this.settingsForm.value.themeColor.toString()
)
this.settings.set(
SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER,
this.settingsForm.value.useNativePdfViewer
)
this.settings.set(
SETTINGS_KEYS.DATE_LOCALE,
this.settingsForm.value.dateLocale
)
this.settings.set(
SETTINGS_KEYS.DATE_FORMAT,
this.settingsForm.value.dateFormat
)
this.settings.set(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT,
this.settingsForm.value.notificationsConsumerNewDocument
)
this.settings.set(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS,
this.settingsForm.value.notificationsConsumerSuccess
)
this.settings.set(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED,
this.settingsForm.value.notificationsConsumerFailed
)
this.settings.set(
SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD,
this.settingsForm.value.notificationsConsumerSuppressOnDashboard
)
this.settings.set(
SETTINGS_KEYS.NOTES_ENABLED,
this.settingsForm.value.notesEnabled
)
this.settings.set(
SETTINGS_KEYS.UPDATE_CHECKING_ENABLED,
this.settingsForm.value.updateCheckingEnabled
)
this.settings.set(
SETTINGS_KEYS.SAVED_VIEWS_WARN_ON_UNSAVED_CHANGE,
this.settingsForm.value.savedViewsWarnOnUnsavedChange
)
this.settings.setLanguage(this.settingsForm.value.displayLanguage)
this.settings
.storeSettings()
.pipe(first())
.pipe(tap(() => (this.savePending = false)))
.subscribe({
next: () => {
this.store.next(this.settingsForm.value)
this.documentListViewService.updatePageSize()
this.settings.updateAppearanceSettings()
let savedToast: Toast = {
title: $localize`Settings saved`,
content: $localize`Settings were saved successfully.`,
delay: 5000,
}
if (reloadRequired) {
savedToast.content = $localize`Settings were saved successfully. Reload is required to apply some changes.`
savedToast.actionName = $localize`Reload now`
savedToast.action = () => {
location.reload()
}
}
this.toastService.show(savedToast)
},
error: (error) => {
this.toastService.showError(
$localize`An error occurred while saving settings.`,
10000,
JSON.stringify(error)
)
},
})
}
get displayLanguageOptions(): LanguageOption[] {
return [{ code: '', name: $localize`Use system language` }].concat(
this.settings.getLanguageOptions()
)
}
get dateLocaleOptions(): LanguageOption[] {
return [
{ code: '', name: $localize`Use date format of display language` },
].concat(this.settings.getDateLocaleOptions())
}
get today() {
return new Date()
}
saveSettings() {
let x = []
for (let id in this.savedViewGroup.value) {
x.push(this.savedViewGroup.value[id])
}
if (x.length > 0) {
this.savedViewService.patchMany(x).subscribe(
(s) => {
this.saveLocalSettings()
},
(error) => {
this.toastService.showError(
$localize`Error while storing settings on server.`,
10000,
JSON.stringify(error)
)
}
)
} else {
this.saveLocalSettings()
}
}
clearThemeColor() {
this.settingsForm.get('themeColor').patchValue('')
}
editUser(user: PaperlessUser) {
var modal = this.modalService.open(UserEditDialogComponent, {
backdrop: 'static',
size: 'xl',
})
modal.componentInstance.dialogMode = user
? EditDialogMode.EDIT
: EditDialogMode.CREATE
modal.componentInstance.object = user
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((newUser: PaperlessUser) => {
if (
newUser.id === this.settings.currentUser.id &&
(modal.componentInstance as UserEditDialogComponent).passwordIsSet
) {
this.toastService.showInfo(
$localize`Password has been changed, you will be logged out momentarily.`
)
setTimeout(() => {
window.location.href = `${window.location.origin}/accounts/logout/?next=/accounts/login/`
}, 2500)
} else {
this.toastService.showInfo(
$localize`Saved user "${newUser.username}".`
)
this.usersService.listAll().subscribe((r) => {
this.users = r.results
this.initialize()
})
}
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving user.`,
10000,
JSON.stringify(e)
)
})
}
deleteUser(user: PaperlessUser) {
let modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete user account`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this user account.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.usersService.delete(user).subscribe({
next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted user`)
this.usersService.listAll().subscribe((r) => {
this.users = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting user.`,
10000,
JSON.stringify(e)
)
},
})
})
}
editGroup(group: PaperlessGroup) {
var modal = this.modalService.open(GroupEditDialogComponent, {
backdrop: 'static',
size: 'lg',
})
modal.componentInstance.dialogMode = group
? EditDialogMode.EDIT
: EditDialogMode.CREATE
modal.componentInstance.object = group
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((newGroup) => {
this.toastService.showInfo($localize`Saved group "${newGroup.name}".`)
this.groupsService.listAll().subscribe((r) => {
this.groups = r.results
this.initialize()
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving group.`,
10000,
JSON.stringify(e)
)
})
}
deleteGroup(group: PaperlessGroup) {
let modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete user group`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this user group.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.groupsService.delete(group).subscribe({
next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted group`)
this.groupsService.listAll().subscribe((r) => {
this.groups = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting group.`,
10000,
JSON.stringify(e)
)
},
})
})
}
getGroupName(id: number): string {
return this.groups?.find((g) => g.id === id)?.name ?? ''
}
editMailAccount(account: PaperlessMailAccount) {
const modal = this.modalService.open(MailAccountEditDialogComponent, {
backdrop: 'static',
size: 'xl',
})
modal.componentInstance.dialogMode = account
? EditDialogMode.EDIT
: EditDialogMode.CREATE
modal.componentInstance.object = account
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((newMailAccount) => {
this.toastService.showInfo(
$localize`Saved account "${newMailAccount.name}".`
)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize()
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving account.`,
10000,
JSON.stringify(e)
)
})
}
deleteMailAccount(account: PaperlessMailAccount) {
const modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete mail account`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this mail account.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.mailAccountService.delete(account).subscribe({
next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted mail account`)
this.mailAccountService.clearCache()
this.mailAccountService.listAll().subscribe((r) => {
this.mailAccounts = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting mail account.`,
10000,
JSON.stringify(e)
)
},
})
})
}
editMailRule(rule: PaperlessMailRule) {
const modal = this.modalService.open(MailRuleEditDialogComponent, {
backdrop: 'static',
size: 'xl',
})
modal.componentInstance.dialogMode = rule
? EditDialogMode.EDIT
: EditDialogMode.CREATE
modal.componentInstance.object = rule
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((newMailRule) => {
this.toastService.showInfo($localize`Saved rule "${newMailRule.name}".`)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
})
modal.componentInstance.failed
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((e) => {
this.toastService.showError(
$localize`Error saving rule.`,
10000,
JSON.stringify(e)
)
})
}
deleteMailRule(rule: PaperlessMailRule) {
const modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete mail rule`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this mail rule.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.mailRuleService.delete(rule).subscribe({
next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted mail rule`)
this.mailRuleService.clearCache()
this.mailRuleService.listAll().subscribe((r) => {
this.mailRules = r.results
this.initialize(true)
})
},
error: (e) => {
this.toastService.showError(
$localize`Error deleting mail rule.`,
10000,
JSON.stringify(e)
)
},
})
})
}
}