mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-04 03:27:12 -05:00 
			
		
		
		
	Handle all ASN filtering rules
This commit is contained in:
		
							parent
							
								
									7785431152
								
							
						
					
					
						commit
						48637188a7
					
				@ -8,13 +8,10 @@
 | 
			
		||||
              <button *ngFor="let t of textFilterTargets" ngbDropdownItem [class.active]="textFilterTarget == t.id" (click)="changeTextFilterTarget(t.id)">{{t.name}}</button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div *ngIf="textFilterTarget == 'asn'" class="input-group-text py-0">
 | 
			
		||||
            <div class="form-check form-switch m-0">
 | 
			
		||||
              <input class="form-check-input" type="checkbox" role="switch" [(ngModel)]="textFilterTargetIsNull" (change)="updateRules()">
 | 
			
		||||
              <label class="form-check-label" [class.text-muted]="!textFilterTargetIsNull" i18n>Is empty</label>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
          <input #textFilterInput class="form-control form-control-sm" type="text" [disabled]="textFilterTargetIsNull" [(ngModel)]="textFilter" (keyup.enter)="textFilterEnter()" [readonly]="textFilterTarget == 'fulltext-morelike'">
 | 
			
		||||
          <select *ngIf="textFilterTarget == 'asn'" class="form-select flex-grow-0 w-auto" [(ngModel)]="textFilterModifier" (change)="textFilterModifierChange()">
 | 
			
		||||
            <option *ngFor="let m of textFilterModifiers" ngbDropdownItem [value]="m.id">{{m.label}}</option>
 | 
			
		||||
          </select>
 | 
			
		||||
          <input #textFilterInput class="form-control form-control-sm" type="text" [disabled]="textFilterModifierIsNull" [(ngModel)]="textFilter" (keyup.enter)="textFilterEnter()" [readonly]="textFilterTarget == 'fulltext-morelike'">
 | 
			
		||||
         </div>
 | 
			
		||||
     </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,8 @@ import {
 | 
			
		||||
  FILTER_TITLE,
 | 
			
		||||
  FILTER_TITLE_CONTENT,
 | 
			
		||||
  FILTER_ASN_ISNULL,
 | 
			
		||||
  FILTER_ASN_GT,
 | 
			
		||||
  FILTER_ASN_LT,
 | 
			
		||||
} 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'
 | 
			
		||||
@ -46,6 +48,12 @@ 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_MODIFIER_EQUALS = 'equals'
 | 
			
		||||
const TEXT_FILTER_MODIFIER_NULL = 'is null'
 | 
			
		||||
const TEXT_FILTER_MODIFIER_NOTNULL = 'not null'
 | 
			
		||||
const TEXT_FILTER_MODIFIER_GT = 'greater'
 | 
			
		||||
const TEXT_FILTER_MODIFIER_LT = 'less'
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-filter-editor',
 | 
			
		||||
  templateUrl: './filter-editor.component.html',
 | 
			
		||||
@ -136,13 +144,45 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  textFilterTarget = TEXT_FILTER_TARGET_TITLE_CONTENT
 | 
			
		||||
  textFilterTargetIsNull: boolean = false
 | 
			
		||||
 | 
			
		||||
  get textFilterTargetName() {
 | 
			
		||||
    return this.textFilterTargets.find((t) => t.id == this.textFilterTarget)
 | 
			
		||||
      ?.name
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public textFilterModifier: string
 | 
			
		||||
 | 
			
		||||
  get textFilterModifiers() {
 | 
			
		||||
    return [
 | 
			
		||||
      {
 | 
			
		||||
        id: TEXT_FILTER_MODIFIER_EQUALS,
 | 
			
		||||
        label: $localize`equals`,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: TEXT_FILTER_MODIFIER_NULL,
 | 
			
		||||
        label: $localize`is empty`,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: TEXT_FILTER_MODIFIER_NOTNULL,
 | 
			
		||||
        label: $localize`is not empty`,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: TEXT_FILTER_MODIFIER_GT,
 | 
			
		||||
        label: $localize`greater than`,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        id: TEXT_FILTER_MODIFIER_LT,
 | 
			
		||||
        label: $localize`less than`,
 | 
			
		||||
      },
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get textFilterModifierIsNull(): boolean {
 | 
			
		||||
    return [TEXT_FILTER_MODIFIER_NULL, TEXT_FILTER_MODIFIER_NOTNULL].includes(
 | 
			
		||||
      this.textFilterModifier
 | 
			
		||||
    )
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  tagSelectionModel = new FilterableDropdownSelectionModel()
 | 
			
		||||
  correspondentSelectionModel = new FilterableDropdownSelectionModel()
 | 
			
		||||
  documentTypeSelectionModel = new FilterableDropdownSelectionModel()
 | 
			
		||||
@ -178,7 +218,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
    this.dateAddedAfter = null
 | 
			
		||||
    this.dateCreatedBefore = null
 | 
			
		||||
    this.dateCreatedAfter = null
 | 
			
		||||
    this.textFilterTargetIsNull = false
 | 
			
		||||
    this.textFilterModifier = TEXT_FILTER_MODIFIER_EQUALS
 | 
			
		||||
 | 
			
		||||
    value.forEach((rule) => {
 | 
			
		||||
      switch (rule.rule_type) {
 | 
			
		||||
@ -259,7 +299,17 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
          break
 | 
			
		||||
        case FILTER_ASN_ISNULL:
 | 
			
		||||
          this.textFilterTarget = TEXT_FILTER_TARGET_ASN
 | 
			
		||||
          this.textFilterTargetIsNull = rule.value == 'true'
 | 
			
		||||
          this.textFilterModifier = TEXT_FILTER_MODIFIER_NULL
 | 
			
		||||
          break
 | 
			
		||||
        case FILTER_ASN_GT:
 | 
			
		||||
          this.textFilterTarget = TEXT_FILTER_TARGET_ASN
 | 
			
		||||
          this.textFilterModifier = TEXT_FILTER_MODIFIER_GT
 | 
			
		||||
          this._textFilter = rule.value
 | 
			
		||||
          break
 | 
			
		||||
        case FILTER_ASN_LT:
 | 
			
		||||
          this.textFilterTarget = TEXT_FILTER_TARGET_ASN
 | 
			
		||||
          this.textFilterModifier = TEXT_FILTER_MODIFIER_LT
 | 
			
		||||
          this._textFilter = rule.value
 | 
			
		||||
          break
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
@ -281,12 +331,30 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
      filterRules.push({ rule_type: FILTER_TITLE, value: this._textFilter })
 | 
			
		||||
    }
 | 
			
		||||
    if (this.textFilterTarget == TEXT_FILTER_TARGET_ASN) {
 | 
			
		||||
      if (this.textFilter?.length && !this.textFilterTargetIsNull) {
 | 
			
		||||
      if (
 | 
			
		||||
        this.textFilterModifier == TEXT_FILTER_MODIFIER_EQUALS &&
 | 
			
		||||
        this._textFilter
 | 
			
		||||
      ) {
 | 
			
		||||
        filterRules.push({ rule_type: FILTER_ASN, value: this._textFilter })
 | 
			
		||||
      } else if (!this.textFilter?.length) {
 | 
			
		||||
      } else if (this.textFilterModifierIsNull) {
 | 
			
		||||
        filterRules.push({
 | 
			
		||||
          rule_type: FILTER_ASN_ISNULL,
 | 
			
		||||
          value: this.textFilterTargetIsNull.toString(),
 | 
			
		||||
          value: (
 | 
			
		||||
            this.textFilterModifier == TEXT_FILTER_MODIFIER_NULL
 | 
			
		||||
          ).toString(),
 | 
			
		||||
        })
 | 
			
		||||
      } else if (
 | 
			
		||||
        [TEXT_FILTER_MODIFIER_GT, TEXT_FILTER_MODIFIER_LT].includes(
 | 
			
		||||
          this.textFilterModifier
 | 
			
		||||
        ) &&
 | 
			
		||||
        this._textFilter
 | 
			
		||||
      ) {
 | 
			
		||||
        filterRules.push({
 | 
			
		||||
          rule_type:
 | 
			
		||||
            this.textFilterModifier == TEXT_FILTER_MODIFIER_GT
 | 
			
		||||
              ? FILTER_ASN_GT
 | 
			
		||||
              : FILTER_ASN_LT,
 | 
			
		||||
          value: this._textFilter,
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@ -412,7 +480,7 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  get textFilter() {
 | 
			
		||||
    return this.textFilterTargetIsNull ? '' : this._textFilter
 | 
			
		||||
    return this.textFilterModifierIsNull ? '' : this._textFilter
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set textFilter(value) {
 | 
			
		||||
@ -512,4 +580,18 @@ export class FilterEditorComponent implements OnInit, OnDestroy {
 | 
			
		||||
    this.textFilterInput.nativeElement.focus()
 | 
			
		||||
    this.updateRules()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  textFilterModifierChange() {
 | 
			
		||||
    if (
 | 
			
		||||
      this.textFilterModifierIsNull ||
 | 
			
		||||
      ([
 | 
			
		||||
        TEXT_FILTER_MODIFIER_EQUALS,
 | 
			
		||||
        TEXT_FILTER_MODIFIER_GT,
 | 
			
		||||
        TEXT_FILTER_MODIFIER_LT,
 | 
			
		||||
      ].includes(this.textFilterModifier) &&
 | 
			
		||||
        this._textFilter)
 | 
			
		||||
    ) {
 | 
			
		||||
      this.updateRules()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -20,11 +20,13 @@ export const FILTER_MODIFIED_AFTER = 16
 | 
			
		||||
export const FILTER_DOES_NOT_HAVE_TAG = 17
 | 
			
		||||
 | 
			
		||||
export const FILTER_ASN_ISNULL = 18
 | 
			
		||||
export const FILTER_ASN_GT = 19
 | 
			
		||||
export const FILTER_ASN_LT = 20
 | 
			
		||||
 | 
			
		||||
export const FILTER_TITLE_CONTENT = 19
 | 
			
		||||
export const FILTER_TITLE_CONTENT = 21
 | 
			
		||||
 | 
			
		||||
export const FILTER_FULLTEXT_QUERY = 20
 | 
			
		||||
export const FILTER_FULLTEXT_MORELIKE = 21
 | 
			
		||||
export const FILTER_FULLTEXT_QUERY = 22
 | 
			
		||||
export const FILTER_FULLTEXT_MORELIKE = 23
 | 
			
		||||
 | 
			
		||||
export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
  {
 | 
			
		||||
@ -41,14 +43,12 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    multi: false,
 | 
			
		||||
    default: '',
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_ASN,
 | 
			
		||||
    filtervar: 'archive_serial_number',
 | 
			
		||||
    datatype: 'number',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_CORRESPONDENT,
 | 
			
		||||
    filtervar: 'correspondent__id',
 | 
			
		||||
@ -63,7 +63,6 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    datatype: 'document_type',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_IS_IN_INBOX,
 | 
			
		||||
    filtervar: 'is_in_inbox',
 | 
			
		||||
@ -96,7 +95,6 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    multi: false,
 | 
			
		||||
    default: true,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_CREATED_BEFORE,
 | 
			
		||||
    filtervar: 'created__date__lt',
 | 
			
		||||
@ -109,7 +107,6 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    datatype: 'date',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_CREATED_YEAR,
 | 
			
		||||
    filtervar: 'created__year',
 | 
			
		||||
@ -141,7 +138,6 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    datatype: 'date',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_MODIFIED_BEFORE,
 | 
			
		||||
    filtervar: 'modified__date__lt',
 | 
			
		||||
@ -160,14 +156,24 @@ export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
    datatype: 'boolean',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_ASN_GT,
 | 
			
		||||
    filtervar: 'archive_serial_number__gt',
 | 
			
		||||
    datatype: 'number',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_ASN_LT,
 | 
			
		||||
    filtervar: 'archive_serial_number__lt',
 | 
			
		||||
    datatype: 'number',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_TITLE_CONTENT,
 | 
			
		||||
    filtervar: 'title_content',
 | 
			
		||||
    datatype: 'string',
 | 
			
		||||
    multi: false,
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    id: FILTER_FULLTEXT_QUERY,
 | 
			
		||||
    filtervar: 'query',
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user