mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-07 23:42:46 -06:00
DRY FTW
This commit is contained in:
@@ -62,53 +62,13 @@
|
|||||||
</pngx-page-header>
|
</pngx-page-header>
|
||||||
|
|
||||||
<ul ngbNav #nav="ngbNav" (navChange)="onNavChange($event)" [(activeId)]="activeNavID" class="nav-tabs">
|
<ul ngbNav #nav="ngbNav" (navChange)="onNavChange($event)" [(activeId)]="activeNavID" class="nav-tabs">
|
||||||
@if (canViewTags) {
|
@for (tab of visibleTabs; track tab.id) {
|
||||||
<li [ngbNavItem]="DocumentAttributesNavIDs.Tags">
|
<li [ngbNavItem]="tab.id">
|
||||||
<a ngbNavLink>
|
<a ngbNavLink>
|
||||||
<i-bs class="me-1" name="tags"></i-bs><ng-container i18n>Tags</ng-container>
|
<i-bs class="me-1" [name]="tab.icon"></i-bs>{{ tab.label }}
|
||||||
</a>
|
</a>
|
||||||
<ng-template ngbNavContent>
|
<ng-template ngbNavContent>
|
||||||
<pngx-tag-list></pngx-tag-list>
|
<ng-container [ngComponentOutlet]="tab.component"></ng-container>
|
||||||
</ng-template>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (canViewCorrespondents) {
|
|
||||||
<li [ngbNavItem]="DocumentAttributesNavIDs.Correspondents">
|
|
||||||
<a ngbNavLink>
|
|
||||||
<i-bs class="me-1" name="person"></i-bs><ng-container i18n>Correspondents</ng-container>
|
|
||||||
</a>
|
|
||||||
<ng-template ngbNavContent>
|
|
||||||
<pngx-correspondent-list></pngx-correspondent-list>
|
|
||||||
</ng-template>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (canViewDocumentTypes) {
|
|
||||||
<li [ngbNavItem]="DocumentAttributesNavIDs.DocumentTypes">
|
|
||||||
<a ngbNavLink>
|
|
||||||
<i-bs class="me-1" name="hash"></i-bs><ng-container i18n>Document types</ng-container>
|
|
||||||
</a>
|
|
||||||
<ng-template ngbNavContent>
|
|
||||||
<pngx-document-type-list></pngx-document-type-list>
|
|
||||||
</ng-template>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (canViewStoragePaths) {
|
|
||||||
<li [ngbNavItem]="DocumentAttributesNavIDs.StoragePaths">
|
|
||||||
<a ngbNavLink>
|
|
||||||
<i-bs class="me-1" name="folder"></i-bs><ng-container i18n>Storage paths</ng-container>
|
|
||||||
</a>
|
|
||||||
<ng-template ngbNavContent>
|
|
||||||
<pngx-storage-path-list></pngx-storage-path-list>
|
|
||||||
</ng-template>
|
|
||||||
</li>
|
|
||||||
}
|
|
||||||
@if (canViewCustomFields) {
|
|
||||||
<li [ngbNavItem]="DocumentAttributesNavIDs.CustomFields">
|
|
||||||
<a ngbNavLink>
|
|
||||||
<i-bs class="me-1" name="ui-radios"></i-bs><ng-container i18n>Custom fields</ng-container>
|
|
||||||
</a>
|
|
||||||
<ng-template ngbNavContent>
|
|
||||||
<pngx-custom-fields></pngx-custom-fields>
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</li>
|
</li>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,12 @@
|
|||||||
import { Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core'
|
import { NgComponentOutlet } from '@angular/common'
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
inject,
|
||||||
|
OnDestroy,
|
||||||
|
OnInit,
|
||||||
|
Type,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core'
|
||||||
import { ActivatedRoute, Router } from '@angular/router'
|
import { ActivatedRoute, Router } from '@angular/router'
|
||||||
import {
|
import {
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
@@ -30,6 +38,18 @@ enum DocumentAttributesNavIDs {
|
|||||||
CustomFields = 5,
|
CustomFields = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DocumentAttributesTabKind = 'bulk' | 'customFields'
|
||||||
|
|
||||||
|
interface DocumentAttributesTab {
|
||||||
|
id: DocumentAttributesNavIDs
|
||||||
|
section: string
|
||||||
|
label: string
|
||||||
|
icon: string
|
||||||
|
permissionType: PermissionType
|
||||||
|
kind: DocumentAttributesTabKind
|
||||||
|
component: Type<any>
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'pngx-document-attributes',
|
selector: 'pngx-document-attributes',
|
||||||
templateUrl: './document-attributes.component.html',
|
templateUrl: './document-attributes.component.html',
|
||||||
@@ -38,14 +58,10 @@ enum DocumentAttributesNavIDs {
|
|||||||
PageHeaderComponent,
|
PageHeaderComponent,
|
||||||
NgbNavModule,
|
NgbNavModule,
|
||||||
NgbDropdownModule,
|
NgbDropdownModule,
|
||||||
|
NgComponentOutlet,
|
||||||
NgxBootstrapIconsModule,
|
NgxBootstrapIconsModule,
|
||||||
IfPermissionsDirective,
|
IfPermissionsDirective,
|
||||||
ClearableBadgeComponent,
|
ClearableBadgeComponent,
|
||||||
TagListComponent,
|
|
||||||
CorrespondentListComponent,
|
|
||||||
DocumentTypeListComponent,
|
|
||||||
StoragePathListComponent,
|
|
||||||
CustomFieldsComponent,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
||||||
@@ -54,10 +70,57 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
|||||||
private readonly router = inject(Router)
|
private readonly router = inject(Router)
|
||||||
private readonly unsubscribeNotifier = new Subject<void>()
|
private readonly unsubscribeNotifier = new Subject<void>()
|
||||||
|
|
||||||
protected readonly DocumentAttributesNavIDs = DocumentAttributesNavIDs
|
|
||||||
protected readonly PermissionAction = PermissionAction
|
protected readonly PermissionAction = PermissionAction
|
||||||
protected readonly PermissionType = PermissionType
|
protected readonly PermissionType = PermissionType
|
||||||
|
|
||||||
|
readonly tabs: DocumentAttributesTab[] = [
|
||||||
|
{
|
||||||
|
id: DocumentAttributesNavIDs.Tags,
|
||||||
|
section: 'tags',
|
||||||
|
label: $localize`Tags`,
|
||||||
|
icon: 'tags',
|
||||||
|
permissionType: PermissionType.Tag,
|
||||||
|
kind: 'bulk',
|
||||||
|
component: TagListComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: DocumentAttributesNavIDs.Correspondents,
|
||||||
|
section: 'correspondents',
|
||||||
|
label: $localize`Correspondents`,
|
||||||
|
icon: 'person',
|
||||||
|
permissionType: PermissionType.Correspondent,
|
||||||
|
kind: 'bulk',
|
||||||
|
component: CorrespondentListComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: DocumentAttributesNavIDs.DocumentTypes,
|
||||||
|
section: 'documenttypes',
|
||||||
|
label: $localize`Document types`,
|
||||||
|
icon: 'hash',
|
||||||
|
permissionType: PermissionType.DocumentType,
|
||||||
|
kind: 'bulk',
|
||||||
|
component: DocumentTypeListComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: DocumentAttributesNavIDs.StoragePaths,
|
||||||
|
section: 'storagepaths',
|
||||||
|
label: $localize`Storage paths`,
|
||||||
|
icon: 'folder',
|
||||||
|
permissionType: PermissionType.StoragePath,
|
||||||
|
kind: 'bulk',
|
||||||
|
component: StoragePathListComponent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: DocumentAttributesNavIDs.CustomFields,
|
||||||
|
section: 'customfields',
|
||||||
|
label: $localize`Custom fields`,
|
||||||
|
icon: 'ui-radios',
|
||||||
|
permissionType: PermissionType.CustomField,
|
||||||
|
kind: 'customFields',
|
||||||
|
component: CustomFieldsComponent,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
@ViewChild(TagListComponent) private tagList?: TagListComponent
|
@ViewChild(TagListComponent) private tagList?: TagListComponent
|
||||||
@ViewChild(CorrespondentListComponent)
|
@ViewChild(CorrespondentListComponent)
|
||||||
private correspondentList?: CorrespondentListComponent
|
private correspondentList?: CorrespondentListComponent
|
||||||
@@ -70,6 +133,19 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
activeNavID: number = null
|
activeNavID: number = null
|
||||||
|
|
||||||
|
get visibleTabs(): DocumentAttributesTab[] {
|
||||||
|
return this.tabs.filter((tab) =>
|
||||||
|
this.permissionsService.currentUserCan(
|
||||||
|
PermissionAction.View,
|
||||||
|
tab.permissionType
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeTab(): DocumentAttributesTab | null {
|
||||||
|
return this.visibleTabs.find((t) => t.id === this.activeNavID) ?? null
|
||||||
|
}
|
||||||
|
|
||||||
get activeBulkList(): ManagementListComponent<any> | null {
|
get activeBulkList(): ManagementListComponent<any> | null {
|
||||||
switch (this.activeNavID) {
|
switch (this.activeNavID) {
|
||||||
case DocumentAttributesNavIDs.Tags:
|
case DocumentAttributesNavIDs.Tags:
|
||||||
@@ -92,20 +168,7 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get activeTabLabel(): string {
|
get activeTabLabel(): string {
|
||||||
switch (this.activeNavID) {
|
return this.activeTab?.label ?? ''
|
||||||
case DocumentAttributesNavIDs.Tags:
|
|
||||||
return $localize`Tags`
|
|
||||||
case DocumentAttributesNavIDs.Correspondents:
|
|
||||||
return $localize`Correspondents`
|
|
||||||
case DocumentAttributesNavIDs.DocumentTypes:
|
|
||||||
return $localize`Document types`
|
|
||||||
case DocumentAttributesNavIDs.StoragePaths:
|
|
||||||
return $localize`Storage paths`
|
|
||||||
case DocumentAttributesNavIDs.CustomFields:
|
|
||||||
return $localize`Custom fields`
|
|
||||||
default:
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get activeHeaderLoading(): boolean {
|
get activeHeaderLoading(): boolean {
|
||||||
@@ -114,41 +177,6 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get canViewTags(): boolean {
|
|
||||||
return this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.Tag
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get canViewCorrespondents(): boolean {
|
|
||||||
return this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.Correspondent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get canViewDocumentTypes(): boolean {
|
|
||||||
return this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.DocumentType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get canViewStoragePaths(): boolean {
|
|
||||||
return this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.StoragePath
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
get canViewCustomFields(): boolean {
|
|
||||||
return this.permissionsService.currentUserCan(
|
|
||||||
PermissionAction.View,
|
|
||||||
PermissionType.CustomField
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.activatedRoute.paramMap
|
this.activatedRoute.paramMap
|
||||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||||
@@ -189,49 +217,19 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getDefaultNavID(): DocumentAttributesNavIDs | null {
|
private getDefaultNavID(): DocumentAttributesNavIDs | null {
|
||||||
if (this.canViewTags) return DocumentAttributesNavIDs.Tags
|
return this.visibleTabs[0]?.id ?? null
|
||||||
if (this.canViewCorrespondents)
|
|
||||||
return DocumentAttributesNavIDs.Correspondents
|
|
||||||
if (this.canViewDocumentTypes) return DocumentAttributesNavIDs.DocumentTypes
|
|
||||||
if (this.canViewStoragePaths) return DocumentAttributesNavIDs.StoragePaths
|
|
||||||
if (this.canViewCustomFields) return DocumentAttributesNavIDs.CustomFields
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNavIDForSection(section: string): DocumentAttributesNavIDs | null {
|
private getNavIDForSection(section: string): DocumentAttributesNavIDs | null {
|
||||||
if (!section) return null
|
const sectionKey = section?.toLowerCase()
|
||||||
const navIDKey: string = Object.keys(DocumentAttributesNavIDs).find(
|
if (!sectionKey) return null
|
||||||
(navID) => navID.toLowerCase() === section.toLowerCase()
|
|
||||||
)
|
|
||||||
if (!navIDKey) return null
|
|
||||||
|
|
||||||
const navID = DocumentAttributesNavIDs[navIDKey]
|
const tab = this.visibleTabs.find((t) => t.section === sectionKey)
|
||||||
if (!this.isNavIDAllowed(navID)) return null
|
return tab?.id ?? null
|
||||||
return navID
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSectionForNavID(navID: number): string | null {
|
private getSectionForNavID(navID: number): string | null {
|
||||||
if (!this.isNavIDAllowed(navID)) return null
|
const tab = this.visibleTabs.find((t) => t.id === navID)
|
||||||
const [foundNavIDKey] = Object.entries(DocumentAttributesNavIDs).find(
|
return tab?.section ?? null
|
||||||
([, navIDValue]) => navIDValue === navID
|
|
||||||
)
|
|
||||||
return foundNavIDKey?.toLowerCase() ?? null
|
|
||||||
}
|
|
||||||
|
|
||||||
private isNavIDAllowed(navID: number): boolean {
|
|
||||||
switch (navID) {
|
|
||||||
case DocumentAttributesNavIDs.Tags:
|
|
||||||
return this.canViewTags
|
|
||||||
case DocumentAttributesNavIDs.Correspondents:
|
|
||||||
return this.canViewCorrespondents
|
|
||||||
case DocumentAttributesNavIDs.DocumentTypes:
|
|
||||||
return this.canViewDocumentTypes
|
|
||||||
case DocumentAttributesNavIDs.StoragePaths:
|
|
||||||
return this.canViewStoragePaths
|
|
||||||
case DocumentAttributesNavIDs.CustomFields:
|
|
||||||
return this.canViewCustomFields
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user