Feature: customizable fields display for documents, saved views & dashboard widgets (#6439)

This commit is contained in:
shamoon
2024-04-26 06:41:12 -07:00
committed by GitHub
parent 7a0334f353
commit bd4476d484
50 changed files with 2929 additions and 1018 deletions

View File

@@ -6,23 +6,38 @@ import {
QueryList,
ViewChildren,
} from '@angular/core'
import { Params, Router } from '@angular/router'
import { Router } from '@angular/router'
import { Subject, takeUntil } from 'rxjs'
import { Document } from 'src/app/data/document'
import {
DEFAULT_DASHBOARD_DISPLAY_FIELDS,
DEFAULT_DASHBOARD_VIEW_PAGE_SIZE,
DEFAULT_DISPLAY_FIELDS,
DisplayField,
DisplayMode,
Document,
} from 'src/app/data/document'
import { SavedView } from 'src/app/data/saved-view'
import { ConsumerStatusService } from 'src/app/services/consumer-status.service'
import { DocumentService } from 'src/app/services/rest/document.service'
import { Tag } from 'src/app/data/tag'
import {
FILTER_CORRESPONDENT,
FILTER_DOCUMENT_TYPE,
FILTER_FULLTEXT_MORELIKE,
FILTER_HAS_TAGS_ALL,
FILTER_STORAGE_PATH,
} from 'src/app/data/filter-rule-type'
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
import { queryParamsFromFilterRules } from 'src/app/utils/query-params'
import { PermissionsService } from 'src/app/services/permissions.service'
import {
PermissionAction,
PermissionType,
PermissionsService,
} from 'src/app/services/permissions.service'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
import { SettingsService } from 'src/app/services/settings.service'
@Component({
selector: 'pngx-saved-view-widget',
@@ -33,8 +48,14 @@ export class SavedViewWidgetComponent
extends ComponentWithPermissions
implements OnInit, OnDestroy
{
public DisplayMode = DisplayMode
public DisplayField = DisplayField
public CustomFieldDataType = CustomFieldDataType
loading: boolean = true
private customFields: CustomField[] = []
constructor(
private documentService: DocumentService,
private router: Router,
@@ -42,7 +63,9 @@ export class SavedViewWidgetComponent
private consumerStatusService: ConsumerStatusService,
public openDocumentsService: OpenDocumentsService,
public documentListViewService: DocumentListViewService,
public permissionsService: PermissionsService
public permissionsService: PermissionsService,
private settingsService: SettingsService,
private customFieldService: CustomFieldsService
) {
super()
}
@@ -60,14 +83,44 @@ export class SavedViewWidgetComponent
mouseOnPreview = false
popoverHidden = true
displayMode: DisplayMode
displayFields: DisplayField[] = DEFAULT_DASHBOARD_DISPLAY_FIELDS
ngOnInit(): void {
this.reload()
this.displayMode = this.savedView.display_mode ?? DisplayMode.TABLE
this.consumerStatusService
.onDocumentConsumptionFinished()
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => {
this.reload()
})
if (
this.permissionsService.currentUserCan(
PermissionAction.View,
PermissionType.CustomField
)
) {
this.customFieldService
.listAll()
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe((customFields) => {
this.customFields = customFields.results
})
}
if (this.savedView.display_fields) {
this.displayFields = this.savedView.display_fields
}
// filter by perms etc
this.displayFields = this.displayFields.filter(
(field) =>
this.settingsService.allDisplayFields.find((f) => f.id === field) !==
undefined
)
}
ngOnDestroy(): void {
@@ -80,7 +133,7 @@ export class SavedViewWidgetComponent
this.documentService
.listFiltered(
1,
10,
this.savedView.page_size ?? DEFAULT_DASHBOARD_VIEW_PAGE_SIZE,
this.savedView.sort_field,
this.savedView.sort_reverse,
this.savedView.filter_rules,
@@ -103,15 +156,52 @@ export class SavedViewWidgetComponent
}
}
clickTag(tag: Tag, event: MouseEvent) {
event.preventDefault()
event.stopImmediatePropagation()
clickTag(tagID: number, event: MouseEvent = null) {
event?.preventDefault()
event?.stopImmediatePropagation()
this.list.quickFilter([
{ rule_type: FILTER_HAS_TAGS_ALL, value: tag.id.toString() },
{ rule_type: FILTER_HAS_TAGS_ALL, value: tagID.toString() },
])
}
clickCorrespondent(correspondentId: number, event: MouseEvent = null) {
event?.preventDefault()
event?.stopImmediatePropagation()
this.list.quickFilter([
{ rule_type: FILTER_CORRESPONDENT, value: correspondentId.toString() },
])
}
clickDocType(docTypeId: number, event: MouseEvent = null) {
event?.preventDefault()
event?.stopImmediatePropagation()
this.list.quickFilter([
{ rule_type: FILTER_DOCUMENT_TYPE, value: docTypeId.toString() },
])
}
clickStoragePath(storagePathId: number, event: MouseEvent = null) {
event?.preventDefault()
event?.stopImmediatePropagation()
this.list.quickFilter([
{ rule_type: FILTER_STORAGE_PATH, value: storagePathId.toString() },
])
}
clickMoreLike(documentID: number) {
this.list.quickFilter([
{ rule_type: FILTER_FULLTEXT_MORELIKE, value: documentID.toString() },
])
}
openDocumentDetail(document: Document) {
this.router.navigate(['documents', document.id])
}
getPreviewUrl(document: Document): string {
return this.documentService.getPreviewUrl(document.id)
}
@@ -161,14 +251,11 @@ export class SavedViewWidgetComponent
}, 300)
}
getCorrespondentQueryParams(correspondentId: number): Params {
return correspondentId !== undefined
? queryParamsFromFilterRules([
{
rule_type: FILTER_CORRESPONDENT,
value: correspondentId.toString(),
},
])
: null
public getColumnTitle(field: DisplayField): string {
if (field.startsWith(DisplayField.CUSTOM_FIELD)) {
const id = field.split('_')[2]
return this.customFields.find((f) => f.id === parseInt(id))?.name
}
return DEFAULT_DISPLAY_FIELDS.find((f) => f.id === field)?.name
}
}