mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	clickable tags and correspondents fixes #54
This commit is contained in:
		@@ -1,2 +1,2 @@
 | 
			
		||||
<span *ngIf="!clickable" class="badge" [style.background]="getColour().value" [style.color]="getColour().textColor">{{tag.name}}</span>
 | 
			
		||||
<a [routerLink]="" *ngIf="clickable" class="badge" [style.background]="getColour().value" [style.color]="getColour().textColor">{{tag.name}}</a>
 | 
			
		||||
<a [routerLink]="" [title]="linkTitle" *ngIf="clickable" class="badge" [style.background]="getColour().value" [style.color]="getColour().textColor">{{tag.name}}</a>
 | 
			
		||||
@@ -13,6 +13,9 @@ export class TagComponent implements OnInit {
 | 
			
		||||
  @Input()
 | 
			
		||||
  tag: PaperlessTag
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  linkTitle: string = ""
 | 
			
		||||
 | 
			
		||||
  @Input()
 | 
			
		||||
  clickable: boolean = false
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,12 @@
 | 
			
		||||
      <div class="card-body">
 | 
			
		||||
 | 
			
		||||
        <div class="d-flex justify-content-between align-items-center">
 | 
			
		||||
          <h5 class="card-title">{{document.correspondent ? document.correspondent.name + ': ' : ''}}{{document.title}}<app-tag [tag]="t" *ngFor="let t of document.tags" class="ml-1"></app-tag></h5>
 | 
			
		||||
          <h5 class="card-title">    
 | 
			
		||||
            <ng-container *ngIf="document.correspondent">
 | 
			
		||||
              <a [routerLink]="" title="Filter by correspondent" (click)="clickCorrespondent.emit(document.correspondent)" class="font-weight-bold">{{document.correspondent.name}}</a>:
 | 
			
		||||
            </ng-container>
 | 
			
		||||
            {{document.title}}<app-tag [tag]="t" linkTitle="Filter by tag" *ngFor="let t of document.tags" class="ml-1" (click)="clickTag.emit(t)" [clickable]="true"></app-tag>
 | 
			
		||||
          </h5>
 | 
			
		||||
          <h5 class="card-title" *ngIf="document.archive_serial_number">#{{document.archive_serial_number}}</h5>
 | 
			
		||||
        </div>
 | 
			
		||||
        <p class="card-text">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
import { Component, Input, OnInit } from '@angular/core';
 | 
			
		||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 | 
			
		||||
import { DomSanitizer } from '@angular/platform-browser';
 | 
			
		||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
 | 
			
		||||
import { PaperlessTag } from 'src/app/data/paperless-tag';
 | 
			
		||||
import { DocumentService } from 'src/app/services/rest/document.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@@ -18,6 +19,12 @@ export class DocumentCardLargeComponent implements OnInit {
 | 
			
		||||
  @Input()
 | 
			
		||||
  details: any
 | 
			
		||||
 | 
			
		||||
  @Output()
 | 
			
		||||
  clickTag = new EventEmitter<PaperlessTag>()
 | 
			
		||||
 | 
			
		||||
  @Output()
 | 
			
		||||
  clickCorrespondent = new EventEmitter<PaperlessDocument>()
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,14 +2,16 @@
 | 
			
		||||
  <div class="card h-100 shadow-sm">
 | 
			
		||||
    <div class=" border-bottom doc-img pr-1" [ngStyle]="{'background-image': 'url(' + getThumbUrl() + ')'}">
 | 
			
		||||
      <div class="row" *ngFor="let t of document.tags">
 | 
			
		||||
        <app-tag [tag]="t" class="col text-right"></app-tag>
 | 
			
		||||
        <app-tag [tag]="t" class="col text-right" (click)="clickTag.emit(t)" [clickable]="true" linkTitle="Filter by tag"></app-tag>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <div class="card-body p-2">
 | 
			
		||||
      <p class="card-text">
 | 
			
		||||
        <span class="font-weight-bold">{{document.correspondent? document.correspondent.name + ': ' : ''}}</span> {{document.title}}
 | 
			
		||||
        <ng-container *ngIf="document.correspondent">
 | 
			
		||||
          <a [routerLink]="" title="Filter by correspondent" (click)="clickCorrespondent.emit(document.correspondent)" class="font-weight-bold">{{document.correspondent.name}}</a>:
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        {{document.title}}
 | 
			
		||||
      </p>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="card-footer">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import { Component, Input, OnInit } from '@angular/core';
 | 
			
		||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 | 
			
		||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
 | 
			
		||||
import { PaperlessTag } from 'src/app/data/paperless-tag';
 | 
			
		||||
import { DocumentService } from 'src/app/services/rest/document.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@@ -14,6 +15,12 @@ export class DocumentCardSmallComponent implements OnInit {
 | 
			
		||||
  @Input()
 | 
			
		||||
  document: PaperlessDocument
 | 
			
		||||
 | 
			
		||||
  @Output()
 | 
			
		||||
  clickTag = new EventEmitter<PaperlessTag>()
 | 
			
		||||
 | 
			
		||||
  @Output()
 | 
			
		||||
  clickCorrespondent = new EventEmitter<PaperlessDocument>()
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,9 @@ import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { ActivatedRoute } from '@angular/router';
 | 
			
		||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 | 
			
		||||
import { cloneFilterRules, FilterRule } from 'src/app/data/filter-rule';
 | 
			
		||||
import { FILTER_CORRESPONDENT, FILTER_HAS_TAG, FILTER_RULE_TYPES } from 'src/app/data/filter-rule-type';
 | 
			
		||||
import { PaperlessCorrespondent } from 'src/app/data/paperless-correspondent';
 | 
			
		||||
import { PaperlessTag } from 'src/app/data/paperless-tag';
 | 
			
		||||
import { SavedViewConfig } from 'src/app/data/saved-view-config';
 | 
			
		||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service';
 | 
			
		||||
import { DOCUMENT_SORT_FIELDS } from 'src/app/services/rest/document.service';
 | 
			
		||||
@@ -86,4 +89,24 @@ export class DocumentListComponent implements OnInit {
 | 
			
		||||
      modal.close()
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  filterByTag(t: PaperlessTag) {
 | 
			
		||||
    if (this.filterRules.find(rule => rule.type.id == FILTER_HAS_TAG && rule.value == t.id)) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.filterRules.push({type: FILTER_RULE_TYPES.find(t => t.id == FILTER_HAS_TAG), value: t.id})
 | 
			
		||||
    this.applyFilterRules()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  filterByCorrespondent(c: PaperlessCorrespondent) {
 | 
			
		||||
    let existing_rule = this.filterRules.find(rule => rule.type.id == FILTER_CORRESPONDENT)
 | 
			
		||||
    if (existing_rule) {
 | 
			
		||||
      existing_rule.value = c.id
 | 
			
		||||
    } else {
 | 
			
		||||
      this.filterRules.push({type: FILTER_RULE_TYPES.find(t => t.id == FILTER_CORRESPONDENT), value: c.id})
 | 
			
		||||
    }
 | 
			
		||||
    this.applyFilterRules()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,51 @@
 | 
			
		||||
export const FILTER_TITLE = 0
 | 
			
		||||
export const FILTER_CONTENT = 1
 | 
			
		||||
export const FILTER_ASN = 2
 | 
			
		||||
export const FILTER_CORRESPONDENT = 3
 | 
			
		||||
export const FILTER_DOCUMENT_TYPE = 4
 | 
			
		||||
export const FILTER_IS_IN_INBOX = 5
 | 
			
		||||
export const FILTER_HAS_TAG = 6
 | 
			
		||||
export const FILTER_HAS_ANY_TAG = 7
 | 
			
		||||
export const FILTER_CREATED_BEFORE = 8
 | 
			
		||||
export const FILTER_CREATED_AFTER = 9
 | 
			
		||||
export const FILTER_CREATED_YEAR = 10
 | 
			
		||||
export const FILTER_CREATED_MONTH = 11
 | 
			
		||||
export const FILTER_CREATED_DAY = 12
 | 
			
		||||
export const FILTER_ADDED_BEFORE = 13
 | 
			
		||||
export const FILTER_ADDED_AFTER = 14
 | 
			
		||||
export const FILTER_MODIFIED_BEFORE = 15
 | 
			
		||||
export const FILTER_MODIFIED_AFTER = 16
 | 
			
		||||
 | 
			
		||||
export const FILTER_RULE_TYPES: FilterRuleType[] = [
 | 
			
		||||
  {name: "Title contains", filtervar: "title__icontains", datatype: "string", multi: false},
 | 
			
		||||
  {name: "Content contains", filtervar: "content__icontains", datatype: "string", multi: false},
 | 
			
		||||
 | 
			
		||||
  {id: FILTER_TITLE, name: "Title contains", filtervar: "title__icontains", datatype: "string", multi: false},
 | 
			
		||||
  {id: FILTER_CONTENT, name: "Content contains", filtervar: "content__icontains", datatype: "string", multi: false},
 | 
			
		||||
  
 | 
			
		||||
  {name: "ASN is", filtervar: "archive_serial_number", datatype: "number", multi: false},
 | 
			
		||||
  {id: FILTER_ASN, name: "ASN is", filtervar: "archive_serial_number", datatype: "number", multi: false},
 | 
			
		||||
  
 | 
			
		||||
  {name: "Correspondent is", filtervar: "correspondent__id", datatype: "correspondent", multi: false},
 | 
			
		||||
  {name: "Document type is", filtervar: "document_type__id", datatype: "document_type", multi: false},
 | 
			
		||||
  {id: FILTER_CORRESPONDENT, name: "Correspondent is", filtervar: "correspondent__id", datatype: "correspondent", multi: false},
 | 
			
		||||
  {id: FILTER_DOCUMENT_TYPE, name: "Document type is", filtervar: "document_type__id", datatype: "document_type", multi: false},
 | 
			
		||||
 | 
			
		||||
  {name: "Is in Inbox", filtervar: "is_in_inbox", datatype: "boolean", multi: false},  
 | 
			
		||||
  {name: "Has tag", filtervar: "tags__id__all", datatype: "tag", multi: true},  
 | 
			
		||||
  {name: "Has any tag", filtervar: "is_tagged", datatype: "boolean", multi: false},
 | 
			
		||||
  {id: FILTER_IS_IN_INBOX, name: "Is in Inbox", filtervar: "is_in_inbox", datatype: "boolean", multi: false},  
 | 
			
		||||
  {id: FILTER_HAS_TAG, name: "Has tag", filtervar: "tags__id__all", datatype: "tag", multi: true},  
 | 
			
		||||
  {id: FILTER_HAS_ANY_TAG, name: "Has any tag", filtervar: "is_tagged", datatype: "boolean", multi: false},
 | 
			
		||||
 | 
			
		||||
  {name: "Created before", filtervar: "created__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {name: "Created after", filtervar: "created__date__gt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_CREATED_BEFORE, name: "Created before", filtervar: "created__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_CREATED_AFTER, name: "Created after", filtervar: "created__date__gt", datatype: "date", multi: false},
 | 
			
		||||
 | 
			
		||||
  {name: "Year created is", filtervar: "created__year", datatype: "number", multi: false},
 | 
			
		||||
  {name: "Month created is", filtervar: "created__month", datatype: "number", multi: false},
 | 
			
		||||
  {name: "Day created is", filtervar: "created__day", datatype: "number", multi: false},
 | 
			
		||||
  {id: FILTER_CREATED_YEAR, name: "Year created is", filtervar: "created__year", datatype: "number", multi: false},
 | 
			
		||||
  {id: FILTER_CREATED_MONTH, name: "Month created is", filtervar: "created__month", datatype: "number", multi: false},
 | 
			
		||||
  {id: FILTER_CREATED_DAY, name: "Day created is", filtervar: "created__day", datatype: "number", multi: false},
 | 
			
		||||
 | 
			
		||||
  {name: "Added before", filtervar: "added__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {name: "Added after", filtervar: "added__date__gt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_ADDED_BEFORE, name: "Added before", filtervar: "added__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_ADDED_AFTER, name: "Added after", filtervar: "added__date__gt", datatype: "date", multi: false},
 | 
			
		||||
  
 | 
			
		||||
  {name: "Modified before", filtervar: "modified__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {name: "Modified after", filtervar: "modified__date__gt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_MODIFIED_BEFORE, name: "Modified before", filtervar: "modified__date__lt", datatype: "date", multi: false},
 | 
			
		||||
  {id: FILTER_MODIFIED_AFTER, name: "Modified after", filtervar: "modified__date__gt", datatype: "date", multi: false},
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
export interface FilterRuleType {
 | 
			
		||||
  id: number
 | 
			
		||||
  name: string
 | 
			
		||||
  filtervar: string
 | 
			
		||||
  datatype: string //number, string, boolean, date
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user