mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-13 10:03:49 -05:00
151 lines
4.4 KiB
TypeScript
151 lines
4.4 KiB
TypeScript
import { DecimalPipe } from '@angular/common'
|
|
import { HttpClient } from '@angular/common/http'
|
|
import { Component, OnDestroy, OnInit } from '@angular/core'
|
|
import { RouterModule } from '@angular/router'
|
|
import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'
|
|
import * as mimeTypeNames from 'mime-names'
|
|
import { first, Subject, Subscription, takeUntil } from 'rxjs'
|
|
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
|
|
import {
|
|
FILTER_HAS_TAGS_ANY,
|
|
FILTER_MIME_TYPE,
|
|
} from 'src/app/data/filter-rule-type'
|
|
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
|
|
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
|
import { WebsocketStatusService } from 'src/app/services/websocket-status.service'
|
|
import { environment } from 'src/environments/environment'
|
|
import { WidgetFrameComponent } from '../widget-frame/widget-frame.component'
|
|
|
|
export interface Statistics {
|
|
documents_total?: number
|
|
documents_inbox?: number
|
|
inbox_tags?: number[]
|
|
document_file_type_counts?: DocumentFileType[]
|
|
character_count?: number
|
|
tag_count?: number
|
|
correspondent_count?: number
|
|
document_type_count?: number
|
|
storage_path_count?: number
|
|
current_asn?: number
|
|
}
|
|
|
|
interface DocumentFileType {
|
|
mime_type: string
|
|
mime_type_count: number
|
|
is_other?: boolean
|
|
}
|
|
|
|
@Component({
|
|
selector: 'pngx-statistics-widget',
|
|
templateUrl: './statistics-widget.component.html',
|
|
styleUrls: ['./statistics-widget.component.scss'],
|
|
imports: [
|
|
WidgetFrameComponent,
|
|
IfPermissionsDirective,
|
|
NgbPopoverModule,
|
|
DecimalPipe,
|
|
RouterModule,
|
|
],
|
|
})
|
|
export class StatisticsWidgetComponent
|
|
extends ComponentWithPermissions
|
|
implements OnInit, OnDestroy
|
|
{
|
|
loading: boolean = false
|
|
|
|
constructor(
|
|
private http: HttpClient,
|
|
private websocketConnectionService: WebsocketStatusService,
|
|
private documentListViewService: DocumentListViewService
|
|
) {
|
|
super()
|
|
}
|
|
|
|
statistics: Statistics = {}
|
|
|
|
subscription: Subscription
|
|
private unsubscribeNotifer: Subject<any> = new Subject()
|
|
|
|
reload() {
|
|
if (this.loading) return
|
|
this.loading = true
|
|
this.http
|
|
.get<Statistics>(`${environment.apiBaseUrl}statistics/`)
|
|
.pipe(takeUntil(this.unsubscribeNotifer), first())
|
|
.subscribe((statistics) => {
|
|
this.loading = false
|
|
const fileTypeMax = 5
|
|
if (statistics.document_file_type_counts?.length > fileTypeMax) {
|
|
const others = statistics.document_file_type_counts.slice(fileTypeMax)
|
|
statistics.document_file_type_counts =
|
|
statistics.document_file_type_counts.slice(0, fileTypeMax)
|
|
statistics.document_file_type_counts.push({
|
|
mime_type: $localize`Other`,
|
|
is_other: true,
|
|
mime_type_count: others.reduce(
|
|
(currentValue, documentFileType) =>
|
|
documentFileType.mime_type_count + currentValue,
|
|
0
|
|
),
|
|
})
|
|
}
|
|
this.statistics = statistics
|
|
})
|
|
}
|
|
|
|
getFileTypeExtension(filetype: DocumentFileType): string {
|
|
return (
|
|
mimeTypeNames[filetype.mime_type]?.extensions[0]?.toUpperCase() ??
|
|
filetype.mime_type
|
|
)
|
|
}
|
|
|
|
getFileTypeName(filetype: DocumentFileType): string {
|
|
return mimeTypeNames[filetype.mime_type]?.name ?? filetype.mime_type
|
|
}
|
|
|
|
getFileTypePercent(filetype: DocumentFileType): number {
|
|
return (filetype.mime_type_count / this.statistics?.documents_total) * 100
|
|
}
|
|
|
|
getItemOpacity(i: number): number {
|
|
return 1 - i / this.statistics?.document_file_type_counts.length
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.reload()
|
|
this.subscription = this.websocketConnectionService
|
|
.onDocumentConsumptionFinished()
|
|
.subscribe(() => {
|
|
this.reload()
|
|
})
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
this.subscription.unsubscribe()
|
|
this.unsubscribeNotifer.next(true)
|
|
this.unsubscribeNotifer.complete()
|
|
}
|
|
|
|
goToInbox() {
|
|
this.documentListViewService.quickFilter([
|
|
{
|
|
rule_type: FILTER_HAS_TAGS_ANY,
|
|
value: this.statistics.inbox_tags
|
|
.map((tagID) => tagID.toString())
|
|
.join(','),
|
|
},
|
|
])
|
|
}
|
|
|
|
filterByFileType(filetype: DocumentFileType) {
|
|
if (filetype.is_other) return
|
|
this.documentListViewService.quickFilter([
|
|
{
|
|
rule_type: FILTER_MIME_TYPE,
|
|
value: filetype.mime_type,
|
|
},
|
|
])
|
|
}
|
|
}
|