import { EditDialogComponent } from 'src/app/components/common/edit-dialog/edit-dialog.component'
import {
IMAPSecurity,
- IMAPSecurityLabels,
PaperlessMailAccount,
} from 'src/app/data/paperless-mail-account'
import { MailAccountService } from 'src/app/services/rest/mail-account.service'
}
get imapSecurityOptions() {
- return IMAPSecurityLabels
+ return [
+ { id: IMAPSecurity.None, name: $localize`No encryption` },
+ { id: IMAPSecurity.SSL, name: $localize`SSL` },
+ { id: IMAPSecurity.STARTTLS, name: $localize`STARTTLS` },
+ ]
}
}
<app-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></app-input-text>
<app-input-text i18n-title title="Order" formControlName="order" [error]="error?.order"></app-input-text>
<app-input-select i18n-title title="Account" [items]="accounts" formControlName="account"></app-input-select>
- <app-input-text i18n-title title="Folder" formControlName="folder" [error]="error?.folder"></app-input-text>
- <app-input-number i18n-title title="Maximum age" formControlName="maximum_age" [error]="error?.maximum_age"></app-input-number>
+ <app-input-text i18n-title title="Folder" formControlName="folder" i18n-hint hint="Subfolders must be separated by a delimiter, often a dot ('.') or slash ('/'), but it varies by mail server." [error]="error?.folder"></app-input-text>
+ <app-input-number i18n-title title="Maximum age (days)" formControlName="maximum_age" [showAdd]="false" [error]="error?.maximum_age"></app-input-number>
<app-input-select i18n-title title="Attachment type" [items]="attachmentTypeOptions" formControlName="attachment_type"></app-input-select>
</div>
<div class="col">
+ <p class="small" i18n>Paperless will only process mails that match <em>all</em> of the filters specified below.</p>
<app-input-text i18n-title title="Filter from" formControlName="filter_from" [error]="error?.filter_from"></app-input-text>
<app-input-text i18n-title title="Filter subject" formControlName="filter_subject" [error]="error?.filter_subject"></app-input-text>
<app-input-text i18n-title title="Filter body" formControlName="filter_body" [error]="error?.filter_body"></app-input-text>
- <app-input-text i18n-title title="Filter attachment filename" formControlName="filter_attachment_filename" [error]="error?.filter_attachment_filename"></app-input-text>
- <app-input-select i18n-title title="Action" [items]="actionOptions" formControlName="attachment_type"></app-input-select>
- <app-input-text i18n-title title="Action parameter" formControlName="action_parameter" [error]="error?.action_parameter"></app-input-text>
+ <app-input-text i18n-title title="Filter attachment filename" formControlName="filter_attachment_filename" i18n-hint hint="Only consume documents which entirely match this filename if specified. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." [error]="error?.filter_attachment_filename"></app-input-text>
</div>
<div class="col">
+ <app-input-select i18n-title title="Action" [items]="actionOptions" formControlName="attachment_type" i18n-hint hint="Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched."></app-input-select>
+ <app-input-text i18n-title title="Action parameter" formControlName="action_parameter" [error]="error?.action_parameter"></app-input-text>
<app-input-select i18n-title title="Assign title from" [items]="metadataTitleOptions" formControlName="assign_title_from"></app-input-select>
<app-input-tags [allowCreate]="false" formControlName="assign_tags"></app-input-tags>
- <app-input-select i18n-title title="Assign document type" [items]="documentTypes" formControlName="assign_document_type"></app-input-select>
+ <app-input-select i18n-title title="Assign document type" [items]="documentTypes" [allowNull]="true" formControlName="assign_document_type"></app-input-select>
<app-input-select i18n-title title="Assign correspondent from" [items]="metadataCorrespondentOptions" formControlName="assign_correspondent_from"></app-input-select>
- <app-input-select i18n-title title="Assign correspondent" [items]="correspondents" formControlName="assign_correspondent"></app-input-select>
+ <app-input-select *ngIf="showCorrespondentField" i18n-title title="Assign correspondent" [items]="correspondents" [allowNull]="true" formControlName="assign_correspondent"></app-input-select>
</div>
</div>
</div>
import { PaperlessMailAccount } from 'src/app/data/paperless-mail-account'
import {
MailAction,
- MailActionOptions,
MailFilterAttachmentType,
- MailFilterAttachmentTypeOptions,
MailMetadataCorrespondentOption,
- MailMetadataCorrespondentOptionOptions,
MailMetadataTitleOption,
- MailMetadataTitleOptionOptions,
PaperlessMailRule,
} from 'src/app/data/paperless-mail-rule'
import { CorrespondentService } from 'src/app/services/rest/correspondent.service'
})
}
+ get showCorrespondentField(): boolean {
+ return (
+ this.objectForm?.get('assign_correspondent_from')?.value ==
+ MailMetadataCorrespondentOption.FromCustom
+ )
+ }
+
get attachmentTypeOptions() {
- return MailFilterAttachmentTypeOptions
+ return [
+ {
+ id: MailFilterAttachmentType.Attachments,
+ name: $localize`Only process attachments.`,
+ },
+ {
+ id: MailFilterAttachmentType.Everything,
+ name: $localize`Process all files, including 'inline' attachments.`,
+ },
+ ]
}
get actionOptions() {
- return MailActionOptions
+ return [
+ {
+ id: MailAction.Delete,
+ name: $localize`Delete`,
+ },
+ {
+ id: MailAction.Move,
+ name: $localize`Move to specified folder`,
+ },
+ {
+ id: MailAction.MarkRead,
+ name: $localize`Mark as read, don't process read mails`,
+ },
+ {
+ id: MailAction.Flag,
+ name: $localize`Flag the mail, don't process flagged mails`,
+ },
+ {
+ id: MailAction.Tag,
+ name: $localize`Tag the mail with specified tag, don't process tagged mails`,
+ },
+ ]
}
get metadataTitleOptions() {
- return MailMetadataTitleOptionOptions
+ return [
+ {
+ id: MailMetadataTitleOption.FromSubject,
+ name: $localize`Use subject as title`,
+ },
+ {
+ id: MailMetadataTitleOption.FromFilename,
+ name: $localize`Use attachment filename as title`,
+ },
+ ]
}
get metadataCorrespondentOptions() {
- return MailMetadataCorrespondentOptionOptions
+ return [
+ {
+ id: MailMetadataCorrespondentOption.FromNothing,
+ name: $localize`Do not assign a correspondent`,
+ },
+ {
+ id: MailMetadataCorrespondentOption.FromEmail,
+ name: $localize`Use mail address`,
+ },
+ {
+ id: MailMetadataCorrespondentOption.FromName,
+ name: $localize`Use name (or mail address if not available)`,
+ },
+ {
+ id: MailMetadataCorrespondentOption.FromCustom,
+ name: $localize`Use correspondent selected below`,
+ },
+ ]
}
}
<label class="form-label" [for]="inputId">{{title}}</label>
<div class="input-group" [class.is-invalid]="error">
<input type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error">
- <button class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="value">+1</button>
+ <button *ngIf="showAdd" class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="value">+1</button>
</div>
<div class="invalid-feedback">
{{error}}
-import { Component, forwardRef } from '@angular/core'
+import { Component, forwardRef, Input } from '@angular/core'
import { NG_VALUE_ACCESSOR } from '@angular/forms'
import { FILTER_ASN_ISNULL } from 'src/app/data/filter-rule-type'
import { DocumentService } from 'src/app/services/rest/document.service'
styleUrls: ['./number.component.scss'],
})
export class NumberComponent extends AbstractInputComponent<number> {
+ @Input()
+ showAdd: boolean = true
+
constructor(private documentService: DocumentService) {
super()
}
<a ngbNavLink i18n>Paperless Mail</a>
<ng-template ngbNavContent>
- <h4 i18n>Mail accounts</h4>
- <ul class="list-group" formGroupName="mailAccounts">
+ <ng-container *ngIf="mailAccounts && mailRules">
+ <h4>
+ <ng-container i18n>Mail accounts</ng-container>
+ <button type="button" class="btn btn-sm btn-primary ms-4" (click)="editMailAccount()" i18n>Add Account</button>
+ </h4>
+ <ul class="list-group" formGroupName="mailAccounts">
<li class="list-group-item">
<div class="row">
</div>
</li>
- <li *ngFor="let account of mailAccounts" class="list-group-item" [formGroupName]="account.id">
- <div class="row">
- <div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editMailAccount(account)">{{account.name}}</button></div>
- <div class="col d-flex align-items-center">{{account.imap_server}}</div>
- <div class="col">
- <div class="btn-group">
- <button class="btn btn-primary" type="button" (click)="editMailAccount(account)" i18n>Edit</button>
- <button class="btn btn-outline-danger" type="button" (click)="deleteMailAccount(account)" i18n>Delete</button>
+ <li *ngFor="let account of mailAccounts" class="list-group-item" [formGroupName]="account.id">
+ <div class="row">
+ <div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editMailAccount(account)">{{account.name}}</button></div>
+ <div class="col d-flex align-items-center">{{account.imap_server}}</div>
+ <div class="col">
+ <div class="btn-group">
+ <button class="btn btn-sm btn-primary" type="button" (click)="editMailAccount(account)" i18n>Edit</button>
+ <button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteMailAccount(account)" i18n>Delete</button>
+ </div>
</div>
</div>
</div>
<div *ngIf="mailAccounts.length == 0" i18n>No mail accounts defined.</div>
</ul>
- <h4 class="mt-4" i18n>Mail rules</h4>
- <ul class="list-group" formGroupName="mailRules">
+ <h4 class="mt-4">
+ <ng-container i18n>Mail rules</ng-container>
+ <button type="button" class="btn btn-sm btn-primary ms-4" (click)="editMailRule()" i18n>Add Rule</button>
+ </h4>
+ <ul class="list-group" formGroupName="mailRules">
<li class="list-group-item">
<div class="row">
</div>
</li>
- <li *ngFor="let rule of mailRules" class="list-group-item" [formGroupName]="rule.id">
- <div class="row">
- <div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editMailRule(rule)">{{rule.name}}</button></div>
- <div class="col d-flex align-items-center">{{(mailAccountService.getCached(rule.account) | async)?.name}}</div>
- <div class="col">
- <div class="btn-group">
- <button class="btn btn-primary" type="button" (click)="editMailRule(rule)" i18n>Edit</button>
- <button class="btn btn-outline-danger" type="button" (click)="deleteMailRule(rule)" i18n>Delete</button>
+ <li *ngFor="let rule of mailRules" class="list-group-item" [formGroupName]="rule.id">
+ <div class="row">
+ <div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editMailRule(rule)">{{rule.name}}</button></div>
+ <div class="col d-flex align-items-center">{{(mailAccountService.getCached(rule.account) | async)?.name}}</div>
+ <div class="col">
+ <div class="btn-group">
+ <button class="btn btn-sm btn-primary" type="button" (click)="editMailRule(rule)" i18n>Edit</button>
+ <button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteMailRule(rule)" i18n>Delete</button>
+ </div>
</div>
</div>
</div>
backdrop: 'static',
size: 'xl',
})
- modal.componentInstance.dialogMode = 'edit'
+ modal.componentInstance.dialogMode = account ? 'edit' : 'create'
modal.componentInstance.object = account
modal.componentInstance.success
.pipe(takeUntil(this.unsubscribeNotifier))
backdrop: 'static',
size: 'xl',
})
- modal.componentInstance.dialogMode = 'edit'
+ modal.componentInstance.dialogMode = rule ? 'edit' : 'create'
modal.componentInstance.object = rule
modal.componentInstance.success
.pipe(takeUntil(this.unsubscribeNotifier))
STARTTLS = 3,
}
-export const IMAPSecurityLabels: Array<{ id: number; name: string }> = [
- { id: IMAPSecurity.None, name: $localize`No encryption` },
- { id: IMAPSecurity.SSL, name: $localize`SSL` },
- { id: IMAPSecurity.STARTTLS, name: $localize`STARTTLS` },
-]
-
export interface PaperlessMailAccount extends ObjectWithId {
name: string
import { ObjectWithId } from './object-with-id'
-import { PaperlessCorrespondent } from './paperless-correspondent'
-import { PaperlessDocumentType } from './paperless-document-type'
-import { PaperlessMailAccount } from './paperless-mail-account'
-import { PaperlessTag } from './paperless-tag'
export enum MailFilterAttachmentType {
Attachments = 1,
Everything = 2,
}
-export const MailFilterAttachmentTypeOptions: Array<{
- id: number
- name: string
-}> = [
- {
- id: MailFilterAttachmentType.Attachments,
- name: $localize`Only process attachments.`,
- },
- {
- id: MailFilterAttachmentType.Everything,
- name: $localize`Process all files, including 'inline' attachments.`,
- },
-]
-
export enum MailAction {
Delete = 1,
Move = 2,
Tag = 5,
}
-export const MailActionOptions: Array<{ id: number; name: string }> = [
- { id: MailAction.Delete, name: $localize`Delete` },
- { id: MailAction.Move, name: $localize`Move to specified folder` },
- {
- id: MailAction.MarkRead,
- name: $localize`Mark as read, don't process read mails`,
- },
- {
- id: MailAction.Flag,
- name: $localize`Flag the mail, don't process flagged mails`,
- },
- {
- id: MailAction.Tag,
- name: $localize`Tag the mail with specified tag, don't process tagged mails`,
- },
-]
-
export enum MailMetadataTitleOption {
FromSubject = 1,
FromFilename = 2,
}
-export const MailMetadataTitleOptionOptions: Array<{
- id: number
- name: string
-}> = [
- {
- id: MailMetadataTitleOption.FromSubject,
- name: $localize`Use subject as title`,
- },
- {
- id: MailMetadataTitleOption.FromFilename,
- name: $localize`Use attachment filename as title`,
- },
-]
-
export enum MailMetadataCorrespondentOption {
FromNothing = 1,
FromEmail = 2,
FromCustom = 4,
}
-export const MailMetadataCorrespondentOptionOptions: Array<{
- id: number
- name: string
-}> = [
- {
- id: MailMetadataCorrespondentOption.FromNothing,
- name: $localize`Do not assign a correspondent`,
- },
- {
- id: MailMetadataCorrespondentOption.FromEmail,
- name: $localize`Use mail address`,
- },
- {
- id: MailMetadataCorrespondentOption.FromName,
- name: $localize`Use name (or mail address if not available)`,
- },
- {
- id: MailMetadataCorrespondentOption.FromCustom,
- name: $localize`Use correspondent selected below`,
- },
-]
-
export interface PaperlessMailRule extends ObjectWithId {
name: string