Working frontend custom field editing

This commit is contained in:
shamoon
2023-10-31 11:30:03 -07:00
parent 17abd90c46
commit 44728aa048
7 changed files with 34 additions and 21 deletions

View File

@@ -92,7 +92,7 @@ describe('CustomFieldsDropdownComponent', () => {
CustomFieldsDropdownComponent.prototype as any, CustomFieldsDropdownComponent.prototype as any,
'updateUnusedFields' 'updateUnusedFields'
) )
component.existingFields = [fields[1]] component.existingFields = [{ field: fields[1] } as any]
component.onOpenClose() component.onOpenClose()
expect(updateSpy).toHaveBeenCalled() expect(updateSpy).toHaveBeenCalled()
expect(component.unusedFields).toEqual([fields[0]]) expect(component.unusedFields).toEqual([fields[0]])

View File

@@ -4,11 +4,11 @@ import {
Input, Input,
OnDestroy, OnDestroy,
Output, Output,
SimpleChanges,
} from '@angular/core' } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap' import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { Subject, first, takeUntil } from 'rxjs' import { Subject, first, takeUntil } from 'rxjs'
import { PaperlessCustomField } from 'src/app/data/paperless-custom-field' import { PaperlessCustomField } from 'src/app/data/paperless-custom-field'
import { PaperlessCustomFieldInstance } from 'src/app/data/paperless-custom-field-instance'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service' import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { ToastService } from 'src/app/services/toast.service' import { ToastService } from 'src/app/services/toast.service'
import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component' import { CustomFieldEditDialogComponent } from '../edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component'
@@ -26,7 +26,7 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
disabled: boolean = false disabled: boolean = false
@Input() @Input()
existingFields: PaperlessCustomField[] = [] existingFields: PaperlessCustomFieldInstance[] = []
@Output() @Output()
added = new EventEmitter() added = new EventEmitter()
@@ -69,7 +69,7 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
private updateUnusedFields() { private updateUnusedFields() {
this.unusedFields = this.customFields.filter( this.unusedFields = this.customFields.filter(
(f) => !this.existingFields.find((e) => e.id === f.id) (f) => !this.existingFields.find((e) => e.field.id === f.id)
) )
} }

View File

@@ -1,7 +1,7 @@
<div class="mb-3"> <div class="mb-3">
<div class="row"> <div class="row">
<div [class.col-md-3]="horizontal"> <div class="d-flex align-items-center" [class.col-md-3]="horizontal">
<label class="form-label" [for]="inputId">{{title}}</label> <label class="form-label mb-md-0" [for]="inputId">{{title}}</label>
</div> </div>
<div [class.col-md-9]="horizontal"> <div [class.col-md-9]="horizontal">
<div class="input-group" [class.is-invalid]="error"> <div class="input-group" [class.is-invalid]="error">

View File

@@ -100,11 +100,11 @@
<pngx-input-select [items]="storagePaths" i18n-title title="Storage path" formControlName="storage_path" [allowNull]="true" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)" <pngx-input-select [items]="storagePaths" i18n-title title="Storage path" formControlName="storage_path" [allowNull]="true" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)"
(createNew)="createStoragePath($event)" [suggestions]="suggestions?.storage_paths" i18n-placeholder placeholder="Default" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.StoragePath }"></pngx-input-select> (createNew)="createStoragePath($event)" [suggestions]="suggestions?.storage_paths" i18n-placeholder placeholder="Default" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.StoragePath }"></pngx-input-select>
<pngx-input-tags formControlName="tags" [suggestions]="suggestions?.tags" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Tag }"></pngx-input-tags> <pngx-input-tags formControlName="tags" [suggestions]="suggestions?.tags" [showFilter]="true" [horizontal]="true" (filterDocuments)="filterDocuments($event)" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Tag }"></pngx-input-tags>
<ng-container *ngFor="let field of customFields; let i = index"> <ng-container *ngFor="let fieldInstance of customFields; let i = index">
<div [formGroup]="customFieldFormFields.controls[i]"> <div [formGroup]="customFieldFormFields.controls[i]">
<pngx-input-text formControlName="value" *ngIf="field.data_type === PaperlessCustomFieldDataType.String" [title]="field.name" [horizontal]="true"></pngx-input-text> <pngx-input-text formControlName="value" *ngIf="fieldInstance.field.data_type === PaperlessCustomFieldDataType.String" [title]="fieldInstance.field.name" [horizontal]="true"></pngx-input-text>
<pngx-input-date formControlName="value" *ngIf="field.data_type === PaperlessCustomFieldDataType.Date" [title]="field.name" [horizontal]="true"></pngx-input-date> <pngx-input-date formControlName="value" *ngIf="fieldInstance.field.data_type === PaperlessCustomFieldDataType.Date" [title]="fieldInstance.field.name" [horizontal]="true"></pngx-input-date>
<pngx-input-number formControlName="value" *ngIf="field.data_type === PaperlessCustomFieldDataType.Integer" [title]="field.name" [horizontal]="true" [showAdd]="false"></pngx-input-number> <pngx-input-number formControlName="value" *ngIf="fieldInstance.field.data_type === PaperlessCustomFieldDataType.Integer" [title]="fieldInstance.field.name" [horizontal]="true" [showAdd]="false"></pngx-input-number>
</div> </div>
</ng-container> </ng-container>
</div> </div>

View File

@@ -63,11 +63,11 @@ import { EditDialogMode } from '../common/edit-dialog/edit-dialog.component'
import { ObjectWithId } from 'src/app/data/object-with-id' import { ObjectWithId } from 'src/app/data/object-with-id'
import { FilterRule } from 'src/app/data/filter-rule' import { FilterRule } from 'src/app/data/filter-rule'
import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter' import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter'
import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
import { import {
PaperlessCustomField, PaperlessCustomField,
PaperlessCustomFieldDataType, PaperlessCustomFieldDataType,
} from 'src/app/data/paperless-custom-field' } from 'src/app/data/paperless-custom-field'
import { PaperlessCustomFieldInstance } from 'src/app/data/paperless-custom-field-instance'
enum DocumentDetailNavIDs { enum DocumentDetailNavIDs {
Details = 1, Details = 1,
@@ -141,7 +141,7 @@ export class DocumentDetailComponent
ogDate: Date ogDate: Date
public readonly PaperlessCustomFieldDataType = PaperlessCustomFieldDataType public readonly PaperlessCustomFieldDataType = PaperlessCustomFieldDataType
customFields: PaperlessCustomField[] = [] customFields: PaperlessCustomFieldInstance[] = []
@ViewChild('nav') nav: NgbNav @ViewChild('nav') nav: NgbNav
@ViewChild('pdfPreview') set pdfPreview(element) { @ViewChild('pdfPreview') set pdfPreview(element) {
@@ -394,6 +394,7 @@ export class DocumentDetailComponent
updateComponent(doc: PaperlessDocument) { updateComponent(doc: PaperlessDocument) {
this.document = doc this.document = doc
this.requiresPassword = false this.requiresPassword = false
this.customFields = doc.custom_fields
this.updateFormForCustomFields() this.updateFormForCustomFields()
this.documentsService this.documentsService
.getMetadata(doc.id) .getMetadata(doc.id)
@@ -449,12 +450,17 @@ export class DocumentDetailComponent
updateFormForCustomFields() { updateFormForCustomFields() {
this.customFieldFormFields.clear() this.customFieldFormFields.clear()
this.customFields.forEach((field) => { this.customFields.forEach((fieldInstance) => {
this.customFieldFormFields.push( this.customFieldFormFields.push(
new FormGroup({ new FormGroup({
parent: new FormControl(field.id), field: new FormGroup({
value: new FormControl(null), id: new FormControl(fieldInstance.field.id),
}) name: new FormControl(fieldInstance.field.name),
data_type: new FormControl(fieldInstance.field.data_type),
}),
value: new FormControl(fieldInstance.value),
}),
{ emitEvent: false }
) )
}) })
} }
@@ -537,7 +543,6 @@ export class DocumentDetailComponent
} }
this.title = doc.title this.title = doc.title
this.documentForm.patchValue(doc) this.documentForm.patchValue(doc)
// TODO: custom field reset
this.customFields = doc.custom_fields this.customFields = doc.custom_fields
this.updateFormForCustomFields() this.updateFormForCustomFields()
this.openDocumentService.setDirty(doc, false) this.openDocumentService.setDirty(doc, false)
@@ -562,6 +567,7 @@ export class DocumentDetailComponent
close && this.close() close && this.close()
this.networkActive = false this.networkActive = false
this.error = null this.error = null
this.openDocumentService.refreshDocument(this.documentId)
}, },
error: (error) => { error: (error) => {
this.networkActive = false this.networkActive = false
@@ -850,7 +856,12 @@ export class DocumentDetailComponent
} }
addField(field: PaperlessCustomField) { addField(field: PaperlessCustomField) {
this.customFields.push(field) this.customFields.push({
field,
value: null,
document: this.documentId,
created: new Date(),
})
this.updateFormForCustomFields() this.updateFormForCustomFields()
} }
} }

View File

@@ -1,7 +1,9 @@
import { ObjectWithId } from './object-with-id' import { ObjectWithId } from './object-with-id'
import { PaperlessCustomField } from './paperless-custom-field'
export interface PaperlessCustomFieldInstance extends ObjectWithId { export interface PaperlessCustomFieldInstance extends ObjectWithId {
document: number // PaperlessDocument document: number // PaperlessDocument
field: number // PaperlessCustomField field: PaperlessCustomField
created: Date created: Date
value?: any
} }

View File

@@ -5,7 +5,7 @@ import { Observable } from 'rxjs'
import { PaperlessStoragePath } from './paperless-storage-path' import { PaperlessStoragePath } from './paperless-storage-path'
import { ObjectWithPermissions } from './object-with-permissions' import { ObjectWithPermissions } from './object-with-permissions'
import { PaperlessDocumentNote } from './paperless-document-note' import { PaperlessDocumentNote } from './paperless-document-note'
import { PaperlessCustomField } from './paperless-custom-field' import { PaperlessCustomFieldInstance } from './paperless-custom-field-instance'
export interface SearchHit { export interface SearchHit {
score?: number score?: number
@@ -60,5 +60,5 @@ export interface PaperlessDocument extends ObjectWithPermissions {
__search_hit__?: SearchHit __search_hit__?: SearchHit
custom_fields?: PaperlessCustomField[] custom_fields?: PaperlessCustomFieldInstance[]
} }