mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Enhancement: disable-able mail rules, add toggle to overview (#7810)
This commit is contained in:
@@ -65,10 +65,6 @@ form {
|
||||
--pngx-focus-alpha: 0;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.mh-75 {
|
||||
max-height: 75vh;
|
||||
}
|
||||
|
@@ -12,12 +12,15 @@
|
||||
<div class="col-md-4">
|
||||
<pngx-input-text [horizontal]="true" i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<pngx-input-number [horizontal]="true" i18n-title title="Rule order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="col-md-3">
|
||||
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts" formControlName="account"></pngx-input-select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<pngx-input-number [horizontal]="true" i18n-title title="Order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
||||
</div>
|
||||
<div class="col-md-2 pt-2">
|
||||
<pngx-input-switch [horizontal]="true" i18n-title title="Enabled" formControlName="enabled"></pngx-input-switch>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="mt-0"/>
|
||||
<div class="row">
|
||||
|
@@ -24,6 +24,7 @@ import { TextComponent } from '../../input/text/text.component'
|
||||
import { EditDialogMode } from '../edit-dialog.component'
|
||||
import { MailRuleEditDialogComponent } from './mail-rule-edit-dialog.component'
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||
import { SwitchComponent } from '../../input/switch/switch.component'
|
||||
|
||||
describe('MailRuleEditDialogComponent', () => {
|
||||
let component: MailRuleEditDialogComponent
|
||||
@@ -43,6 +44,7 @@ describe('MailRuleEditDialogComponent', () => {
|
||||
TagsComponent,
|
||||
SafeHtmlPipe,
|
||||
CheckComponent,
|
||||
SwitchComponent,
|
||||
],
|
||||
imports: [FormsModule, ReactiveFormsModule, NgSelectModule, NgbModule],
|
||||
providers: [
|
||||
|
@@ -153,6 +153,7 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
|
||||
return new FormGroup({
|
||||
name: new FormControl(null),
|
||||
account: new FormControl(null),
|
||||
enabled: new FormControl(true),
|
||||
folder: new FormControl('INBOX'),
|
||||
filter_from: new FormControl(null),
|
||||
filter_to: new FormControl(null),
|
||||
|
@@ -6,10 +6,6 @@ tr {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table-row-selected {
|
||||
background-color: var(--pngx-primary-faded);
|
||||
}
|
||||
|
@@ -78,6 +78,7 @@
|
||||
<div class="col" i18n>Name</div>
|
||||
<div class="col d-none d-sm-block" i18n>Sort Order</div>
|
||||
<div class="col" i18n>Account</div>
|
||||
<div class="col d-none d-sm-block" i18n>Status</div>
|
||||
<div class="col" i18n>Actions</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -86,8 +87,16 @@
|
||||
<li class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center"><button class="btn btn-link p-0 text-start" type="button" (click)="editMailRule(rule)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.MailRule)">{{rule.name}}</button></div>
|
||||
<div class="col d-flex align-items-center d-none d-sm-block">{{rule.order}}</div>
|
||||
<div class="col d-flex align-items-center d-none d-sm-flex">{{rule.order}}</div>
|
||||
<div class="col d-flex align-items-center">{{(mailAccountService.getCached(rule.account) | async)?.name}}</div>
|
||||
<div class="col d-flex align-items-center d-none d-sm-flex">
|
||||
<div class="form-check form-switch mb-0">
|
||||
<input #inputField type="checkbox" class="form-check-input cursor-pointer" [id]="rule.id+'_enable'" [(ngModel)]="rule.enabled" (change)="onMailRuleEnableToggled(rule)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.MailRule }">
|
||||
<label class="form-check-label cursor-pointer" [for]="rule.id+'_enable'">
|
||||
<code> @if(rule.enabled) { <ng-container i18n>Enabled</ng-container> } @else { <span i18n class="text-muted">Disabled</span> }</code>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="btn-group d-block d-sm-none">
|
||||
<div ngbDropdown container="body" class="d-inline-block">
|
||||
|
@@ -43,14 +43,15 @@ import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
|
||||
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
|
||||
import { SwitchComponent } from '../../common/input/switch/switch.component'
|
||||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
|
||||
import { By } from '@angular/platform-browser'
|
||||
|
||||
const mailAccounts = [
|
||||
{ id: 1, name: 'account1' },
|
||||
{ id: 2, name: 'account2' },
|
||||
]
|
||||
const mailRules = [
|
||||
{ id: 1, name: 'rule1', owner: 1, account: 1 },
|
||||
{ id: 2, name: 'rule2', owner: 2, account: 2 },
|
||||
{ id: 1, name: 'rule1', owner: 1, account: 1, enabled: true },
|
||||
{ id: 2, name: 'rule2', owner: 2, account: 2, enabled: true },
|
||||
]
|
||||
|
||||
describe('MailComponent', () => {
|
||||
@@ -321,4 +322,30 @@ describe('MailComponent', () => {
|
||||
dialog.confirmClicked.emit({ permissions: perms, merge: true })
|
||||
expect(accountPatchSpy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should update mail rule when enable is toggled', () => {
|
||||
completeSetup()
|
||||
const patchSpy = jest.spyOn(mailRuleService, 'patch')
|
||||
const toggleInput = fixture.debugElement.query(
|
||||
By.css('input[type="checkbox"]')
|
||||
)
|
||||
const toastErrorSpy = jest.spyOn(toastService, 'showError')
|
||||
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
|
||||
// fail first
|
||||
patchSpy.mockReturnValueOnce(
|
||||
throwError(() => new Error('Error getting config'))
|
||||
)
|
||||
toggleInput.nativeElement.click()
|
||||
expect(patchSpy).toHaveBeenCalled()
|
||||
expect(toastErrorSpy).toHaveBeenCalled()
|
||||
// succeed second
|
||||
patchSpy.mockReturnValueOnce(of(mailRules[0] as MailRule))
|
||||
toggleInput.nativeElement.click()
|
||||
patchSpy.mockReturnValueOnce(
|
||||
of({ ...mailRules[0], enabled: false } as MailRule)
|
||||
)
|
||||
toggleInput.nativeElement.click()
|
||||
expect(patchSpy).toHaveBeenCalled()
|
||||
expect(toastInfoSpy).toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
@@ -170,6 +170,21 @@ export class MailComponent
|
||||
this.editMailRule(clone, true)
|
||||
}
|
||||
|
||||
onMailRuleEnableToggled(rule: MailRule) {
|
||||
this.mailRuleService.patch(rule).subscribe({
|
||||
next: () => {
|
||||
this.toastService.showInfo(
|
||||
rule.enabled
|
||||
? $localize`Rule "${rule.name}" enabled.`
|
||||
: $localize`Rule "${rule.name}" disabled.`
|
||||
)
|
||||
},
|
||||
error: (e) => {
|
||||
this.toastService.showError($localize`Error toggling rule.`, e)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
deleteMailRule(rule: MailRule) {
|
||||
const modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
|
@@ -39,6 +39,8 @@ export interface MailRule extends ObjectWithPermissions {
|
||||
|
||||
order: number
|
||||
|
||||
enabled: boolean
|
||||
|
||||
folder: string
|
||||
|
||||
filter_from: string
|
||||
|
@@ -18,6 +18,7 @@ const mail_rules = [
|
||||
id: 1,
|
||||
account: 1,
|
||||
order: 1,
|
||||
enabled: true,
|
||||
folder: 'INBOX',
|
||||
filter_from: null,
|
||||
filter_to: null,
|
||||
@@ -36,6 +37,7 @@ const mail_rules = [
|
||||
id: 2,
|
||||
account: 1,
|
||||
order: 1,
|
||||
enabled: true,
|
||||
folder: 'INBOX',
|
||||
filter_from: null,
|
||||
filter_to: null,
|
||||
@@ -54,6 +56,7 @@ const mail_rules = [
|
||||
id: 3,
|
||||
account: 1,
|
||||
order: 1,
|
||||
enabled: true,
|
||||
folder: 'INBOX',
|
||||
filter_from: null,
|
||||
filter_to: null,
|
||||
|
@@ -369,6 +369,10 @@ textarea,
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul.pagination {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user