DocumentAttributesTab --> Section, move header stuff in there too

This commit is contained in:
shamoon
2026-02-06 21:56:24 -08:00
parent 8ef048e3ba
commit 793fdeb0d2
2 changed files with 68 additions and 71 deletions

View File

@@ -6,19 +6,19 @@
[subTitle]="activeTabLabel" [subTitle]="activeTabLabel"
[loading]="activeHeaderLoading" [loading]="activeHeaderLoading"
> >
@if (activeBulkList) { @if (activeAttributeList) {
<div ngbDropdown class="btn-group flex-fill d-sm-none"> <div ngbDropdown class="btn-group flex-fill d-sm-none">
<button class="btn btn-sm btn-outline-primary" id="dropdownSelectMobile" ngbDropdownToggle> <button class="btn btn-sm btn-outline-primary" id="dropdownSelectMobile" ngbDropdownToggle>
<i-bs name="text-indent-left"></i-bs> <i-bs name="text-indent-left"></i-bs>
<div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Select</ng-container></div> <div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Select</ng-container></div>
@if (activeBulkList.selectedObjects.size > 0) { @if (activeAttributeList.selectedObjects.size > 0) {
<pngx-clearable-badge [selected]="activeBulkList.selectedObjects.size > 0" [number]="activeBulkList.selectedObjects.size" (cleared)="activeBulkList.selectNone()"></pngx-clearable-badge><span class="visually-hidden">selected</span> <pngx-clearable-badge [selected]="activeAttributeList.selectedObjects.size > 0" [number]="activeAttributeList.selectedObjects.size" (cleared)="activeAttributeList.selectNone()"></pngx-clearable-badge><span class="visually-hidden">selected</span>
} }
</button> </button>
<div ngbDropdownMenu aria-labelledby="dropdownSelectMobile" class="shadow"> <div ngbDropdownMenu aria-labelledby="dropdownSelectMobile" class="shadow">
<button ngbDropdownItem (click)="activeBulkList.selectNone()" i18n>Select none</button> <button ngbDropdownItem (click)="activeAttributeList.selectNone()" i18n>Select none</button>
<button ngbDropdownItem (click)="activeBulkList.selectPage(true)" i18n>Select page</button> <button ngbDropdownItem (click)="activeAttributeList.selectPage(true)" i18n>Select page</button>
<button ngbDropdownItem (click)="activeBulkList.selectAll()" i18n>Select all</button> <button ngbDropdownItem (click)="activeAttributeList.selectAll()" i18n>Select all</button>
</div> </div>
</div> </div>
@@ -27,30 +27,30 @@
<span class="input-group-text border-0" i18n>Select:</span> <span class="input-group-text border-0" i18n>Select:</span>
</div> </div>
<div class="btn-group btn-group-sm flex-nowrap"> <div class="btn-group btn-group-sm flex-nowrap">
@if (activeBulkList.selectedObjects.size > 0) { @if (activeAttributeList.selectedObjects.size > 0) {
<button class="btn btn-sm btn-outline-secondary" (click)="activeBulkList.selectNone()"> <button class="btn btn-sm btn-outline-secondary" (click)="activeAttributeList.selectNone()">
<i-bs name="slash-circle"></i-bs>&nbsp;<ng-container i18n>None</ng-container> <i-bs name="slash-circle"></i-bs>&nbsp;<ng-container i18n>None</ng-container>
</button> </button>
} }
<button class="btn btn-sm btn-outline-primary" (click)="activeBulkList.selectPage(true)"> <button class="btn btn-sm btn-outline-primary" (click)="activeAttributeList.selectPage(true)">
<i-bs name="file-earmark-check"></i-bs>&nbsp;<ng-container i18n>Page</ng-container> <i-bs name="file-earmark-check"></i-bs>&nbsp;<ng-container i18n>Page</ng-container>
</button> </button>
<button class="btn btn-sm btn-outline-primary" (click)="activeBulkList.selectAll()"> <button class="btn btn-sm btn-outline-primary" (click)="activeAttributeList.selectAll()">
<i-bs name="check-all"></i-bs>&nbsp;<ng-container i18n>All</ng-container> <i-bs name="check-all"></i-bs>&nbsp;<ng-container i18n>All</ng-container>
</button> </button>
</div> </div>
</div> </div>
<button type="button" class="btn btn-sm btn-outline-primary" (click)="activeBulkList.setPermissions()" <button type="button" class="btn btn-sm btn-outline-primary" (click)="activeAttributeList.setPermissions()"
[disabled]="!activeBulkList.userCanBulkEdit(PermissionAction.Change) || activeBulkList.selectedObjects.size === 0"> [disabled]="!activeAttributeList.userCanBulkEdit(PermissionAction.Change) || activeAttributeList.selectedObjects.size === 0">
<i-bs name="person-fill-lock"></i-bs>&nbsp;<ng-container i18n>Permissions</ng-container> <i-bs name="person-fill-lock"></i-bs>&nbsp;<ng-container i18n>Permissions</ng-container>
</button> </button>
<button type="button" class="btn btn-sm btn-outline-danger" (click)="activeBulkList.delete()" <button type="button" class="btn btn-sm btn-outline-danger" (click)="activeAttributeList.delete()"
[disabled]="!activeBulkList.userCanBulkEdit(PermissionAction.Delete) || activeBulkList.selectedObjects.size === 0"> [disabled]="!activeAttributeList.userCanBulkEdit(PermissionAction.Delete) || activeAttributeList.selectedObjects.size === 0">
<i-bs name="trash"></i-bs>&nbsp;<ng-container i18n>Delete</ng-container> <i-bs name="trash"></i-bs>&nbsp;<ng-container i18n>Delete</ng-container>
</button> </button>
<button type="button" class="btn btn-sm btn-outline-primary ms-md-5" (click)="activeBulkList.openCreateDialog()" <button type="button" class="btn btn-sm btn-outline-primary ms-md-5" (click)="activeAttributeList.openCreateDialog()"
*pngxIfPermissions="{ action: PermissionAction.Add, type: activeBulkList.permissionType }"> *pngxIfPermissions="{ action: PermissionAction.Add, type: activeAttributeList.permissionType }">
<i-bs name="plus-circle"></i-bs>&nbsp;<ng-container i18n>Create</ng-container> <i-bs name="plus-circle"></i-bs>&nbsp;<ng-container i18n>Create</ng-container>
</button> </button>
} @else if (activeCustomFields) { } @else if (activeCustomFields) {
@@ -62,13 +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">
@for (tab of visibleTabs; track tab.id) { @for (section of visibleSections; track section.id) {
<li [ngbNavItem]="tab.id"> <li [ngbNavItem]="section.id">
<a ngbNavLink> <a ngbNavLink>
<i-bs class="me-1" [name]="tab.icon"></i-bs>{{ tab.label }} <i-bs class="me-2" [name]="section.icon"></i-bs>{{ section.label }}
</a> </a>
<ng-template ngbNavContent> <ng-template ngbNavContent>
<ng-container [ngComponentOutlet]="tab.component"></ng-container> <ng-container [ngComponentOutlet]="section.component"></ng-container>
</ng-template> </ng-template>
</li> </li>
} }

View File

@@ -4,8 +4,10 @@ import {
inject, inject,
OnDestroy, OnDestroy,
OnInit, OnInit,
QueryList,
Type, Type,
ViewChild, ViewChild,
ViewChildren,
} from '@angular/core' } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router' import { ActivatedRoute, Router } from '@angular/router'
import { import {
@@ -38,15 +40,15 @@ enum DocumentAttributesNavIDs {
CustomFields = 5, CustomFields = 5,
} }
type DocumentAttributesTabKind = 'bulk' | 'customFields' type DocumentAttributesSectionKind = 'attributeList' | 'customFields'
interface DocumentAttributesTab { interface DocumentAttributesSection {
id: DocumentAttributesNavIDs id: DocumentAttributesNavIDs
section: string path: string
label: string label: string
icon: string icon: string
permissionType: PermissionType permissionType: PermissionType
kind: DocumentAttributesTabKind kind: DocumentAttributesSectionKind
component: Type<any> component: Type<any>
} }
@@ -73,46 +75,46 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
protected readonly PermissionAction = PermissionAction protected readonly PermissionAction = PermissionAction
protected readonly PermissionType = PermissionType protected readonly PermissionType = PermissionType
readonly tabs: DocumentAttributesTab[] = [ readonly sections: DocumentAttributesSection[] = [
{ {
id: DocumentAttributesNavIDs.Tags, id: DocumentAttributesNavIDs.Tags,
section: 'tags', path: 'tags',
label: $localize`Tags`, label: $localize`Tags`,
icon: 'tags', icon: 'tags',
permissionType: PermissionType.Tag, permissionType: PermissionType.Tag,
kind: 'bulk', kind: 'attributeList',
component: TagListComponent, component: TagListComponent,
}, },
{ {
id: DocumentAttributesNavIDs.Correspondents, id: DocumentAttributesNavIDs.Correspondents,
section: 'correspondents', path: 'correspondents',
label: $localize`Correspondents`, label: $localize`Correspondents`,
icon: 'person', icon: 'person',
permissionType: PermissionType.Correspondent, permissionType: PermissionType.Correspondent,
kind: 'bulk', kind: 'attributeList',
component: CorrespondentListComponent, component: CorrespondentListComponent,
}, },
{ {
id: DocumentAttributesNavIDs.DocumentTypes, id: DocumentAttributesNavIDs.DocumentTypes,
section: 'documenttypes', path: 'documenttypes',
label: $localize`Document types`, label: $localize`Document types`,
icon: 'hash', icon: 'hash',
permissionType: PermissionType.DocumentType, permissionType: PermissionType.DocumentType,
kind: 'bulk', kind: 'attributeList',
component: DocumentTypeListComponent, component: DocumentTypeListComponent,
}, },
{ {
id: DocumentAttributesNavIDs.StoragePaths, id: DocumentAttributesNavIDs.StoragePaths,
section: 'storagepaths', path: 'storagepaths',
label: $localize`Storage paths`, label: $localize`Storage paths`,
icon: 'folder', icon: 'folder',
permissionType: PermissionType.StoragePath, permissionType: PermissionType.StoragePath,
kind: 'bulk', kind: 'attributeList',
component: StoragePathListComponent, component: StoragePathListComponent,
}, },
{ {
id: DocumentAttributesNavIDs.CustomFields, id: DocumentAttributesNavIDs.CustomFields,
section: 'customfields', path: 'customfields',
label: $localize`Custom fields`, label: $localize`Custom fields`,
icon: 'ui-radios', icon: 'ui-radios',
permissionType: PermissionType.CustomField, permissionType: PermissionType.CustomField,
@@ -121,59 +123,54 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
}, },
] ]
@ViewChild(TagListComponent) private tagList?: TagListComponent @ViewChildren(ManagementListComponent)
@ViewChild(CorrespondentListComponent) private attributeLists?: QueryList<ManagementListComponent<any>>
private correspondentList?: CorrespondentListComponent
@ViewChild(DocumentTypeListComponent) @ViewChild(CustomFieldsComponent) private customFields?: CustomFieldsComponent
private documentTypeList?: DocumentTypeListComponent
@ViewChild(StoragePathListComponent)
private storagePathList?: StoragePathListComponent
@ViewChild(CustomFieldsComponent)
private customFields?: CustomFieldsComponent
activeNavID: number = null activeNavID: number = null
get visibleTabs(): DocumentAttributesTab[] { get visibleSections(): DocumentAttributesSection[] {
return this.tabs.filter((tab) => return this.sections.filter((section) =>
this.permissionsService.currentUserCan( this.permissionsService.currentUserCan(
PermissionAction.View, PermissionAction.View,
tab.permissionType section.permissionType
) )
) )
} }
get activeTab(): DocumentAttributesTab | null { get activeSection(): DocumentAttributesSection | null {
return this.visibleTabs.find((t) => t.id === this.activeNavID) ?? null return (
this.visibleSections.find((section) => section.id === this.activeNavID) ??
null
)
} }
get activeBulkList(): ManagementListComponent<any> | null { get activeAttributeList(): ManagementListComponent<any> | null {
switch (this.activeNavID) { if (this.activeSection?.kind !== 'attributeList') return null
case DocumentAttributesNavIDs.Tags: const permissionType = this.activeSection.permissionType
return this.tagList ?? null return (
case DocumentAttributesNavIDs.Correspondents: this.attributeLists?.find(
return this.correspondentList ?? null (list) => list.permissionType === permissionType
case DocumentAttributesNavIDs.DocumentTypes: ) ?? null
return this.documentTypeList ?? null )
case DocumentAttributesNavIDs.StoragePaths:
return this.storagePathList ?? null
default:
return null
}
} }
get activeCustomFields(): CustomFieldsComponent | null { get activeCustomFields(): CustomFieldsComponent | null {
return this.activeNavID === DocumentAttributesNavIDs.CustomFields return this.activeSection?.kind === 'customFields'
? (this.customFields ?? null) ? (this.customFields ?? null)
: null : null
} }
get activeTabLabel(): string { get activeTabLabel(): string {
return this.activeTab?.label ?? '' return this.activeSection?.label ?? ''
} }
get activeHeaderLoading(): boolean { get activeHeaderLoading(): boolean {
return ( return (
this.activeBulkList?.loading ?? this.activeCustomFields?.loading ?? false this.activeAttributeList?.loading ??
this.activeCustomFields?.loading ??
false
) )
} }
@@ -217,19 +214,19 @@ export class DocumentAttributesComponent implements OnInit, OnDestroy {
} }
private getDefaultNavID(): DocumentAttributesNavIDs | null { private getDefaultNavID(): DocumentAttributesNavIDs | null {
return this.visibleTabs[0]?.id ?? null return this.visibleSections[0]?.id ?? null
} }
private getNavIDForSection(section: string): DocumentAttributesNavIDs | null { private getNavIDForSection(section: string): DocumentAttributesNavIDs | null {
const sectionKey = section?.toLowerCase() const path = section?.toLowerCase()
if (!sectionKey) return null if (!path) return null
const tab = this.visibleTabs.find((t) => t.section === sectionKey) const found = this.visibleSections.find((s) => s.path === path)
return tab?.id ?? null return found?.id ?? null
} }
private getSectionForNavID(navID: number): string | null { private getSectionForNavID(navID: number): string | null {
const tab = this.visibleTabs.find((t) => t.id === navID) const section = this.visibleSections.find((s) => s.id === navID)
return tab?.section ?? null return section?.path ?? null
} }
} }